From: niklas Date: Thu, 11 Jan 1996 22:27:45 +0000 (+0000) Subject: Remove obsolete GCC X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ae8eac1922da7a4b7536666eeb7c7dd91e0a83bc;p=openbsd Remove obsolete GCC --- diff --git a/gnu/usr.bin/gcc2/Makefile b/gnu/usr.bin/gcc2/Makefile deleted file mode 100644 index 53d57776047..00000000000 --- a/gnu/usr.bin/gcc2/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $NetBSD: Makefile,v 1.5 1995/04/23 07:58:38 cgd Exp $ - -SUBDIR= common cc cpp cc1 cc1plus cc1obj libgcc #libobjc - -.include diff --git a/gnu/usr.bin/gcc2/Makefile.cc1 b/gnu/usr.bin/gcc2/Makefile.cc1 deleted file mode 100644 index 1b4843b65e7..00000000000 --- a/gnu/usr.bin/gcc2/Makefile.cc1 +++ /dev/null @@ -1,18 +0,0 @@ -# $Id: Makefile.cc1,v 1.2 1995/12/14 03:42:27 deraadt Exp $ - -NOMAN= - -BINDIR= /usr/libexec - -CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../common \ - -I${.CURDIR}/../arch -I${.CURDIR}/../arch/${MACHINE_ARCH} -YFLAGS= - -LIBCC1!= cd $(.CURDIR)/../common; \ - printf "xxx:\n\techo \$${.OBJDIR}/libcc1.a\n" | \ - ${MAKE} -r -s -f - xxx | grep libcc1 - -LDADD+=${LIBCC1} -lgnumalloc -DPADD+= /usr/lib/libgnumalloc.a - -.include diff --git a/gnu/usr.bin/gcc2/arch/genattrtab.c b/gnu/usr.bin/gcc2/arch/genattrtab.c deleted file mode 100644 index fd2974308f1..00000000000 --- a/gnu/usr.bin/gcc2/arch/genattrtab.c +++ /dev/null @@ -1,5672 +0,0 @@ -/* Generate code from machine description to compute values of attributes. - Copyright (C) 1991 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@nyu.edu) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This program handles insn attributes and the DEFINE_DELAY and - DEFINE_FUNCTION_UNIT definitions. - - It produces a series of functions named `get_attr_...', one for each insn - attribute. Each of these is given the rtx for an insn and returns a member - of the enum for the attribute. - - These subroutines have the form of a `switch' on the INSN_CODE (via - `recog_memoized'). Each case either returns a constant attribute value - or a value that depends on tests on other attributes, the form of - operands, or some random C expression (encoded with a SYMBOL_REF - expression). - - If the attribute `alternative', or a random C expression is present, - `constrain_operands' is called. If either of these cases of a reference to - an operand is found, `insn_extract' is called. - - The special attribute `length' is also recognized. For this operand, - expressions involving the address of an operand or the current insn, - (address (pc)), are valid. In this case, an initial pass is made to - set all lengths that do not depend on address. Those that do are set to - the maximum length. Then each insn that depends on an address is checked - and possibly has its length changed. The process repeats until no further - changed are made. The resulting lengths are saved for use by - `get_attr_length'. - - A special form of DEFINE_ATTR, where the expression for default value is a - CONST expression, indicates an attribute that is constant for a given run - of the compiler. The subroutine generated for these attributes has no - parameters as it does not depend on any particular insn. Constant - attributes are typically used to specify which variety of processor is - used. - - Internal attributes are defined to handle DEFINE_DELAY and - DEFINE_FUNCTION_UNIT. Special routines are output for these cases. - - This program works by keeping a list of possible values for each attribute. - These include the basic attribute choices, default values for attribute, and - all derived quantities. - - As the description file is read, the definition for each insn is saved in a - `struct insn_def'. When the file reading is complete, a `struct insn_ent' - is created for each insn and chained to the corresponding attribute value, - either that specified, or the default. - - An optimization phase is then run. This simplifies expressions for each - insn. EQ_ATTR tests are resolved, whenever possible, to a test that - indicates when the attribute has the specified value for the insn. This - avoids recursive calls during compilation. - - The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT - definitions is to create arbitrarily complex expressions and have the - optimization simplify them. - - Once optimization is complete, any required routines and definitions - will be written. - - An optimization that is not yet implemented is to hoist the constant - expressions entirely out of the routines and definitions that are written. - A way to do this is to iterate over all possible combinations of values - for constant attributes and generate a set of functions for that given - combination. An initialization function would be written that evaluates - the attributes and installs the corresponding set of routines and - definitions (each would be accessed through a pointer). - - We use the flags in an RTX as follows: - `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified - independent of the insn code. - `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified - for the insn code currently being processed (see optimize_attrs). - `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique - (see attr_rtx). - `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an - EQ_ATTR rtx is true if !volatil and false if volatil. */ - -#ifndef lint -static char rcsid[] = "$Id: genattrtab.c,v 1.1.1.1 1995/10/18 08:39:15 deraadt Exp $"; -#endif /* not lint */ - -#include "gvarargs.h" -#include "config.h" -#include "rtl.h" -#include "insn-config.h" /* For REGISTER_CONSTRAINTS */ -#include - -#ifndef VMS -#ifndef USG -#include -#include -#endif -#endif - -/* We must include obstack.h after , to avoid lossage with - /usr/include/sys/stdtypes.h on Sun OS 4.x. */ -#include "obstack.h" - -static struct obstack obstack, obstack1, obstack2; -struct obstack *rtl_obstack = &obstack; -struct obstack *hash_obstack = &obstack1; -struct obstack *temp_obstack = &obstack2; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Define this so we can link with print-rtl.o to get debug_rtx function. */ -char **insn_name_ptr = 0; - -extern void free (); -extern rtx read_rtx (); - -static void fatal (); -void fancy_abort (); - -/* enough space to reserve for printing out ints */ -#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3) - -/* Define structures used to record attributes and values. */ - -/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is - encountered, we store all the relevant information into a - `struct insn_def'. This is done to allow attribute definitions to occur - anywhere in the file. */ - -struct insn_def -{ - int insn_code; /* Instruction number. */ - int insn_index; /* Expression numer in file, for errors. */ - struct insn_def *next; /* Next insn in chain. */ - rtx def; /* The DEFINE_... */ - int num_alternatives; /* Number of alternatives. */ - int vec_idx; /* Index of attribute vector in `def'. */ -}; - -/* Once everything has been read in, we store in each attribute value a list - of insn codes that have that value. Here is the structure used for the - list. */ - -struct insn_ent -{ - int insn_code; /* Instruction number. */ - int insn_index; /* Index of definition in file */ - struct insn_ent *next; /* Next in chain. */ -}; - -/* Each value of an attribute (either constant or computed) is assigned a - structure which is used as the listhead of the insns that have that - value. */ - -struct attr_value -{ - rtx value; /* Value of attribute. */ - struct attr_value *next; /* Next attribute value in chain. */ - struct insn_ent *first_insn; /* First insn with this value. */ - int num_insns; /* Number of insns with this value. */ - int has_asm_insn; /* True if this value used for `asm' insns */ -}; - -/* Structure for each attribute. */ - -struct attr_desc -{ - char *name; /* Name of attribute. */ - struct attr_desc *next; /* Next attribute. */ - int is_numeric; /* Values of this attribute are numeric. */ - int negative_ok; /* Allow negative numeric values. */ - int unsigned_p; /* Make the output function unsigned int. */ - int is_const; /* Attribute value constant for each run. */ - int is_special; /* Don't call `write_attr_set'. */ - struct attr_value *first_value; /* First value of this attribute. */ - struct attr_value *default_val; /* Default value for this attribute. */ -}; - -#define NULL_ATTR (struct attr_desc *) NULL - -/* A range of values. */ - -struct range -{ - int min; - int max; -}; - -/* Structure for each DEFINE_DELAY. */ - -struct delay_desc -{ - rtx def; /* DEFINE_DELAY expression. */ - struct delay_desc *next; /* Next DEFINE_DELAY. */ - int num; /* Number of DEFINE_DELAY, starting at 1. */ -}; - -/* Record information about each DEFINE_FUNCTION_UNIT. */ - -struct function_unit_op -{ - rtx condexp; /* Expression TRUE for applicable insn. */ - struct function_unit_op *next; /* Next operation for this function unit. */ - int num; /* Ordinal for this operation type in unit. */ - int ready; /* Cost until data is ready. */ - int issue_delay; /* Cost until unit can accept another insn. */ - rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */ - rtx issue_exp; /* Expression computing issue delay. */ -}; - -/* Record information about each function unit mentioned in a - DEFINE_FUNCTION_UNIT. */ - -struct function_unit -{ - char *name; /* Function unit name. */ - struct function_unit *next; /* Next function unit. */ - int num; /* Ordinal of this unit type. */ - int multiplicity; /* Number of units of this type. */ - int simultaneity; /* Maximum number of simultaneous insns - on this function unit or 0 if unlimited. */ - rtx condexp; /* Expression TRUE for insn needing unit. */ - int num_opclasses; /* Number of different operation types. */ - struct function_unit_op *ops; /* Pointer to first operation type. */ - int needs_conflict_function; /* Nonzero if a conflict function required. */ - int needs_blockage_function; /* Nonzero if a blockage function required. */ - int needs_range_function; /* Nonzero if blockage range function needed.*/ - rtx default_cost; /* Conflict cost, if constant. */ - struct range issue_delay; /* Range of issue delay values. */ - int max_blockage; /* Maximum time an insn blocks the unit. */ -}; - -/* Listheads of above structures. */ - -/* This one is indexed by the first character of the attribute name. */ -#define MAX_ATTRS_INDEX 256 -static struct attr_desc *attrs[MAX_ATTRS_INDEX]; -static struct insn_def *defs; -static struct delay_desc *delays; -static struct function_unit *units; - -/* An expression where all the unknown terms are EQ_ATTR tests can be - rearranged into a COND provided we can enumerate all possible - combinations of the unknown values. The set of combinations become the - tests of the COND; the value of the expression given that combination is - computed and becomes the corresponding value. To do this, we must be - able to enumerate all values for each attribute used in the expression - (currently, we give up if we find a numeric attribute). - - If the set of EQ_ATTR tests used in an expression tests the value of N - different attributes, the list of all possible combinations can be made - by walking the N-dimensional attribute space defined by those - attributes. We record each of these as a struct dimension. - - The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an - expression are the same, the will also have the same address. We find - all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later - represents the value of an EQ_ATTR node, so once all nodes are marked, - they are also given an initial value of FALSE. - - We then separate the set of EQ_ATTR nodes into dimensions for each - attribute and put them on the VALUES list. Terms are added as needed by - `add_values_to_cover' so that all possible values of the attribute are - tested. - - Each dimension also has a current value. This is the node that is - currently considered to be TRUE. If this is one of the nodes added by - `add_values_to_cover', all the EQ_ATTR tests in the original expression - will be FALSE. Otherwise, only the CURRENT_VALUE will be true. - - NUM_VALUES is simply the length of the VALUES list and is there for - convenience. - - Once the dimensions are created, the algorithm enumerates all possible - values and computes the current value of the given expression. */ - -struct dimension -{ - struct attr_desc *attr; /* Attribute for this dimension. */ - rtx values; /* List of attribute values used. */ - rtx current_value; /* Position in the list for the TRUE value. */ - int num_values; /* Length of the values list. */ -}; - -/* Other variables. */ - -static int insn_code_number; -static int insn_index_number; -static int got_define_asm_attributes; -static int must_extract; -static int must_constrain; -static int address_used; -static int length_used; -static int num_delays; -static int have_annul_true, have_annul_false; -static int num_units; - -/* Used as operand to `operate_exp': */ - -enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, MAX_OP, MIN_OP, RANGE_OP}; - -/* Stores, for each insn code, the number of constraint alternatives. */ - -static int *insn_n_alternatives; - -/* Stores, for each insn code, a bitmap that has bits on for each possible - alternative. */ - -static int *insn_alternatives; - -/* If nonzero, assume that the `alternative' attr has this value. - This is the hashed, unique string for the numeral - whose value is chosen alternative. */ - -static char *current_alternative_string; - -/* Used to simplify expressions. */ - -static rtx true_rtx, false_rtx; - -/* Used to reduce calls to `strcmp' */ - -static char *alternative_name; - -/* Simplify an expression. Only call the routine if there is something to - simplify. */ -#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \ - (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \ - : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX)) - -/* Simplify (eq_attr ("alternative") ...) - when we are working with a particular alternative. */ -#define SIMPLIFY_ALTERNATIVE(EXP) \ - if (current_alternative_string \ - && GET_CODE ((EXP)) == EQ_ATTR \ - && XSTR ((EXP), 0) == alternative_name) \ - (EXP) = (XSTR ((EXP), 1) == current_alternative_string \ - ? true_rtx : false_rtx); - -/* These are referenced by rtlanal.c and hence need to be defined somewhere. - They won't actually be used. */ - -rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx; - -#if 0 -static rtx attr_rtx PROTO((enum rtx_code, ...)); -static char *attr_printf PROTO((int, char *, ...)); -#else -static rtx attr_rtx (); -static char *attr_printf (); -#endif - -static char *attr_string PROTO((char *, int)); -static rtx check_attr_test PROTO((rtx, int)); -static rtx check_attr_value PROTO((rtx, struct attr_desc *)); -static rtx convert_set_attr_alternative PROTO((rtx, int, int, int)); -static rtx convert_set_attr PROTO((rtx, int, int, int)); -static void check_defs PROTO((void)); -static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *)); -static rtx make_canonical PROTO((struct attr_desc *, rtx)); -static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int)); -static rtx copy_rtx_unchanging PROTO((rtx)); -static rtx copy_boolean PROTO((rtx)); -static void expand_delays PROTO((void)); -static rtx operate_exp PROTO((enum operator, rtx, rtx)); -static void expand_units PROTO((void)); -static rtx simplify_knowing PROTO((rtx, rtx)); -static rtx encode_units_mask PROTO((rtx)); -static void fill_attr PROTO((struct attr_desc *)); -static rtx substitute_address PROTO((rtx, rtx (*) (rtx), rtx (*) (rtx))); -static void make_length_attrs PROTO((void)); -static rtx identity_fn PROTO((rtx)); -static rtx zero_fn PROTO((rtx)); -static rtx one_fn PROTO((rtx)); -static rtx max_fn PROTO((rtx)); -static rtx simplify_cond PROTO((rtx, int, int)); -static rtx simplify_by_alternatives PROTO((rtx, int, int)); -static rtx simplify_by_exploding PROTO((rtx)); -static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *)); -static void unmark_used_attributes PROTO((rtx, struct dimension *, int)); -static int add_values_to_cover PROTO((struct dimension *)); -static int increment_current_value PROTO((struct dimension *, int)); -static rtx test_for_current_value PROTO((struct dimension *, int)); -static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int)); -static rtx simplify_with_current_value_aux PROTO((rtx)); -static void clear_struct_flag PROTO((rtx)); -static int count_sub_rtxs PROTO((rtx, int)); -static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *)); -static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *)); -static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int)); -static rtx make_alternative_compare PROTO((int)); -static int compute_alternative_mask PROTO((rtx, enum rtx_code)); -static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int)); -static rtx simplify_and_tree PROTO((rtx, rtx *, int, int)); -static rtx simplify_or_tree PROTO((rtx, rtx *, int, int)); -static rtx simplify_test_exp PROTO((rtx, int, int)); -static void optimize_attrs PROTO((void)); -static void gen_attr PROTO((rtx)); -static int count_alternatives PROTO((rtx)); -static int compares_alternatives_p PROTO((rtx)); -static int contained_in_p PROTO((rtx, rtx)); -static void gen_insn PROTO((rtx)); -static void gen_delay PROTO((rtx)); -static void gen_unit PROTO((rtx)); -static void write_test_expr PROTO((rtx, int)); -static int max_attr_value PROTO((rtx)); -static void walk_attr_value PROTO((rtx)); -static void write_attr_get PROTO((struct attr_desc *)); -static rtx eliminate_known_true PROTO((rtx, rtx, int, int)); -static void write_attr_set PROTO((struct attr_desc *, int, rtx, char *, - char *, rtx, int, int)); -static void write_attr_case PROTO((struct attr_desc *, struct attr_value *, - int, char *, char *, int, rtx)); -static void write_attr_valueq PROTO((struct attr_desc *, char *)); -static void write_attr_value PROTO((struct attr_desc *, rtx)); -static void write_upcase PROTO((char *)); -static void write_indent PROTO((int)); -static void write_eligible_delay PROTO((char *)); -static void write_function_unit_info PROTO((void)); -static void write_complex_function PROTO((struct function_unit *, char *, - char *)); -static int n_comma_elts PROTO((char *)); -static char *next_comma_elt PROTO((char **)); -static struct attr_desc *find_attr PROTO((char *, int)); -static void make_internal_attr PROTO((char *, rtx, int)); -static struct attr_value *find_most_used PROTO((struct attr_desc *)); -static rtx find_single_value PROTO((struct attr_desc *)); -static rtx make_numeric_value PROTO((int)); -static void extend_range PROTO((struct range *, int, int)); -char *xrealloc PROTO((char *, unsigned)); -char *xmalloc PROTO((unsigned)); - -#define oballoc(size) obstack_alloc (hash_obstack, size) - - -/* Hash table for sharing RTL and strings. */ - -/* Each hash table slot is a bucket containing a chain of these structures. - Strings are given negative hash codes; RTL expressions are given positive - hash codes. */ - -struct attr_hash -{ - struct attr_hash *next; /* Next structure in the bucket. */ - int hashcode; /* Hash code of this rtx or string. */ - union - { - char *str; /* The string (negative hash codes) */ - rtx rtl; /* or the RTL recorded here. */ - } u; -}; - -/* Now here is the hash table. When recording an RTL, it is added to - the slot whose index is the hash code mod the table size. Note - that the hash table is used for several kinds of RTL (see attr_rtx) - and for strings. While all these live in the same table, they are - completely independent, and the hash code is computed differently - for each. */ - -#define RTL_HASH_SIZE 4093 -struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; - -/* Here is how primitive or already-shared RTL's hash - codes are made. */ -#define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777) - -/* Add an entry to the hash table for RTL with hash code HASHCODE. */ - -static void -attr_hash_add_rtx (hashcode, rtl) - int hashcode; - rtx rtl; -{ - register struct attr_hash *h; - - h = (struct attr_hash *) obstack_alloc (hash_obstack, - sizeof (struct attr_hash)); - h->hashcode = hashcode; - h->u.rtl = rtl; - h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; - attr_hash_table[hashcode % RTL_HASH_SIZE] = h; -} - -/* Add an entry to the hash table for STRING with hash code HASHCODE. */ - -static void -attr_hash_add_string (hashcode, str) - int hashcode; - char *str; -{ - register struct attr_hash *h; - - h = (struct attr_hash *) obstack_alloc (hash_obstack, - sizeof (struct attr_hash)); - h->hashcode = -hashcode; - h->u.str = str; - h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; - attr_hash_table[hashcode % RTL_HASH_SIZE] = h; -} - -/* Generate an RTL expression, but avoid duplicates. - Set the RTX_INTEGRATED_P flag for these permanent objects. - - In some cases we cannot uniquify; then we return an ordinary - impermanent rtx with RTX_INTEGRATED_P clear. - - Args are like gen_rtx, but without the mode: - - rtx attr_rtx (code, [element1, ..., elementn]) */ - -/*VARARGS1*/ -static rtx -attr_rtx (va_alist) - va_dcl -{ - va_list p; - enum rtx_code code; - register int i; /* Array indices... */ - register char *fmt; /* Current rtx's format... */ - register rtx rt_val; /* RTX to return to caller... */ - int hashcode; - register struct attr_hash *h; - struct obstack *old_obstack = rtl_obstack; - - va_start (p); - code = va_arg (p, enum rtx_code); - - /* For each of several cases, search the hash table for an existing entry. - Use that entry if one is found; otherwise create a new RTL and add it - to the table. */ - - if (GET_RTX_CLASS (code) == '1') - { - rtx arg0 = va_arg (p, rtx); - - /* A permanent object cannot point to impermanent ones. */ - if (! RTX_INTEGRATED_P (arg0)) - { - rt_val = rtx_alloc (code); - XEXP (rt_val, 0) = arg0; - va_end (p); - return rt_val; - } - - hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); - for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) - if (h->hashcode == hashcode - && GET_CODE (h->u.rtl) == code - && XEXP (h->u.rtl, 0) == arg0) - goto found; - - if (h == 0) - { - rtl_obstack = hash_obstack; - rt_val = rtx_alloc (code); - XEXP (rt_val, 0) = arg0; - } - } - else if (GET_RTX_CLASS (code) == 'c' - || GET_RTX_CLASS (code) == '2' - || GET_RTX_CLASS (code) == '<') - { - rtx arg0 = va_arg (p, rtx); - rtx arg1 = va_arg (p, rtx); - - /* A permanent object cannot point to impermanent ones. */ - if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1)) - { - rt_val = rtx_alloc (code); - XEXP (rt_val, 0) = arg0; - XEXP (rt_val, 1) = arg1; - va_end (p); - return rt_val; - } - - hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); - for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) - if (h->hashcode == hashcode - && GET_CODE (h->u.rtl) == code - && XEXP (h->u.rtl, 0) == arg0 - && XEXP (h->u.rtl, 1) == arg1) - goto found; - - if (h == 0) - { - rtl_obstack = hash_obstack; - rt_val = rtx_alloc (code); - XEXP (rt_val, 0) = arg0; - XEXP (rt_val, 1) = arg1; - } - } - else if (GET_RTX_LENGTH (code) == 1 - && GET_RTX_FORMAT (code)[0] == 's') - { - char * arg0 = va_arg (p, char *); - - if (code == SYMBOL_REF) - arg0 = attr_string (arg0, strlen (arg0)); - - hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); - for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) - if (h->hashcode == hashcode - && GET_CODE (h->u.rtl) == code - && XSTR (h->u.rtl, 0) == arg0) - goto found; - - if (h == 0) - { - rtl_obstack = hash_obstack; - rt_val = rtx_alloc (code); - XSTR (rt_val, 0) = arg0; - } - } - else if (GET_RTX_LENGTH (code) == 2 - && GET_RTX_FORMAT (code)[0] == 's' - && GET_RTX_FORMAT (code)[1] == 's') - { - char *arg0 = va_arg (p, char *); - char *arg1 = va_arg (p, char *); - - hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); - for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) - if (h->hashcode == hashcode - && GET_CODE (h->u.rtl) == code - && XSTR (h->u.rtl, 0) == arg0 - && XSTR (h->u.rtl, 1) == arg1) - goto found; - - if (h == 0) - { - rtl_obstack = hash_obstack; - rt_val = rtx_alloc (code); - XSTR (rt_val, 0) = arg0; - XSTR (rt_val, 1) = arg1; - } - } - else if (code == CONST_INT) - { - HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT); - if (arg0 == 0) - return false_rtx; - if (arg0 == 1) - return true_rtx; - goto nohash; - } - else - { - nohash: - rt_val = rtx_alloc (code); /* Allocate the storage space. */ - - fmt = GET_RTX_FORMAT (code); /* Find the right format... */ - for (i = 0; i < GET_RTX_LENGTH (code); i++) - { - switch (*fmt++) - { - case '0': /* Unused field. */ - break; - - case 'i': /* An integer? */ - XINT (rt_val, i) = va_arg (p, int); - break; - - case 'w': /* A wide integer? */ - XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT); - break; - - case 's': /* A string? */ - XSTR (rt_val, i) = va_arg (p, char *); - break; - - case 'e': /* An expression? */ - case 'u': /* An insn? Same except when printing. */ - XEXP (rt_val, i) = va_arg (p, rtx); - break; - - case 'E': /* An RTX vector? */ - XVEC (rt_val, i) = va_arg (p, rtvec); - break; - - default: - abort(); - } - } - va_end (p); - return rt_val; - } - - rtl_obstack = old_obstack; - va_end (p); - attr_hash_add_rtx (hashcode, rt_val); - RTX_INTEGRATED_P (rt_val) = 1; - return rt_val; - - found: - va_end (p); - return h->u.rtl; -} - -/* Create a new string printed with the printf line arguments into a space - of at most LEN bytes: - - rtx attr_printf (len, format, [arg1, ..., argn]) */ - -#ifdef HAVE_VPRINTF - -/*VARARGS2*/ -static char * -attr_printf (va_alist) - va_dcl -{ - va_list p; - register int len; - register char *fmt; - register char *str; - - /* Print the string into a temporary location. */ - va_start (p); - len = va_arg (p, int); - str = (char *) alloca (len); - fmt = va_arg (p, char *); - vsprintf (str, fmt, p); - va_end (p); - - return attr_string (str, strlen (str)); -} - -#else /* not HAVE_VPRINTF */ - -static char * -attr_printf (len, fmt, arg1, arg2, arg3) - int len; - char *fmt; - char *arg1, *arg2, *arg3; /* also int */ -{ - register char *str; - - /* Print the string into a temporary location. */ - str = (char *) alloca (len); - sprintf (str, fmt, arg1, arg2, arg3); - - return attr_string (str, strlen (str)); -} -#endif /* not HAVE_VPRINTF */ - -rtx -attr_eq (name, value) - char *name, *value; -{ - return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)), - attr_string (value, strlen (value))); -} - -char * -attr_numeral (n) - int n; -{ - return XSTR (make_numeric_value (n), 0); -} - -/* Return a permanent (possibly shared) copy of a string STR (not assumed - to be null terminated) with LEN bytes. */ - -static char * -attr_string (str, len) - char *str; - int len; -{ - register struct attr_hash *h; - int hashcode; - int i; - register char *new_str; - - /* Compute the hash code. */ - hashcode = (len + 1) * 613 + (unsigned)str[0]; - for (i = 1; i <= len; i += 2) - hashcode = ((hashcode * 613) + (unsigned)str[i]); - if (hashcode < 0) - hashcode = -hashcode; - - /* Search the table for the string. */ - for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) - if (h->hashcode == -hashcode && h->u.str[0] == str[0] - && !strncmp (h->u.str, str, len)) - return h->u.str; /* <-- return if found. */ - - /* Not found; create a permanent copy and add it to the hash table. */ - new_str = (char *) obstack_alloc (hash_obstack, len + 1); - bcopy (str, new_str, len); - new_str[len] = '\0'; - attr_hash_add_string (hashcode, new_str); - - return new_str; /* Return the new string. */ -} - -/* Check two rtx's for equality of contents, - taking advantage of the fact that if both are hashed - then they can't be equal unless they are the same object. */ - -int -attr_equal_p (x, y) - rtx x, y; -{ - return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y)) - && rtx_equal_p (x, y))); -} - -/* Copy an attribute value expression, - descending to all depths, but not copying any - permanent hashed subexpressions. */ - -rtx -attr_copy_rtx (orig) - register rtx orig; -{ - register rtx copy; - register int i, j; - register RTX_CODE code; - register char *format_ptr; - - /* No need to copy a permanent object. */ - if (RTX_INTEGRATED_P (orig)) - return orig; - - code = GET_CODE (orig); - - switch (code) - { - case REG: - case QUEUED: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case CC0: - return orig; - } - - copy = rtx_alloc (code); - PUT_MODE (copy, GET_MODE (orig)); - copy->in_struct = orig->in_struct; - copy->volatil = orig->volatil; - copy->unchanging = orig->unchanging; - copy->integrated = orig->integrated; - - format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); - - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) - { - switch (*format_ptr++) - { - case 'e': - XEXP (copy, i) = XEXP (orig, i); - if (XEXP (orig, i) != NULL) - XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i)); - break; - - case 'E': - case 'V': - XVEC (copy, i) = XVEC (orig, i); - if (XVEC (orig, i) != NULL) - { - XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); - for (j = 0; j < XVECLEN (copy, i); j++) - XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j)); - } - break; - - case 'n': - case 'i': - XINT (copy, i) = XINT (orig, i); - break; - - case 'w': - XWINT (copy, i) = XWINT (orig, i); - break; - - case 's': - case 'S': - XSTR (copy, i) = XSTR (orig, i); - break; - - default: - abort (); - } - } - return copy; -} - -/* Given a test expression for an attribute, ensure it is validly formed. - IS_CONST indicates whether the expression is constant for each compiler - run (a constant expression may not test any particular insn). - - Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..)) - and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter - test first so that (eq_attr "att" "!a1,a2,a3") works as expected. - - Update the string address in EQ_ATTR expression to be the same used - in the attribute (or `alternative_name') to speed up subsequent - `find_attr' calls and eliminate most `strcmp' calls. - - Return the new expression, if any. */ - -static rtx -check_attr_test (exp, is_const) - rtx exp; - int is_const; -{ - struct attr_desc *attr; - struct attr_value *av; - char *name_ptr, *p; - rtx orexp, newexp; - - switch (GET_CODE (exp)) - { - case EQ_ATTR: - /* Handle negation test. */ - if (XSTR (exp, 1)[0] == '!') - return check_attr_test (attr_rtx (NOT, - attr_eq (XSTR (exp, 0), - &XSTR (exp, 1)[1])), - is_const); - - else if (n_comma_elts (XSTR (exp, 1)) == 1) - { - attr = find_attr (XSTR (exp, 0), 0); - if (attr == NULL) - { - if (! strcmp (XSTR (exp, 0), "alternative")) - { - XSTR (exp, 0) = alternative_name; - /* This can't be simplified any further. */ - RTX_UNCHANGING_P (exp) = 1; - return exp; - } - else - fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0)); - } - - if (is_const && ! attr->is_const) - fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR", - XEXP (exp, 0)); - - /* Copy this just to make it permanent, - so expressions using it can be permanent too. */ - exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1)); - - /* It shouldn't be possible to simplify the value given to a - constant attribute, so don't expand this until it's time to - write the test expression. */ - if (attr->is_const) - RTX_UNCHANGING_P (exp) = 1; - - if (attr->is_numeric) - { - for (p = XSTR (exp, 1); *p; p++) - if (*p < '0' || *p > '9') - fatal ("Attribute `%s' takes only numeric values", - XEXP (exp, 0)); - } - else - { - for (av = attr->first_value; av; av = av->next) - if (GET_CODE (av->value) == CONST_STRING - && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0))) - break; - - if (av == NULL) - fatal ("Unknown value `%s' for `%s' attribute", - XEXP (exp, 1), XEXP (exp, 0)); - } - } - else - { - /* Make an IOR tree of the possible values. */ - orexp = false_rtx; - name_ptr = XSTR (exp, 1); - while ((p = next_comma_elt (&name_ptr)) != NULL) - { - newexp = attr_eq (XSTR (exp, 0), p); - orexp = insert_right_side (IOR, orexp, newexp, -2, -2); - } - - return check_attr_test (orexp, is_const); - } - break; - - case ATTR_FLAG: - break; - - case CONST_INT: - /* Either TRUE or FALSE. */ - if (XWINT (exp, 0)) - return true_rtx; - else - return false_rtx; - - case IOR: - case AND: - XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const); - XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const); - break; - - case NOT: - XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const); - break; - - case MATCH_OPERAND: - if (is_const) - fatal ("RTL operator \"%s\" not valid in constant attribute test", - GET_RTX_NAME (MATCH_OPERAND)); - /* These cases can't be simplified. */ - RTX_UNCHANGING_P (exp) = 1; - break; - - case LE: case LT: case GT: case GE: - case LEU: case LTU: case GTU: case GEU: - case NE: case EQ: - if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF - && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF) - exp = attr_rtx (GET_CODE (exp), - attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)), - attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0))); - /* These cases can't be simplified. */ - RTX_UNCHANGING_P (exp) = 1; - break; - - case SYMBOL_REF: - if (is_const) - { - /* These cases are valid for constant attributes, but can't be - simplified. */ - exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0)); - RTX_UNCHANGING_P (exp) = 1; - break; - } - default: - fatal ("RTL operator \"%s\" not valid in attribute test", - GET_RTX_NAME (GET_CODE (exp))); - } - - return exp; -} - -/* Given an expression, ensure that it is validly formed and that all named - attribute values are valid for the given attribute. Issue a fatal error - if not. If no attribute is specified, assume a numeric attribute. - - Return a perhaps modified replacement expression for the value. */ - -static rtx -check_attr_value (exp, attr) - rtx exp; - struct attr_desc *attr; -{ - struct attr_value *av; - char *p; - int i; - - switch (GET_CODE (exp)) - { - case CONST_INT: - if (attr && ! attr->is_numeric) - fatal ("CONST_INT not valid for non-numeric `%s' attribute", - attr->name); - - if (INTVAL (exp) < 0) - fatal ("Negative numeric value specified for `%s' attribute", - attr->name); - - break; - - case CONST_STRING: - if (! strcmp (XSTR (exp, 0), "*")) - break; - - if (attr == 0 || attr->is_numeric) - { - p = XSTR (exp, 0); - if (attr && attr->negative_ok && *p == '-') - p++; - for (; *p; p++) - if (*p > '9' || *p < '0') - fatal ("Non-numeric value for numeric `%s' attribute", - attr ? attr->name : "internal"); - break; - } - - for (av = attr->first_value; av; av = av->next) - if (GET_CODE (av->value) == CONST_STRING - && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0))) - break; - - if (av == NULL) - fatal ("Unknown value `%s' for `%s' attribute", - XSTR (exp, 0), attr ? attr->name : "internal"); - - break; - - case IF_THEN_ELSE: - XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), - attr ? attr->is_const : 0); - XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); - XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); - break; - - case COND: - if (XVECLEN (exp, 0) % 2 != 0) - fatal ("First operand of COND must have even length"); - - for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i), - attr ? attr->is_const : 0); - XVECEXP (exp, 0, i + 1) - = check_attr_value (XVECEXP (exp, 0, i + 1), attr); - } - - XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); - break; - - case SYMBOL_REF: - if (attr && attr->is_const) - /* A constant SYMBOL_REF is valid as a constant attribute test and - is expanded later by make_canonical into a COND. */ - return attr_rtx (SYMBOL_REF, XSTR (exp, 0)); - /* Otherwise, fall through... */ - - default: - fatal ("Illegal operation `%s' for attribute value", - GET_RTX_NAME (GET_CODE (exp))); - } - - return exp; -} - -/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET. - It becomes a COND with each test being (eq_attr "alternative "n") */ - -static rtx -convert_set_attr_alternative (exp, num_alt, insn_code, insn_index) - rtx exp; - int num_alt; - int insn_code, insn_index; -{ - rtx condexp; - int i; - - if (XVECLEN (exp, 1) != num_alt) - fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d", - insn_index); - - /* Make a COND with all tests but the last. Select the last value via the - default. */ - condexp = rtx_alloc (COND); - XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2); - - for (i = 0; i < num_alt - 1; i++) - { - char *p; - p = attr_numeral (i); - - XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p); -#if 0 - /* Sharing this EQ_ATTR rtl causes trouble. */ - XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR); - XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name; - XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p; -#endif - XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i); - } - - XEXP (condexp, 1) = XVECEXP (exp, 1, i); - - return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp); -} - -/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated - list of values is given, convert to SET_ATTR_ALTERNATIVE first. */ - -static rtx -convert_set_attr (exp, num_alt, insn_code, insn_index) - rtx exp; - int num_alt; - int insn_code, insn_index; -{ - rtx newexp; - char *name_ptr; - char *p; - int n; - - /* See how many alternative specified. */ - n = n_comma_elts (XSTR (exp, 1)); - if (n == 1) - return attr_rtx (SET, - attr_rtx (ATTR, XSTR (exp, 0)), - attr_rtx (CONST_STRING, XSTR (exp, 1))); - - newexp = rtx_alloc (SET_ATTR_ALTERNATIVE); - XSTR (newexp, 0) = XSTR (exp, 0); - XVEC (newexp, 1) = rtvec_alloc (n); - - /* Process each comma-separated name. */ - name_ptr = XSTR (exp, 1); - n = 0; - while ((p = next_comma_elt (&name_ptr)) != NULL) - XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p); - - return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index); -} - -/* Scan all definitions, checking for validity. Also, convert any SET_ATTR - and SET_ATTR_ALTERNATIVE expressions to the corresponding SET - expressions. */ - -static void -check_defs () -{ - struct insn_def *id; - struct attr_desc *attr; - int i; - rtx value; - - for (id = defs; id; id = id->next) - { - if (XVEC (id->def, id->vec_idx) == NULL) - continue; - - for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) - { - value = XVECEXP (id->def, id->vec_idx, i); - switch (GET_CODE (value)) - { - case SET: - if (GET_CODE (XEXP (value, 0)) != ATTR) - fatal ("Bad attribute set in pattern %d", id->insn_index); - break; - - case SET_ATTR_ALTERNATIVE: - value = convert_set_attr_alternative (value, - id->num_alternatives, - id->insn_code, - id->insn_index); - break; - - case SET_ATTR: - value = convert_set_attr (value, id->num_alternatives, - id->insn_code, id->insn_index); - break; - - default: - fatal ("Invalid attribute code `%s' for pattern %d", - GET_RTX_NAME (GET_CODE (value)), id->insn_index); - } - - if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL) - fatal ("Unknown attribute `%s' for pattern number %d", - XSTR (XEXP (value, 0), 0), id->insn_index); - - XVECEXP (id->def, id->vec_idx, i) = value; - XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr); - } - } -} - -/* Given a constant SYMBOL_REF expression, convert to a COND that - explicitly tests each enumerated value. */ - -static rtx -convert_const_symbol_ref (exp, attr) - rtx exp; - struct attr_desc *attr; -{ - rtx condexp; - struct attr_value *av; - int i; - int num_alt = 0; - - for (av = attr->first_value; av; av = av->next) - num_alt++; - - /* Make a COND with all tests but the last, and in the original order. - Select the last value via the default. Note that the attr values - are constructed in reverse order. */ - - condexp = rtx_alloc (COND); - XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2); - av = attr->first_value; - XEXP (condexp, 1) = av->value; - - for (i = num_alt - 2; av = av->next, i >= 0; i--) - { - char *p, *string; - rtx value; - - string = p = (char *) oballoc (2 - + strlen (attr->name) - + strlen (XSTR (av->value, 0))); - strcpy (p, attr->name); - strcat (p, "_"); - strcat (p, XSTR (av->value, 0)); - for (; *p != '\0'; p++) - if (*p >= 'a' && *p <= 'z') - *p -= 'a' - 'A'; - - value = attr_rtx (SYMBOL_REF, string); - RTX_UNCHANGING_P (value) = 1; - - XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value); - - XVECEXP (condexp, 0, 2 * i + 1) = av->value; - } - - return condexp; -} - -/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE - expressions by converting them into a COND. This removes cases from this - program. Also, replace an attribute value of "*" with the default attribute - value. */ - -static rtx -make_canonical (attr, exp) - struct attr_desc *attr; - rtx exp; -{ - int i; - rtx newexp; - - switch (GET_CODE (exp)) - { - case CONST_INT: - exp = make_numeric_value (INTVAL (exp)); - break; - - case CONST_STRING: - if (! strcmp (XSTR (exp, 0), "*")) - { - if (attr == 0 || attr->default_val == 0) - fatal ("(attr_value \"*\") used in invalid context."); - exp = attr->default_val->value; - } - - break; - - case SYMBOL_REF: - if (!attr->is_const || RTX_UNCHANGING_P (exp)) - break; - /* The SYMBOL_REF is constant for a given run, so mark it as unchanging. - This makes the COND something that won't be considered an arbitrary - expression by walk_attr_value. */ - RTX_UNCHANGING_P (exp) = 1; - exp = convert_const_symbol_ref (exp, attr); - RTX_UNCHANGING_P (exp) = 1; - exp = check_attr_value (exp, attr); - /* Goto COND case since this is now a COND. Note that while the - new expression is rescanned, all symbol_ref notes are mared as - unchanging. */ - goto cond; - - case IF_THEN_ELSE: - newexp = rtx_alloc (COND); - XVEC (newexp, 0) = rtvec_alloc (2); - XVECEXP (newexp, 0, 0) = XEXP (exp, 0); - XVECEXP (newexp, 0, 1) = XEXP (exp, 1); - - XEXP (newexp, 1) = XEXP (exp, 2); - - exp = newexp; - /* Fall through to COND case since this is now a COND. */ - - case COND: - cond: - { - int allsame = 1; - rtx defval; - - /* First, check for degenerate COND. */ - if (XVECLEN (exp, 0) == 0) - return make_canonical (attr, XEXP (exp, 1)); - defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1)); - - for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i)); - XVECEXP (exp, 0, i + 1) - = make_canonical (attr, XVECEXP (exp, 0, i + 1)); - if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval)) - allsame = 0; - } - if (allsame) - return defval; - break; - } - } - - return exp; -} - -static rtx -copy_boolean (exp) - rtx exp; -{ - if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR) - return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)), - copy_boolean (XEXP (exp, 1))); - return exp; -} - -/* Given a value and an attribute description, return a `struct attr_value *' - that represents that value. This is either an existing structure, if the - value has been previously encountered, or a newly-created structure. - - `insn_code' is the code of an insn whose attribute has the specified - value (-2 if not processing an insn). We ensure that all insns for - a given value have the same number of alternatives if the value checks - alternatives. */ - -static struct attr_value * -get_attr_value (value, attr, insn_code) - rtx value; - struct attr_desc *attr; - int insn_code; -{ - struct attr_value *av; - int num_alt = 0; - - value = make_canonical (attr, value); - if (compares_alternatives_p (value)) - { - if (insn_code < 0 || insn_alternatives == NULL) - fatal ("(eq_attr \"alternatives\" ...) used in non-insn context"); - else - num_alt = insn_alternatives[insn_code]; - } - - for (av = attr->first_value; av; av = av->next) - if (rtx_equal_p (value, av->value) - && (num_alt == 0 || av->first_insn == NULL - || insn_alternatives[av->first_insn->insn_code])) - return av; - - av = (struct attr_value *) oballoc (sizeof (struct attr_value)); - av->value = value; - av->next = attr->first_value; - attr->first_value = av; - av->first_insn = NULL; - av->num_insns = 0; - av->has_asm_insn = 0; - - return av; -} - -/* After all DEFINE_DELAYs have been read in, create internal attributes - to generate the required routines. - - First, we compute the number of delay slots for each insn (as a COND of - each of the test expressions in DEFINE_DELAYs). Then, if more than one - delay type is specified, we compute a similar function giving the - DEFINE_DELAY ordinal for each insn. - - Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that - tells whether a given insn can be in that delay slot. - - Normal attribute filling and optimization expands these to contain the - information needed to handle delay slots. */ - -static void -expand_delays () -{ - struct delay_desc *delay; - rtx condexp; - rtx newexp; - int i; - char *p; - - /* First, generate data for `num_delay_slots' function. */ - - condexp = rtx_alloc (COND); - XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); - XEXP (condexp, 1) = make_numeric_value (0); - - for (i = 0, delay = delays; delay; i += 2, delay = delay->next) - { - XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); - XVECEXP (condexp, 0, i + 1) - = make_numeric_value (XVECLEN (delay->def, 1) / 3); - } - - make_internal_attr ("*num_delay_slots", condexp, 0); - - /* If more than one delay type, do the same for computing the delay type. */ - if (num_delays > 1) - { - condexp = rtx_alloc (COND); - XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); - XEXP (condexp, 1) = make_numeric_value (0); - - for (i = 0, delay = delays; delay; i += 2, delay = delay->next) - { - XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); - XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num); - } - - make_internal_attr ("*delay_type", condexp, 1); - } - - /* For each delay possibility and delay slot, compute an eligibility - attribute for non-annulled insns and for each type of annulled (annul - if true and annul if false). */ - for (delay = delays; delay; delay = delay->next) - { - for (i = 0; i < XVECLEN (delay->def, 1); i += 3) - { - condexp = XVECEXP (delay->def, 1, i); - if (condexp == 0) condexp = false_rtx; - newexp = attr_rtx (IF_THEN_ELSE, condexp, - make_numeric_value (1), make_numeric_value (0)); - - p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d", - delay->num, i / 3); - make_internal_attr (p, newexp, 1); - - if (have_annul_true) - { - condexp = XVECEXP (delay->def, 1, i + 1); - if (condexp == 0) condexp = false_rtx; - newexp = attr_rtx (IF_THEN_ELSE, condexp, - make_numeric_value (1), - make_numeric_value (0)); - p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2, - "*annul_true_%d_%d", delay->num, i / 3); - make_internal_attr (p, newexp, 1); - } - - if (have_annul_false) - { - condexp = XVECEXP (delay->def, 1, i + 2); - if (condexp == 0) condexp = false_rtx; - newexp = attr_rtx (IF_THEN_ELSE, condexp, - make_numeric_value (1), - make_numeric_value (0)); - p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2, - "*annul_false_%d_%d", delay->num, i / 3); - make_internal_attr (p, newexp, 1); - } - } - } -} - -/* This function is given a left and right side expression and an operator. - Each side is a conditional expression, each alternative of which has a - numerical value. The function returns another conditional expression - which, for every possible set of condition values, returns a value that is - the operator applied to the values of the two sides. - - Since this is called early, it must also support IF_THEN_ELSE. */ - -static rtx -operate_exp (op, left, right) - enum operator op; - rtx left, right; -{ - int left_value, right_value; - rtx newexp; - int i; - - /* If left is a string, apply operator to it and the right side. */ - if (GET_CODE (left) == CONST_STRING) - { - /* If right is also a string, just perform the operation. */ - if (GET_CODE (right) == CONST_STRING) - { - left_value = atoi (XSTR (left, 0)); - right_value = atoi (XSTR (right, 0)); - switch (op) - { - case PLUS_OP: - i = left_value + right_value; - break; - - case MINUS_OP: - i = left_value - right_value; - break; - - case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */ - if (left_value > right_value) - i = left_value - right_value; - else - i = 0; - break; - - case OR_OP: - i = left_value | right_value; - break; - - case EQ_OP: - i = left_value == right_value; - break; - - case RANGE_OP: - i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value; - break; - - case MAX_OP: - if (left_value > right_value) - i = left_value; - else - i = right_value; - break; - - case MIN_OP: - if (left_value < right_value) - i = left_value; - else - i = right_value; - break; - - default: - abort (); - } - - return make_numeric_value (i); - } - else if (GET_CODE (right) == IF_THEN_ELSE) - { - /* Apply recursively to all values within. */ - rtx newleft = operate_exp (op, left, XEXP (right, 1)); - rtx newright = operate_exp (op, left, XEXP (right, 2)); - if (rtx_equal_p (newleft, newright)) - return newleft; - return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright); - } - else if (GET_CODE (right) == COND) - { - int allsame = 1; - rtx defval; - - newexp = rtx_alloc (COND); - XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0)); - defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1)); - - for (i = 0; i < XVECLEN (right, 0); i += 2) - { - XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i); - XVECEXP (newexp, 0, i + 1) - = operate_exp (op, left, XVECEXP (right, 0, i + 1)); - if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1), - defval)) - allsame = 0; - } - - /* If the resulting cond is trivial (all alternatives - give the same value), optimize it away. */ - if (allsame) - { - obstack_free (rtl_obstack, newexp); - return operate_exp (op, left, XEXP (right, 1)); - } - - /* If the result is the same as the RIGHT operand, - just use that. */ - if (rtx_equal_p (newexp, right)) - { - obstack_free (rtl_obstack, newexp); - return right; - } - - return newexp; - } - else - fatal ("Badly formed attribute value"); - } - - /* Otherwise, do recursion the other way. */ - else if (GET_CODE (left) == IF_THEN_ELSE) - { - rtx newleft = operate_exp (op, XEXP (left, 1), right); - rtx newright = operate_exp (op, XEXP (left, 2), right); - if (rtx_equal_p (newleft, newright)) - return newleft; - return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright); - } - else if (GET_CODE (left) == COND) - { - int allsame = 1; - rtx defval; - - newexp = rtx_alloc (COND); - XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0)); - defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right); - - for (i = 0; i < XVECLEN (left, 0); i += 2) - { - XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i); - XVECEXP (newexp, 0, i + 1) - = operate_exp (op, XVECEXP (left, 0, i + 1), right); - if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1), - defval)) - allsame = 0; - } - - /* If the cond is trivial (all alternatives give the same value), - optimize it away. */ - if (allsame) - { - obstack_free (rtl_obstack, newexp); - return operate_exp (op, XEXP (left, 1), right); - } - - /* If the result is the same as the LEFT operand, - just use that. */ - if (rtx_equal_p (newexp, left)) - { - obstack_free (rtl_obstack, newexp); - return left; - } - - return newexp; - } - - else - fatal ("Badly formed attribute value."); - /* NOTREACHED */ - return NULL; -} - -/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we - construct a number of attributes. - - The first produces a function `function_units_used' which is given an - insn and produces an encoding showing which function units are required - for the execution of that insn. If the value is non-negative, the insn - uses that unit; otherwise, the value is a one's compliment mask of units - used. - - The second produces a function `result_ready_cost' which is used to - determine the time that the result of an insn will be ready and hence - a worst-case schedule. - - Both of these produce quite complex expressions which are then set as the - default value of internal attributes. Normal attribute simplification - should produce reasonable expressions. - - For each unit, a `_unit_ready_cost' function will take an - insn and give the delay until that unit will be ready with the result - and a `_unit_conflict_cost' function is given an insn already - executing on the unit and a candidate to execute and will give the - cost from the time the executing insn started until the candidate - can start (ignore limitations on the number of simultaneous insns). - - For each unit, a `_unit_blockage' function is given an insn - already executing on the unit and a candidate to execute and will - give the delay incurred due to function unit conflicts. The range of - blockage cost values for a given executing insn is given by the - `_unit_blockage_range' function. These values are encoded in - an int where the upper half gives the minimum value and the lower - half gives the maximum value. */ - -static void -expand_units () -{ - struct function_unit *unit, **unit_num; - struct function_unit_op *op, **op_array, ***unit_ops; - rtx unitsmask; - rtx readycost; - rtx newexp; - char *str; - int i, j, u, num, nvalues; - - /* Rebuild the condition for the unit to share the RTL expressions. - Sharing is required by simplify_by_exploding. Build the issue delay - expressions. Validate the expressions we were given for the conditions - and conflict vector. Then make attributes for use in the conflict - function. */ - - for (unit = units; unit; unit = unit->next) - { - rtx min_issue = make_numeric_value (unit->issue_delay.min); - - unit->condexp = check_attr_test (unit->condexp, 0); - - for (op = unit->ops; op; op = op->next) - { - rtx issue_delay = make_numeric_value (op->issue_delay); - rtx issue_exp = issue_delay; - - /* Build, validate, and simplify the issue delay expression. */ - if (op->conflict_exp != true_rtx) - issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp, - issue_exp, make_numeric_value (0)); - issue_exp = check_attr_value (make_canonical (NULL_ATTR, - issue_exp), - NULL_ATTR); - issue_exp = simplify_knowing (issue_exp, unit->condexp); - op->issue_exp = issue_exp; - - /* Make an attribute for use in the conflict function if needed. */ - unit->needs_conflict_function = (unit->issue_delay.min - != unit->issue_delay.max); - if (unit->needs_conflict_function) - { - str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS, - "*%s_cost_%d", unit->name, op->num); - make_internal_attr (str, issue_exp, 1); - } - - /* Validate the condition. */ - op->condexp = check_attr_test (op->condexp, 0); - } - } - - /* Compute the mask of function units used. Initially, the unitsmask is - zero. Set up a conditional to compute each unit's contribution. */ - unitsmask = make_numeric_value (0); - newexp = rtx_alloc (IF_THEN_ELSE); - XEXP (newexp, 2) = make_numeric_value (0); - - /* Merge each function unit into the unit mask attributes. */ - for (unit = units; unit; unit = unit->next) - { - XEXP (newexp, 0) = unit->condexp; - XEXP (newexp, 1) = make_numeric_value (1 << unit->num); - unitsmask = operate_exp (OR_OP, unitsmask, newexp); - } - - /* Simplify the unit mask expression, encode it, and make an attribute - for the function_units_used function. */ - unitsmask = simplify_by_exploding (unitsmask); - unitsmask = encode_units_mask (unitsmask); - make_internal_attr ("*function_units_used", unitsmask, 2); - - /* Create an array of ops for each unit. Add an extra unit for the - result_ready_cost function that has the ops of all other units. */ - unit_ops = (struct function_unit_op ***) - alloca ((num_units + 1) * sizeof (struct function_unit_op **)); - unit_num = (struct function_unit **) - alloca ((num_units + 1) * sizeof (struct function_unit *)); - - unit_num[num_units] = unit = (struct function_unit *) - alloca (sizeof (struct function_unit)); - unit->num = num_units; - unit->num_opclasses = 0; - - for (unit = units; unit; unit = unit->next) - { - unit_num[num_units]->num_opclasses += unit->num_opclasses; - unit_num[unit->num] = unit; - unit_ops[unit->num] = op_array = (struct function_unit_op **) - alloca (unit->num_opclasses * sizeof (struct function_unit_op *)); - - for (op = unit->ops; op; op = op->next) - op_array[op->num] = op; - } - - /* Compose the array of ops for the extra unit. */ - unit_ops[num_units] = op_array = (struct function_unit_op **) - alloca (unit_num[num_units]->num_opclasses - * sizeof (struct function_unit_op *)); - - for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next) - bcopy (unit_ops[unit->num], &op_array[i], - unit->num_opclasses * sizeof (struct function_unit_op *)); - - /* Compute the ready cost function for each unit by computing the - condition for each non-default value. */ - for (u = 0; u <= num_units; u++) - { - rtx orexp; - int value; - - unit = unit_num[u]; - op_array = unit_ops[unit->num]; - num = unit->num_opclasses; - - /* Sort the array of ops into increasing ready cost order. */ - for (i = 0; i < num; i++) - for (j = num - 1; j > i; j--) - if (op_array[j-1]->ready < op_array[j]->ready) - { - op = op_array[j]; - op_array[j] = op_array[j-1]; - op_array[j-1] = op; - } - - /* Determine how many distinct non-default ready cost values there - are. We use a default ready cost value of 1. */ - nvalues = 0; value = 1; - for (i = num - 1; i >= 0; i--) - if (op_array[i]->ready > value) - { - value = op_array[i]->ready; - nvalues++; - } - - if (nvalues == 0) - readycost = make_numeric_value (1); - else - { - /* Construct the ready cost expression as a COND of each value from - the largest to the smallest. */ - readycost = rtx_alloc (COND); - XVEC (readycost, 0) = rtvec_alloc (nvalues * 2); - XEXP (readycost, 1) = make_numeric_value (1); - - nvalues = 0; orexp = false_rtx; value = op_array[0]->ready; - for (i = 0; i < num; i++) - { - op = op_array[i]; - if (op->ready <= 1) - break; - else if (op->ready == value) - orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2); - else - { - XVECEXP (readycost, 0, nvalues * 2) = orexp; - XVECEXP (readycost, 0, nvalues * 2 + 1) - = make_numeric_value (value); - nvalues++; - value = op->ready; - orexp = op->condexp; - } - } - XVECEXP (readycost, 0, nvalues * 2) = orexp; - XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value); - } - - if (u < num_units) - { - rtx max_blockage = 0, min_blockage = 0; - - /* Simplify the readycost expression by only considering insns - that use the unit. */ - readycost = simplify_knowing (readycost, unit->condexp); - - /* Determine the blockage cost the executing insn (E) given - the candidate insn (C). This is the maximum of the issue - delay, the pipeline delay, and the simultaneity constraint. - Each function_unit_op represents the characteristics of the - candidate insn, so in the expressions below, C is a known - term and E is an unknown term. - - The issue delay function for C is op->issue_exp and is used to - write the `_unit_conflict_cost' function. Symbolicly - this is "ISSUE-DELAY (E,C)". - - The pipeline delay results form the FIFO constraint on the - function unit and is "READY-COST (E) + 1 - READY-COST (C)". - - The simultaneity constraint is based on how long it takes to - fill the unit given the minimum issue delay. FILL-TIME is the - constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and - the simultaneity constraint is "READY-COST (E) - FILL-TIME" - if SIMULTANEITY is non-zero and zero otherwise. - - Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is - - MAX (ISSUE-DELAY (E,C), - READY-COST (E) - (READY-COST (C) - 1)) - - and otherwise - - MAX (ISSUE-DELAY (E,C), - READY-COST (E) - (READY-COST (C) - 1), - READY-COST (E) - FILL-TIME) - - The `_unit_blockage' function is computed by determining - this value for each candidate insn. As these values are - computed, we also compute the upper and lower bounds for - BLOCKAGE (E,*). These are combined to form the function - `_unit_blockage_range'. Finally, the maximum blockage - cost, MAX (BLOCKAGE (*,*)), is computed. */ - - for (op = unit->ops; op; op = op->next) - { - rtx blockage = readycost; - int delay = op->ready - 1; - - if (unit->simultaneity != 0) - delay = MIN (delay, ((unit->simultaneity - 1) - * unit->issue_delay.min)); - - if (delay > 0) - blockage = operate_exp (POS_MINUS_OP, blockage, - make_numeric_value (delay)); - - blockage = operate_exp (MAX_OP, blockage, op->issue_exp); - blockage = simplify_knowing (blockage, unit->condexp); - - /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and - MIN (BLOCKAGE (E,*)). */ - if (max_blockage == 0) - max_blockage = min_blockage = blockage; - else - { - max_blockage - = simplify_knowing (operate_exp (MAX_OP, max_blockage, - blockage), - unit->condexp); - min_blockage - = simplify_knowing (operate_exp (MIN_OP, min_blockage, - blockage), - unit->condexp); - } - - /* Make an attribute for use in the blockage function. */ - str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS, - "*%s_block_%d", unit->name, op->num); - make_internal_attr (str, blockage, 1); - } - - /* Record MAX (BLOCKAGE (*,*)). */ - unit->max_blockage = max_attr_value (max_blockage); - - /* See if the upper and lower bounds of BLOCKAGE (E,*) are the - same. If so, the blockage function carries no additional - information and is not written. */ - newexp = operate_exp (EQ_OP, max_blockage, min_blockage); - newexp = simplify_knowing (newexp, unit->condexp); - unit->needs_blockage_function - = (GET_CODE (newexp) != CONST_STRING - || atoi (XSTR (newexp, 0)) != 1); - - /* If the all values of BLOCKAGE (E,C) have the same value, - neither blockage function is written. */ - unit->needs_range_function - = (unit->needs_blockage_function - || GET_CODE (max_blockage) != CONST_STRING); - - if (unit->needs_range_function) - { - /* Compute the blockage range function and make an attribute - for writing it's value. */ - newexp = operate_exp (RANGE_OP, min_blockage, max_blockage); - newexp = simplify_knowing (newexp, unit->condexp); - - str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"), - "*%s_unit_blockage_range", unit->name); - make_internal_attr (str, newexp, 4); - } - - str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"), - "*%s_unit_ready_cost", unit->name); - } - else - str = "*result_ready_cost"; - - /* Make an attribute for the ready_cost function. Simplifying - further with simplify_by_exploding doesn't win. */ - make_internal_attr (str, readycost, 0); - } - - /* For each unit that requires a conflict cost function, make an attribute - that maps insns to the operation number. */ - for (unit = units; unit; unit = unit->next) - { - rtx caseexp; - - if (! unit->needs_conflict_function - && ! unit->needs_blockage_function) - continue; - - caseexp = rtx_alloc (COND); - XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2); - - for (op = unit->ops; op; op = op->next) - { - /* Make our adjustment to the COND being computed. If we are the - last operation class, place our values into the default of the - COND. */ - if (op->num == unit->num_opclasses - 1) - { - XEXP (caseexp, 1) = make_numeric_value (op->num); - } - else - { - XVECEXP (caseexp, 0, op->num * 2) = op->condexp; - XVECEXP (caseexp, 0, op->num * 2 + 1) - = make_numeric_value (op->num); - } - } - - /* Simplifying caseexp with simplify_by_exploding doesn't win. */ - str = attr_printf (strlen (unit->name) + sizeof ("*_cases"), - "*%s_cases", unit->name); - make_internal_attr (str, caseexp, 1); - } -} - -/* Simplify EXP given KNOWN_TRUE. */ - -static rtx -simplify_knowing (exp, known_true) - rtx exp, known_true; -{ - if (GET_CODE (exp) != CONST_STRING) - { - exp = attr_rtx (IF_THEN_ELSE, known_true, exp, - make_numeric_value (max_attr_value (exp))); - exp = simplify_by_exploding (exp); - } - return exp; -} - -/* Translate the CONST_STRING expressions in X to change the encoding of - value. On input, the value is a bitmask with a one bit for each unit - used; on output, the value is the unit number (zero based) if one - and only one unit is used or the one's compliment of the bitmask. */ - -static rtx -encode_units_mask (x) - rtx x; -{ - register int i; - register int j; - register enum rtx_code code; - register char *fmt; - - code = GET_CODE (x); - - switch (code) - { - case CONST_STRING: - i = atoi (XSTR (x, 0)); - if (i < 0) - abort (); /* The sign bit encodes a one's compliment mask. */ - else if (i != 0 && i == (i & -i)) - /* Only one bit is set, so yield that unit number. */ - for (j = 0; (i >>= 1) != 0; j++) - ; - else - j = ~i; - return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j)); - - case REG: - case QUEUED: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case CC0: - case EQ_ATTR: - return x; - } - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - switch (fmt[i]) - { - case 'V': - case 'E': - for (j = 0; j < XVECLEN (x, i); j++) - XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j)); - break; - - case 'e': - XEXP (x, i) = encode_units_mask (XEXP (x, i)); - break; - } - } - return x; -} - -/* Once all attributes and insns have been read and checked, we construct for - each attribute value a list of all the insns that have that value for - the attribute. */ - -static void -fill_attr (attr) - struct attr_desc *attr; -{ - struct attr_value *av; - struct insn_ent *ie; - struct insn_def *id; - int i; - rtx value; - - /* Don't fill constant attributes. The value is independent of - any particular insn. */ - if (attr->is_const) - return; - - for (id = defs; id; id = id->next) - { - /* If no value is specified for this insn for this attribute, use the - default. */ - value = NULL; - if (XVEC (id->def, id->vec_idx)) - for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) - if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), - attr->name)) - value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1); - - if (value == NULL) - av = attr->default_val; - else - av = get_attr_value (value, attr, id->insn_code); - - ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent)); - ie->insn_code = id->insn_code; - ie->insn_index = id->insn_code; - insert_insn_ent (av, ie); - } -} - -/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a - test that checks relative positions of insns (uses MATCH_DUP or PC). - If so, replace it with what is obtained by passing the expression to - ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine - recursively on each value (including the default value). Otherwise, - return the value returned by NO_ADDRESS_FN applied to EXP. */ - -static rtx -substitute_address (exp, no_address_fn, address_fn) - rtx exp; - rtx (*no_address_fn) (); - rtx (*address_fn) (); -{ - int i; - rtx newexp; - - if (GET_CODE (exp) == COND) - { - /* See if any tests use addresses. */ - address_used = 0; - for (i = 0; i < XVECLEN (exp, 0); i += 2) - walk_attr_value (XVECEXP (exp, 0, i)); - - if (address_used) - return (*address_fn) (exp); - - /* Make a new copy of this COND, replacing each element. */ - newexp = rtx_alloc (COND); - XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0)); - for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i); - XVECEXP (newexp, 0, i + 1) - = substitute_address (XVECEXP (exp, 0, i + 1), - no_address_fn, address_fn); - } - - XEXP (newexp, 1) = substitute_address (XEXP (exp, 1), - no_address_fn, address_fn); - - return newexp; - } - - else if (GET_CODE (exp) == IF_THEN_ELSE) - { - address_used = 0; - walk_attr_value (XEXP (exp, 0)); - if (address_used) - return (*address_fn) (exp); - - return attr_rtx (IF_THEN_ELSE, - substitute_address (XEXP (exp, 0), - no_address_fn, address_fn), - substitute_address (XEXP (exp, 1), - no_address_fn, address_fn), - substitute_address (XEXP (exp, 2), - no_address_fn, address_fn)); - } - - return (*no_address_fn) (exp); -} - -/* Make new attributes from the `length' attribute. The following are made, - each corresponding to a function called from `shorten_branches' or - `get_attr_length': - - *insn_default_length This is the length of the insn to be returned - by `get_attr_length' before `shorten_branches' - has been called. In each case where the length - depends on relative addresses, the largest - possible is used. This routine is also used - to compute the initial size of the insn. - - *insn_variable_length_p This returns 1 if the insn's length depends - on relative addresses, zero otherwise. - - *insn_current_length This is only called when it is known that the - insn has a variable length and returns the - current length, based on relative addresses. - */ - -static void -make_length_attrs () -{ - static char *new_names[] = {"*insn_default_length", - "*insn_variable_length_p", - "*insn_current_length"}; - static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn}; - static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn}; - int i; - struct attr_desc *length_attr, *new_attr; - struct attr_value *av, *new_av; - struct insn_ent *ie, *new_ie; - - /* See if length attribute is defined. If so, it must be numeric. Make - it special so we don't output anything for it. */ - length_attr = find_attr ("length", 0); - if (length_attr == 0) - return; - - if (! length_attr->is_numeric) - fatal ("length attribute must be numeric."); - - length_attr->is_const = 0; - length_attr->is_special = 1; - - /* Make each new attribute, in turn. */ - for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++) - { - make_internal_attr (new_names[i], - substitute_address (length_attr->default_val->value, - no_address_fn[i], address_fn[i]), - 0); - new_attr = find_attr (new_names[i], 0); - for (av = length_attr->first_value; av; av = av->next) - for (ie = av->first_insn; ie; ie = ie->next) - { - new_av = get_attr_value (substitute_address (av->value, - no_address_fn[i], - address_fn[i]), - new_attr, ie->insn_code); - new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent)); - new_ie->insn_code = ie->insn_code; - new_ie->insn_index = ie->insn_index; - insert_insn_ent (new_av, new_ie); - } - } -} - -/* Utility functions called from above routine. */ - -static rtx -identity_fn (exp) - rtx exp; -{ - return exp; -} - -static rtx -zero_fn (exp) - rtx exp; -{ - return make_numeric_value (0); -} - -static rtx -one_fn (exp) - rtx exp; -{ - return make_numeric_value (1); -} - -static rtx -max_fn (exp) - rtx exp; -{ - return make_numeric_value (max_attr_value (exp)); -} - -/* Take a COND expression and see if any of the conditions in it can be - simplified. If any are known true or known false for the particular insn - code, the COND can be further simplified. - - Also call ourselves on any COND operations that are values of this COND. - - We do not modify EXP; rather, we make and return a new rtx. */ - -static rtx -simplify_cond (exp, insn_code, insn_index) - rtx exp; - int insn_code, insn_index; -{ - int i, j; - /* We store the desired contents here, - then build a new expression if they don't match EXP. */ - rtx defval = XEXP (exp, 1); - rtx new_defval = XEXP (exp, 1); - - int len = XVECLEN (exp, 0); - rtx *tests = (rtx *) alloca (len * sizeof (rtx)); - int allsame = 1; - char *first_spacer; - - /* This lets us free all storage allocated below, if appropriate. */ - first_spacer = (char *) obstack_finish (rtl_obstack); - - bcopy (&XVECEXP (exp, 0, 0), tests, len * sizeof (rtx)); - - /* See if default value needs simplification. */ - if (GET_CODE (defval) == COND) - new_defval = simplify_cond (defval, insn_code, insn_index); - - /* Simplify the subexpressions, and see what tests we can get rid of. */ - - for (i = 0; i < len; i += 2) - { - rtx newtest, newval; - - /* Simplify this test. */ - newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index); - tests[i] = newtest; - - newval = tests[i + 1]; - /* See if this value may need simplification. */ - if (GET_CODE (newval) == COND) - newval = simplify_cond (newval, insn_code, insn_index); - - /* Look for ways to delete or combine this test. */ - if (newtest == true_rtx) - { - /* If test is true, make this value the default - and discard this + any following tests. */ - len = i; - defval = tests[i + 1]; - new_defval = newval; - } - - else if (newtest == false_rtx) - { - /* If test is false, discard it and its value. */ - for (j = i; j < len - 2; j++) - tests[j] = tests[j + 2]; - len -= 2; - } - - else if (i > 0 && attr_equal_p (newval, tests[i - 1])) - { - /* If this value and the value for the prev test are the same, - merge the tests. */ - - tests[i - 2] - = insert_right_side (IOR, tests[i - 2], newtest, - insn_code, insn_index); - - /* Delete this test/value. */ - for (j = i; j < len - 2; j++) - tests[j] = tests[j + 2]; - len -= 2; - } - - else - tests[i + 1] = newval; - } - - /* If the last test in a COND has the same value - as the default value, that test isn't needed. */ - - while (len > 0 && attr_equal_p (tests[len - 1], new_defval)) - len -= 2; - - /* See if we changed anything. */ - if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1)) - allsame = 0; - else - for (i = 0; i < len; i++) - if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i))) - { - allsame = 0; - break; - } - - if (len == 0) - { - obstack_free (rtl_obstack, first_spacer); - if (GET_CODE (defval) == COND) - return simplify_cond (defval, insn_code, insn_index); - return defval; - } - else if (allsame) - { - obstack_free (rtl_obstack, first_spacer); - return exp; - } - else - { - rtx newexp = rtx_alloc (COND); - - XVEC (newexp, 0) = rtvec_alloc (len); - bcopy (tests, &XVECEXP (newexp, 0, 0), len * sizeof (rtx)); - XEXP (newexp, 1) = new_defval; - return newexp; - } -} - -/* Remove an insn entry from an attribute value. */ - -static void -remove_insn_ent (av, ie) - struct attr_value *av; - struct insn_ent *ie; -{ - struct insn_ent *previe; - - if (av->first_insn == ie) - av->first_insn = ie->next; - else - { - for (previe = av->first_insn; previe->next != ie; previe = previe->next) - ; - previe->next = ie->next; - } - - av->num_insns--; - if (ie->insn_code == -1) - av->has_asm_insn = 0; -} - -/* Insert an insn entry in an attribute value list. */ - -static void -insert_insn_ent (av, ie) - struct attr_value *av; - struct insn_ent *ie; -{ - ie->next = av->first_insn; - av->first_insn = ie; - av->num_insns++; - if (ie->insn_code == -1) - av->has_asm_insn = 1; -} - -/* This is a utility routine to take an expression that is a tree of either - AND or IOR expressions and insert a new term. The new term will be - inserted at the right side of the first node whose code does not match - the root. A new node will be created with the root's code. Its left - side will be the old right side and its right side will be the new - term. - - If the `term' is itself a tree, all its leaves will be inserted. */ - -static rtx -insert_right_side (code, exp, term, insn_code, insn_index) - enum rtx_code code; - rtx exp; - rtx term; - int insn_code, insn_index; -{ - rtx newexp; - - /* Avoid consing in some special cases. */ - if (code == AND && term == true_rtx) - return exp; - if (code == AND && term == false_rtx) - return false_rtx; - if (code == AND && exp == true_rtx) - return term; - if (code == AND && exp == false_rtx) - return false_rtx; - if (code == IOR && term == true_rtx) - return true_rtx; - if (code == IOR && term == false_rtx) - return exp; - if (code == IOR && exp == true_rtx) - return true_rtx; - if (code == IOR && exp == false_rtx) - return term; - if (attr_equal_p (exp, term)) - return exp; - - if (GET_CODE (term) == code) - { - exp = insert_right_side (code, exp, XEXP (term, 0), - insn_code, insn_index); - exp = insert_right_side (code, exp, XEXP (term, 1), - insn_code, insn_index); - - return exp; - } - - if (GET_CODE (exp) == code) - { - rtx new = insert_right_side (code, XEXP (exp, 1), - term, insn_code, insn_index); - if (new != XEXP (exp, 1)) - /* Make a copy of this expression and call recursively. */ - newexp = attr_rtx (code, XEXP (exp, 0), new); - else - newexp = exp; - } - else - { - /* Insert the new term. */ - newexp = attr_rtx (code, exp, term); - } - - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); -} - -/* If we have an expression which AND's a bunch of - (not (eq_attrq "alternative" "n")) - terms, we may have covered all or all but one of the possible alternatives. - If so, we can optimize. Similarly for IOR's of EQ_ATTR. - - This routine is passed an expression and either AND or IOR. It returns a - bitmask indicating which alternatives are mentioned within EXP. */ - -static int -compute_alternative_mask (exp, code) - rtx exp; - enum rtx_code code; -{ - char *string; - if (GET_CODE (exp) == code) - return compute_alternative_mask (XEXP (exp, 0), code) - | compute_alternative_mask (XEXP (exp, 1), code); - - else if (code == AND && GET_CODE (exp) == NOT - && GET_CODE (XEXP (exp, 0)) == EQ_ATTR - && XSTR (XEXP (exp, 0), 0) == alternative_name) - string = XSTR (XEXP (exp, 0), 1); - - else if (code == IOR && GET_CODE (exp) == EQ_ATTR - && XSTR (exp, 0) == alternative_name) - string = XSTR (exp, 1); - - else - return 0; - - if (string[1] == 0) - return 1 << (string[0] - '0'); - return 1 << atoi (string); -} - -/* Given I, a single-bit mask, return RTX to compare the `alternative' - attribute with the value represented by that bit. */ - -static rtx -make_alternative_compare (mask) - int mask; -{ - rtx newexp; - int i; - - /* Find the bit. */ - for (i = 0; (mask & (1 << i)) == 0; i++) - ; - - newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i)); - RTX_UNCHANGING_P (newexp) = 1; - - return newexp; -} - -/* If we are processing an (eq_attr "attr" "value") test, we find the value - of "attr" for this insn code. From that value, we can compute a test - showing when the EQ_ATTR will be true. This routine performs that - computation. If a test condition involves an address, we leave the EQ_ATTR - intact because addresses are only valid for the `length' attribute. - - EXP is the EQ_ATTR expression and VALUE is the value of that attribute - for the insn corresponding to INSN_CODE and INSN_INDEX. */ - -static rtx -evaluate_eq_attr (exp, value, insn_code, insn_index) - rtx exp; - rtx value; - int insn_code, insn_index; -{ - rtx orexp, andexp; - rtx right; - rtx newexp; - int i; - - if (GET_CODE (value) == CONST_STRING) - { - if (! strcmp (XSTR (value, 0), XSTR (exp, 1))) - newexp = true_rtx; - else - newexp = false_rtx; - } - else if (GET_CODE (value) == COND) - { - /* We construct an IOR of all the cases for which the requested attribute - value is present. Since we start with FALSE, if it is not present, - FALSE will be returned. - - Each case is the AND of the NOT's of the previous conditions with the - current condition; in the default case the current condition is TRUE. - - For each possible COND value, call ourselves recursively. - - The extra TRUE and FALSE expressions will be eliminated by another - call to the simplification routine. */ - - orexp = false_rtx; - andexp = true_rtx; - - if (current_alternative_string) - clear_struct_flag (value); - - for (i = 0; i < XVECLEN (value, 0); i += 2) - { - rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i), - insn_code, insn_index); - - SIMPLIFY_ALTERNATIVE (this); - - right = insert_right_side (AND, andexp, this, - insn_code, insn_index); - right = insert_right_side (AND, right, - evaluate_eq_attr (exp, - XVECEXP (value, 0, - i + 1), - insn_code, insn_index), - insn_code, insn_index); - orexp = insert_right_side (IOR, orexp, right, - insn_code, insn_index); - - /* Add this condition into the AND expression. */ - newexp = attr_rtx (NOT, this); - andexp = insert_right_side (AND, andexp, newexp, - insn_code, insn_index); - } - - /* Handle the default case. */ - right = insert_right_side (AND, andexp, - evaluate_eq_attr (exp, XEXP (value, 1), - insn_code, insn_index), - insn_code, insn_index); - newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index); - } - else - abort (); - - /* If uses an address, must return original expression. But set the - RTX_UNCHANGING_P bit so we don't try to simplify it again. */ - - address_used = 0; - walk_attr_value (newexp); - - if (address_used) - { - /* This had `&& current_alternative_string', which seems to be wrong. */ - if (! RTX_UNCHANGING_P (exp)) - return copy_rtx_unchanging (exp); - return exp; - } - else - return newexp; -} - -/* This routine is called when an AND of a term with a tree of AND's is - encountered. If the term or its complement is present in the tree, it - can be replaced with TRUE or FALSE, respectively. - - Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both - be true and hence are complementary. - - There is one special case: If we see - (and (not (eq_attr "att" "v1")) - (eq_attr "att" "v2")) - this can be replaced by (eq_attr "att" "v2"). To do this we need to - replace the term, not anything in the AND tree. So we pass a pointer to - the term. */ - -static rtx -simplify_and_tree (exp, pterm, insn_code, insn_index) - rtx exp; - rtx *pterm; - int insn_code, insn_index; -{ - rtx left, right; - rtx newexp; - rtx temp; - int left_eliminates_term, right_eliminates_term; - - if (GET_CODE (exp) == AND) - { - left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index); - right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index); - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (GET_CODE (exp), left, right); - - exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - else if (GET_CODE (exp) == IOR) - { - /* For the IOR case, we do the same as above, except that we can - only eliminate `term' if both sides of the IOR would do so. */ - temp = *pterm; - left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index); - left_eliminates_term = (temp == true_rtx); - - temp = *pterm; - right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index); - right_eliminates_term = (temp == true_rtx); - - if (left_eliminates_term && right_eliminates_term) - *pterm = true_rtx; - - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (GET_CODE (exp), left, right); - - exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - /* Check for simplifications. Do some extra checking here since this - routine is called so many times. */ - - if (exp == *pterm) - return true_rtx; - - else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm) - return false_rtx; - - else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0)) - return false_rtx; - - else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR) - { - if (XSTR (exp, 0) != XSTR (*pterm, 0)) - return exp; - - if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1))) - return true_rtx; - else - return false_rtx; - } - - else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT - && GET_CODE (XEXP (exp, 0)) == EQ_ATTR) - { - if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0)) - return exp; - - if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1))) - return false_rtx; - else - return true_rtx; - } - - else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT - && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR) - { - if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0)) - return exp; - - if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1))) - return false_rtx; - else - *pterm = true_rtx; - } - - else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT) - { - if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0))) - return true_rtx; - } - - else if (GET_CODE (exp) == NOT) - { - if (attr_equal_p (XEXP (exp, 0), *pterm)) - return false_rtx; - } - - else if (GET_CODE (*pterm) == NOT) - { - if (attr_equal_p (XEXP (*pterm, 0), exp)) - return false_rtx; - } - - else if (attr_equal_p (exp, *pterm)) - return true_rtx; - - return exp; -} - -/* Similar to `simplify_and_tree', but for IOR trees. */ - -static rtx -simplify_or_tree (exp, pterm, insn_code, insn_index) - rtx exp; - rtx *pterm; - int insn_code, insn_index; -{ - rtx left, right; - rtx newexp; - rtx temp; - int left_eliminates_term, right_eliminates_term; - - if (GET_CODE (exp) == IOR) - { - left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index); - right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index); - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (GET_CODE (exp), left, right); - - exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - else if (GET_CODE (exp) == AND) - { - /* For the AND case, we do the same as above, except that we can - only eliminate `term' if both sides of the AND would do so. */ - temp = *pterm; - left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index); - left_eliminates_term = (temp == false_rtx); - - temp = *pterm; - right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index); - right_eliminates_term = (temp == false_rtx); - - if (left_eliminates_term && right_eliminates_term) - *pterm = false_rtx; - - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (GET_CODE (exp), left, right); - - exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - if (attr_equal_p (exp, *pterm)) - return false_rtx; - - else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm)) - return true_rtx; - - else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp)) - return true_rtx; - - else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT - && GET_CODE (XEXP (exp, 0)) == EQ_ATTR - && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0)) - *pterm = false_rtx; - - else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT - && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR - && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0)) - return false_rtx; - - return exp; -} - -/* Given an expression, see if it can be simplified for a particular insn - code based on the values of other attributes being tested. This can - eliminate nested get_attr_... calls. - - Note that if an endless recursion is specified in the patterns, the - optimization will loop. However, it will do so in precisely the cases where - an infinite recursion loop could occur during compilation. It's better that - it occurs here! */ - -static rtx -simplify_test_exp (exp, insn_code, insn_index) - rtx exp; - int insn_code, insn_index; -{ - rtx left, right; - struct attr_desc *attr; - struct attr_value *av; - struct insn_ent *ie; - int i; - rtx newexp = exp; - char *spacer = (char *) obstack_finish (rtl_obstack); - - /* Don't re-simplify something we already simplified. */ - if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp)) - return exp; - - switch (GET_CODE (exp)) - { - case AND: - left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (left); - if (left == false_rtx) - { - obstack_free (rtl_obstack, spacer); - return false_rtx; - } - right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (right); - if (left == false_rtx) - { - obstack_free (rtl_obstack, spacer); - return false_rtx; - } - - /* If either side is an IOR and we have (eq_attr "alternative" ..") - present on both sides, apply the distributive law since this will - yield simplifications. */ - if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR) - && compute_alternative_mask (left, IOR) - && compute_alternative_mask (right, IOR)) - { - if (GET_CODE (left) == IOR) - { - rtx tem = left; - left = right; - right = tem; - } - - newexp = attr_rtx (IOR, - attr_rtx (AND, left, XEXP (right, 0)), - attr_rtx (AND, left, XEXP (right, 1))); - - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - - /* Try with the term on both sides. */ - right = simplify_and_tree (right, &left, insn_code, insn_index); - if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) - left = simplify_and_tree (left, &right, insn_code, insn_index); - - if (left == false_rtx || right == false_rtx) - { - obstack_free (rtl_obstack, spacer); - return false_rtx; - } - else if (left == true_rtx) - { - return right; - } - else if (right == true_rtx) - { - return left; - } - /* See if all or all but one of the insn's alternatives are specified - in this tree. Optimize if so. */ - - else if (insn_code >= 0 - && (GET_CODE (left) == AND - || (GET_CODE (left) == NOT - && GET_CODE (XEXP (left, 0)) == EQ_ATTR - && XSTR (XEXP (left, 0), 0) == alternative_name) - || GET_CODE (right) == AND - || (GET_CODE (right) == NOT - && GET_CODE (XEXP (right, 0)) == EQ_ATTR - && XSTR (XEXP (right, 0), 0) == alternative_name))) - { - i = compute_alternative_mask (exp, AND); - if (i & ~insn_alternatives[insn_code]) - fatal ("Illegal alternative specified for pattern number %d", - insn_index); - - /* If all alternatives are excluded, this is false. */ - i ^= insn_alternatives[insn_code]; - if (i == 0) - return false_rtx; - else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) - { - /* If just one excluded, AND a comparison with that one to the - front of the tree. The others will be eliminated by - optimization. We do not want to do this if the insn has one - alternative and we have tested none of them! */ - left = make_alternative_compare (i); - right = simplify_and_tree (exp, &left, insn_code, insn_index); - newexp = attr_rtx (AND, left, right); - - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (AND, left, right); - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - break; - - case IOR: - left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (left); - if (left == true_rtx) - { - obstack_free (rtl_obstack, spacer); - return true_rtx; - } - right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (right); - if (right == true_rtx) - { - obstack_free (rtl_obstack, spacer); - return true_rtx; - } - - right = simplify_or_tree (right, &left, insn_code, insn_index); - if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) - left = simplify_or_tree (left, &right, insn_code, insn_index); - - if (right == true_rtx || left == true_rtx) - { - obstack_free (rtl_obstack, spacer); - return true_rtx; - } - else if (left == false_rtx) - { - return right; - } - else if (right == false_rtx) - { - return left; - } - - /* Test for simple cases where the distributive law is useful. I.e., - convert (ior (and (x) (y)) - (and (x) (z))) - to (and (x) - (ior (y) (z))) - */ - - else if (GET_CODE (left) == AND && GET_CODE (right) == AND - && attr_equal_p (XEXP (left, 0), XEXP (right, 0))) - { - newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1)); - - left = XEXP (left, 0); - right = newexp; - newexp = attr_rtx (AND, left, right); - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - - /* See if all or all but one of the insn's alternatives are specified - in this tree. Optimize if so. */ - - else if (insn_code >= 0 - && (GET_CODE (left) == IOR - || (GET_CODE (left) == EQ_ATTR - && XSTR (left, 0) == alternative_name) - || GET_CODE (right) == IOR - || (GET_CODE (right) == EQ_ATTR - && XSTR (right, 0) == alternative_name))) - { - i = compute_alternative_mask (exp, IOR); - if (i & ~insn_alternatives[insn_code]) - fatal ("Illegal alternative specified for pattern number %d", - insn_index); - - /* If all alternatives are included, this is true. */ - i ^= insn_alternatives[insn_code]; - if (i == 0) - return true_rtx; - else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) - { - /* If just one excluded, IOR a comparison with that one to the - front of the tree. The others will be eliminated by - optimization. We do not want to do this if the insn has one - alternative and we have tested none of them! */ - left = make_alternative_compare (i); - right = simplify_and_tree (exp, &left, insn_code, insn_index); - newexp = attr_rtx (IOR, attr_rtx (NOT, left), right); - - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - } - - if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) - { - newexp = attr_rtx (IOR, left, right); - return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - break; - - case NOT: - if (GET_CODE (XEXP (exp, 0)) == NOT) - { - left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0), - insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (left); - return left; - } - - left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); - SIMPLIFY_ALTERNATIVE (left); - if (GET_CODE (left) == NOT) - return XEXP (left, 0); - - if (left == false_rtx) - { - obstack_free (rtl_obstack, spacer); - return true_rtx; - } - else if (left == true_rtx) - { - obstack_free (rtl_obstack, spacer); - return false_rtx; - } - - /* Try to apply De`Morgan's laws. */ - else if (GET_CODE (left) == IOR) - { - newexp = attr_rtx (AND, - attr_rtx (NOT, XEXP (left, 0)), - attr_rtx (NOT, XEXP (left, 1))); - - newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - else if (GET_CODE (left) == AND) - { - newexp = attr_rtx (IOR, - attr_rtx (NOT, XEXP (left, 0)), - attr_rtx (NOT, XEXP (left, 1))); - - newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); - } - else if (left != XEXP (exp, 0)) - { - newexp = attr_rtx (NOT, left); - } - break; - - case EQ_ATTR: - if (current_alternative_string && XSTR (exp, 0) == alternative_name) - return (XSTR (exp, 1) == current_alternative_string - ? true_rtx : false_rtx); - - /* Look at the value for this insn code in the specified attribute. - We normally can replace this comparison with the condition that - would give this insn the values being tested for. */ - if (XSTR (exp, 0) != alternative_name - && (attr = find_attr (XSTR (exp, 0), 0)) != NULL) - for (av = attr->first_value; av; av = av->next) - for (ie = av->first_insn; ie; ie = ie->next) - if (ie->insn_code == insn_code) - return evaluate_eq_attr (exp, av->value, insn_code, insn_index); - } - - /* We have already simplified this expression. Simplifying it again - won't buy anything unless we weren't given a valid insn code - to process (i.e., we are canonicalizing something.). */ - if (insn_code != -2 /* Seems wrong: && current_alternative_string. */ - && ! RTX_UNCHANGING_P (newexp)) - return copy_rtx_unchanging (newexp); - - return newexp; -} - -/* Optimize the attribute lists by seeing if we can determine conditional - values from the known values of other attributes. This will save subroutine - calls during the compilation. */ - -static void -optimize_attrs () -{ - struct attr_desc *attr; - struct attr_value *av; - struct insn_ent *ie; - rtx newexp; - int something_changed = 1; - int i; - struct attr_value_list { struct attr_value *av; - struct insn_ent *ie; - struct attr_desc * attr; - struct attr_value_list *next; }; - struct attr_value_list **insn_code_values; - struct attr_value_list *iv; - - /* For each insn code, make a list of all the insn_ent's for it, - for all values for all attributes. */ - - /* Make 2 extra elements, for "code" values -2 and -1. */ - insn_code_values - = (struct attr_value_list **) alloca ((insn_code_number + 2) - * sizeof (struct attr_value_list *)); - bzero (insn_code_values, - (insn_code_number + 2) * sizeof (struct attr_value_list *)); - /* Offset the table address so we can index by -2 or -1. */ - insn_code_values += 2; - - for (i = 0; i < MAX_ATTRS_INDEX; i++) - for (attr = attrs[i]; attr; attr = attr->next) - for (av = attr->first_value; av; av = av->next) - for (ie = av->first_insn; ie; ie = ie->next) - { - iv = ((struct attr_value_list *) - alloca (sizeof (struct attr_value_list))); - iv->attr = attr; - iv->av = av; - iv->ie = ie; - iv->next = insn_code_values[ie->insn_code]; - insn_code_values[ie->insn_code] = iv; - } - - /* Process one insn code at a time. */ - for (i = -2; i < insn_code_number; i++) - { - /* Clear the MEM_IN_STRUCT_P flag everywhere relevant. - We use it to mean "already simplified for this insn". */ - for (iv = insn_code_values[i]; iv; iv = iv->next) - clear_struct_flag (iv->av->value); - - /* Loop until nothing changes for one iteration. */ - something_changed = 1; - while (something_changed) - { - something_changed = 0; - for (iv = insn_code_values[i]; iv; iv = iv->next) - { - struct obstack *old = rtl_obstack; - char *spacer = (char *) obstack_finish (temp_obstack); - - attr = iv->attr; - av = iv->av; - ie = iv->ie; - if (GET_CODE (av->value) != COND) - continue; - - rtl_obstack = temp_obstack; -#if 0 /* This was intended as a speed up, but it was slower. */ - if (insn_n_alternatives[ie->insn_code] > 6 - && count_sub_rtxs (av->value, 200) >= 200) - newexp = simplify_by_alternatives (av->value, ie->insn_code, - ie->insn_index); - else -#endif - newexp = simplify_cond (av->value, ie->insn_code, - ie->insn_index); - - rtl_obstack = old; - if (newexp != av->value) - { - newexp = attr_copy_rtx (newexp); - remove_insn_ent (av, ie); - av = get_attr_value (newexp, attr, ie->insn_code); - iv->av = av; - insert_insn_ent (av, ie); - something_changed = 1; - } - obstack_free (temp_obstack, spacer); - } - } - } -} - -#if 0 -static rtx -simplify_by_alternatives (exp, insn_code, insn_index) - rtx exp; - int insn_code, insn_index; -{ - int i; - int len = insn_n_alternatives[insn_code]; - rtx newexp = rtx_alloc (COND); - rtx ultimate; - - - XVEC (newexp, 0) = rtvec_alloc (len * 2); - - /* It will not matter what value we use as the default value - of the new COND, since that default will never be used. - Choose something of the right type. */ - for (ultimate = exp; GET_CODE (ultimate) == COND;) - ultimate = XEXP (ultimate, 1); - XEXP (newexp, 1) = ultimate; - - for (i = 0; i < insn_n_alternatives[insn_code]; i++) - { - current_alternative_string = attr_numeral (i); - XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i); - XVECEXP (newexp, 0, i * 2 + 1) - = simplify_cond (exp, insn_code, insn_index); - } - - current_alternative_string = 0; - return simplify_cond (newexp, insn_code, insn_index); -} -#endif - -/* If EXP is a suitable expression, reorganize it by constructing an - equivalent expression that is a COND with the tests being all combinations - of attribute values and the values being simple constants. */ - -static rtx -simplify_by_exploding (exp) - rtx exp; -{ - rtx list = 0, link, condexp, defval; - struct dimension *space; - rtx *condtest, *condval; - int i, j, total, ndim = 0; - int most_tests, num_marks, new_marks; - - /* Locate all the EQ_ATTR expressions. */ - if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0) - { - unmark_used_attributes (list, 0, 0); - return exp; - } - - /* Create an attribute space from the list of used attributes. For each - dimension in the attribute space, record the attribute, list of values - used, and number of values used. Add members to the list of values to - cover the domain of the attribute. This makes the expanded COND form - order independent. */ - - space = (struct dimension *) alloca (ndim * sizeof (struct dimension)); - - total = 1; - for (ndim = 0; list; ndim++) - { - /* Pull the first attribute value from the list and record that - attribute as another dimension in the attribute space. */ - char *name = XSTR (XEXP (list, 0), 0); - rtx *prev; - - if ((space[ndim].attr = find_attr (name, 0)) == 0 - || space[ndim].attr->is_numeric) - { - unmark_used_attributes (list, space, ndim); - return exp; - } - - /* Add all remaining attribute values that refer to this attribute. */ - space[ndim].num_values = 0; - space[ndim].values = 0; - prev = &list; - for (link = list; link; link = *prev) - if (! strcmp (XSTR (XEXP (link, 0), 0), name)) - { - space[ndim].num_values++; - *prev = XEXP (link, 1); - XEXP (link, 1) = space[ndim].values; - space[ndim].values = link; - } - else - prev = &XEXP (link, 1); - - /* Add sufficient members to the list of values to make the list - mutually exclusive and record the total size of the attribute - space. */ - total *= add_values_to_cover (&space[ndim]); - } - - /* Sort the attribute space so that the attributes go from non-constant - to constant and from most values to least values. */ - for (i = 0; i < ndim; i++) - for (j = ndim - 1; j > i; j--) - if ((space[j-1].attr->is_const && !space[j].attr->is_const) - || space[j-1].num_values < space[j].num_values) - { - struct dimension tmp; - tmp = space[j]; - space[j] = space[j-1]; - space[j-1] = tmp; - } - - /* Establish the initial current value. */ - for (i = 0; i < ndim; i++) - space[i].current_value = space[i].values; - - condtest = (rtx *) alloca (total * sizeof (rtx)); - condval = (rtx *) alloca (total * sizeof (rtx)); - - /* Expand the tests and values by iterating over all values in the - attribute space. */ - for (i = 0;; i++) - { - condtest[i] = test_for_current_value (space, ndim); - condval[i] = simplify_with_current_value (exp, space, ndim); - if (! increment_current_value (space, ndim)) - break; - } - if (i != total - 1) - abort (); - - /* We are now finished with the original expression. */ - unmark_used_attributes (0, space, ndim); - - /* Find the most used constant value and make that the default. */ - most_tests = -1; - for (i = num_marks = 0; i < total; i++) - if (GET_CODE (condval[i]) == CONST_STRING - && ! MEM_VOLATILE_P (condval[i])) - { - /* Mark the unmarked constant value and count how many are marked. */ - MEM_VOLATILE_P (condval[i]) = 1; - for (j = new_marks = 0; j < total; j++) - if (GET_CODE (condval[j]) == CONST_STRING - && MEM_VOLATILE_P (condval[j])) - new_marks++; - if (new_marks - num_marks > most_tests) - { - most_tests = new_marks - num_marks; - defval = condval[i]; - } - num_marks = new_marks; - } - /* Clear all the marks. */ - for (i = 0; i < total; i++) - MEM_VOLATILE_P (condval[i]) = 0; - - /* Give up if nothing is constant. */ - if (num_marks == 0) - return exp; - - /* If all values are the default, use that. */ - if (total == most_tests) - return defval; - - /* Make a COND with the most common constant value the default. (A more - complex method where tests with the same value were combined didn't - seem to improve things.) */ - condexp = rtx_alloc (COND); - XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2); - XEXP (condexp, 1) = defval; - for (i = j = 0; i < total; i++) - if (condval[i] != defval) - { - XVECEXP (condexp, 0, 2 * j) = condtest[i]; - XVECEXP (condexp, 0, 2 * j + 1) = condval[i]; - j++; - } - - return condexp; -} - -/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and - verify that EXP can be simplified to a constant term if all the EQ_ATTR - tests have known value. */ - -static int -find_and_mark_used_attributes (exp, terms, nterms) - rtx exp, *terms; - int *nterms; -{ - int i; - - switch (GET_CODE (exp)) - { - case EQ_ATTR: - if (! MEM_VOLATILE_P (exp)) - { - rtx link = rtx_alloc (EXPR_LIST); - XEXP (link, 0) = exp; - XEXP (link, 1) = *terms; - *terms = link; - *nterms += 1; - MEM_VOLATILE_P (exp) = 1; - } - case CONST_STRING: - return 1; - - case IF_THEN_ELSE: - if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms)) - return 0; - case IOR: - case AND: - if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms)) - return 0; - case NOT: - if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms)) - return 0; - return 1; - - case COND: - for (i = 0; i < XVECLEN (exp, 0); i++) - if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms)) - return 0; - if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms)) - return 0; - return 1; - } - - return 0; -} - -/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and - in the values of the NDIM-dimensional attribute space SPACE. */ - -static void -unmark_used_attributes (list, space, ndim) - rtx list; - struct dimension *space; - int ndim; -{ - rtx link, exp; - int i; - - for (i = 0; i < ndim; i++) - unmark_used_attributes (space[i].values, 0, 0); - - for (link = list; link; link = XEXP (link, 1)) - { - exp = XEXP (link, 0); - if (GET_CODE (exp) == EQ_ATTR) - MEM_VOLATILE_P (exp) = 0; - } -} - -/* Update the attribute dimension DIM so that all values of the attribute - are tested. Return the updated number of values. */ - -static int -add_values_to_cover (dim) - struct dimension *dim; -{ - struct attr_value *av; - rtx exp, link, *prev; - int nalt = 0; - - for (av = dim->attr->first_value; av; av = av->next) - if (GET_CODE (av->value) == CONST_STRING) - nalt++; - - if (nalt < dim->num_values) - abort (); - else if (nalt == dim->num_values) - ; /* Ok. */ - else if (nalt * 2 < dim->num_values * 3) - { - /* Most all the values of the attribute are used, so add all the unused - values. */ - prev = &dim->values; - for (link = dim->values; link; link = *prev) - prev = &XEXP (link, 1); - - for (av = dim->attr->first_value; av; av = av->next) - if (GET_CODE (av->value) == CONST_STRING) - { - exp = attr_eq (dim->attr->name, XSTR (av->value, 0)); - if (MEM_VOLATILE_P (exp)) - continue; - - link = rtx_alloc (EXPR_LIST); - XEXP (link, 0) = exp; - XEXP (link, 1) = 0; - *prev = link; - prev = &XEXP (link, 1); - } - dim->num_values = nalt; - } - else - { - rtx orexp = false_rtx; - - /* Very few values are used, so compute a mutually exclusive - expression. (We could do this for numeric values if that becomes - important.) */ - prev = &dim->values; - for (link = dim->values; link; link = *prev) - { - orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2); - prev = &XEXP (link, 1); - } - link = rtx_alloc (EXPR_LIST); - XEXP (link, 0) = attr_rtx (NOT, orexp); - XEXP (link, 1) = 0; - *prev = link; - dim->num_values++; - } - return dim->num_values; -} - -/* Increment the current value for the NDIM-dimensional attribute space SPACE - and return FALSE if the increment overflowed. */ - -static int -increment_current_value (space, ndim) - struct dimension *space; - int ndim; -{ - int i; - - for (i = ndim - 1; i >= 0; i--) - { - if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0) - space[i].current_value = space[i].values; - else - return 1; - } - return 0; -} - -/* Construct an expression corresponding to the current value for the - NDIM-dimensional attribute space SPACE. */ - -static rtx -test_for_current_value (space, ndim) - struct dimension *space; - int ndim; -{ - int i; - rtx exp = true_rtx; - - for (i = 0; i < ndim; i++) - exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0), - -2, -2); - - return exp; -} - -/* Given the current value of the NDIM-dimensional attribute space SPACE, - set the corresponding EQ_ATTR expressions to that value and reduce - the expression EXP as much as possible. On input [and output], all - known EQ_ATTR expressions are set to FALSE. */ - -static rtx -simplify_with_current_value (exp, space, ndim) - rtx exp; - struct dimension *space; - int ndim; -{ - int i; - rtx x; - - /* Mark each current value as TRUE. */ - for (i = 0; i < ndim; i++) - { - x = XEXP (space[i].current_value, 0); - if (GET_CODE (x) == EQ_ATTR) - MEM_VOLATILE_P (x) = 0; - } - - exp = simplify_with_current_value_aux (exp); - - /* Change each current value back to FALSE. */ - for (i = 0; i < ndim; i++) - { - x = XEXP (space[i].current_value, 0); - if (GET_CODE (x) == EQ_ATTR) - MEM_VOLATILE_P (x) = 1; - } - - return exp; -} - -/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of - all EQ_ATTR expressions. */ - -static rtx -simplify_with_current_value_aux (exp) - rtx exp; -{ - register int i; - rtx cond; - - switch (GET_CODE (exp)) - { - case EQ_ATTR: - if (MEM_VOLATILE_P (exp)) - return false_rtx; - else - return true_rtx; - case CONST_STRING: - return exp; - - case IF_THEN_ELSE: - cond = simplify_with_current_value_aux (XEXP (exp, 0)); - if (cond == true_rtx) - return simplify_with_current_value_aux (XEXP (exp, 1)); - else if (cond == false_rtx) - return simplify_with_current_value_aux (XEXP (exp, 2)); - else - return attr_rtx (IF_THEN_ELSE, cond, - simplify_with_current_value_aux (XEXP (exp, 1)), - simplify_with_current_value_aux (XEXP (exp, 2))); - - case IOR: - cond = simplify_with_current_value_aux (XEXP (exp, 1)); - if (cond == true_rtx) - return cond; - else if (cond == false_rtx) - return simplify_with_current_value_aux (XEXP (exp, 0)); - else - return attr_rtx (IOR, cond, - simplify_with_current_value_aux (XEXP (exp, 0))); - - case AND: - cond = simplify_with_current_value_aux (XEXP (exp, 1)); - if (cond == true_rtx) - return simplify_with_current_value_aux (XEXP (exp, 0)); - else if (cond == false_rtx) - return cond; - else - return attr_rtx (AND, cond, - simplify_with_current_value_aux (XEXP (exp, 0))); - - case NOT: - cond = simplify_with_current_value_aux (XEXP (exp, 0)); - if (cond == true_rtx) - return false_rtx; - else if (cond == false_rtx) - return true_rtx; - else - return attr_rtx (NOT, cond); - - case COND: - for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i)); - if (cond == true_rtx) - return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1)); - else if (cond == false_rtx) - continue; - else - abort (); /* With all EQ_ATTR's of known value, a case should - have been selected. */ - } - return simplify_with_current_value_aux (XEXP (exp, 1)); - } - abort (); -} - -/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */ - -static void -clear_struct_flag (x) - rtx x; -{ - register int i; - register int j; - register enum rtx_code code; - register char *fmt; - - MEM_IN_STRUCT_P (x) = 0; - if (RTX_UNCHANGING_P (x)) - return; - - code = GET_CODE (x); - - switch (code) - { - case REG: - case QUEUED: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case CC0: - case EQ_ATTR: - case ATTR_FLAG: - return; - } - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - switch (fmt[i]) - { - case 'V': - case 'E': - for (j = 0; j < XVECLEN (x, i); j++) - clear_struct_flag (XVECEXP (x, i, j)); - break; - - case 'e': - clear_struct_flag (XEXP (x, i)); - break; - } - } -} - -/* Return the number of RTX objects making up the expression X. - But if we count more more than MAX objects, stop counting. */ - -static int -count_sub_rtxs (x, max) - rtx x; - int max; -{ - register int i; - register int j; - register enum rtx_code code; - register char *fmt; - int total = 0; - - code = GET_CODE (x); - - switch (code) - { - case REG: - case QUEUED: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case CC0: - case EQ_ATTR: - case ATTR_FLAG: - return 1; - } - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (total >= max) - return total; - - switch (fmt[i]) - { - case 'V': - case 'E': - for (j = 0; j < XVECLEN (x, i); j++) - total += count_sub_rtxs (XVECEXP (x, i, j), max); - break; - - case 'e': - total += count_sub_rtxs (XEXP (x, i), max); - break; - } - } - return total; - -} - -/* Create table entries for DEFINE_ATTR. */ - -static void -gen_attr (exp) - rtx exp; -{ - struct attr_desc *attr; - struct attr_value *av; - char *name_ptr; - char *p; - - /* Make a new attribute structure. Check for duplicate by looking at - attr->default_val, since it is initialized by this routine. */ - attr = find_attr (XSTR (exp, 0), 1); - if (attr->default_val) - fatal ("Duplicate definition for `%s' attribute", attr->name); - - if (*XSTR (exp, 1) == '\0') - attr->is_numeric = 1; - else - { - name_ptr = XSTR (exp, 1); - while ((p = next_comma_elt (&name_ptr)) != NULL) - { - av = (struct attr_value *) oballoc (sizeof (struct attr_value)); - av->value = attr_rtx (CONST_STRING, p); - av->next = attr->first_value; - attr->first_value = av; - av->first_insn = NULL; - av->num_insns = 0; - av->has_asm_insn = 0; - } - } - - if (GET_CODE (XEXP (exp, 2)) == CONST) - { - attr->is_const = 1; - if (attr->is_numeric) - fatal ("Constant attributes may not take numeric values"); - /* Get rid of the CONST node. It is allowed only at top-level. */ - XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0); - } - - if (! strcmp (attr->name, "length") && ! attr->is_numeric) - fatal ("`length' attribute must take numeric values"); - - /* Set up the default value. */ - XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); - attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2); -} - -/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of - alternatives in the constraints. Assume all MATCH_OPERANDs have the same - number of alternatives as this should be checked elsewhere. */ - -static int -count_alternatives (exp) - rtx exp; -{ - int i, j, n; - char *fmt; - - if (GET_CODE (exp) == MATCH_OPERAND) - return n_comma_elts (XSTR (exp, 2)); - - for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); - i < GET_RTX_LENGTH (GET_CODE (exp)); i++) - switch (*fmt++) - { - case 'e': - case 'u': - n = count_alternatives (XEXP (exp, i)); - if (n) - return n; - break; - - case 'E': - case 'V': - if (XVEC (exp, i) != NULL) - for (j = 0; j < XVECLEN (exp, i); j++) - { - n = count_alternatives (XVECEXP (exp, i, j)); - if (n) - return n; - } - } - - return 0; -} - -/* Returns non-zero if the given expression contains an EQ_ATTR with the - `alternative' attribute. */ - -static int -compares_alternatives_p (exp) - rtx exp; -{ - int i, j; - char *fmt; - - if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name) - return 1; - - for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); - i < GET_RTX_LENGTH (GET_CODE (exp)); i++) - switch (*fmt++) - { - case 'e': - case 'u': - if (compares_alternatives_p (XEXP (exp, i))) - return 1; - break; - - case 'E': - for (j = 0; j < XVECLEN (exp, i); j++) - if (compares_alternatives_p (XVECEXP (exp, i, j))) - return 1; - break; - } - - return 0; -} - -/* Returns non-zero is INNER is contained in EXP. */ - -static int -contained_in_p (inner, exp) - rtx inner; - rtx exp; -{ - int i, j; - char *fmt; - - if (rtx_equal_p (inner, exp)) - return 1; - - for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); - i < GET_RTX_LENGTH (GET_CODE (exp)); i++) - switch (*fmt++) - { - case 'e': - case 'u': - if (contained_in_p (inner, XEXP (exp, i))) - return 1; - break; - - case 'E': - for (j = 0; j < XVECLEN (exp, i); j++) - if (contained_in_p (inner, XVECEXP (exp, i, j))) - return 1; - break; - } - - return 0; -} - -/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ - -static void -gen_insn (exp) - rtx exp; -{ - struct insn_def *id; - - id = (struct insn_def *) oballoc (sizeof (struct insn_def)); - id->next = defs; - defs = id; - id->def = exp; - - switch (GET_CODE (exp)) - { - case DEFINE_INSN: - id->insn_code = insn_code_number++; - id->insn_index = insn_index_number++; - id->num_alternatives = count_alternatives (exp); - if (id->num_alternatives == 0) - id->num_alternatives = 1; - id->vec_idx = 4; - break; - - case DEFINE_PEEPHOLE: - id->insn_code = insn_code_number++; - id->insn_index = insn_index_number++; - id->num_alternatives = count_alternatives (exp); - if (id->num_alternatives == 0) - id->num_alternatives = 1; - id->vec_idx = 3; - break; - - case DEFINE_ASM_ATTRIBUTES: - id->insn_code = -1; - id->insn_index = -1; - id->num_alternatives = 1; - id->vec_idx = 0; - got_define_asm_attributes = 1; - break; - } -} - -/* Process a DEFINE_DELAY. Validate the vector length, check if annul - true or annul false is specified, and make a `struct delay_desc'. */ - -static void -gen_delay (def) - rtx def; -{ - struct delay_desc *delay; - int i; - - if (XVECLEN (def, 1) % 3 != 0) - fatal ("Number of elements in DEFINE_DELAY must be multiple of three."); - - for (i = 0; i < XVECLEN (def, 1); i += 3) - { - if (XVECEXP (def, 1, i + 1)) - have_annul_true = 1; - if (XVECEXP (def, 1, i + 2)) - have_annul_false = 1; - } - - delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc)); - delay->def = def; - delay->num = ++num_delays; - delay->next = delays; - delays = delay; -} - -/* Process a DEFINE_FUNCTION_UNIT. - - This gives information about a function unit contained in the CPU. - We fill in a `struct function_unit_op' and a `struct function_unit' - with information used later by `expand_unit'. */ - -static void -gen_unit (def) - rtx def; -{ - struct function_unit *unit; - struct function_unit_op *op; - char *name = XSTR (def, 0); - int multiplicity = XINT (def, 1); - int simultaneity = XINT (def, 2); - rtx condexp = XEXP (def, 3); - int ready_cost = MAX (XINT (def, 4), 1); - int issue_delay = MAX (XINT (def, 5), 1); - - /* See if we have already seen this function unit. If so, check that - the multiplicity and simultaneity values are the same. If not, make - a structure for this function unit. */ - for (unit = units; unit; unit = unit->next) - if (! strcmp (unit->name, name)) - { - if (unit->multiplicity != multiplicity - || unit->simultaneity != simultaneity) - fatal ("Differing specifications given for `%s' function unit.", - unit->name); - break; - } - - if (unit == 0) - { - unit = (struct function_unit *) oballoc (sizeof (struct function_unit)); - unit->name = name; - unit->multiplicity = multiplicity; - unit->simultaneity = simultaneity; - unit->issue_delay.min = unit->issue_delay.max = issue_delay; - unit->num = num_units++; - unit->num_opclasses = 0; - unit->condexp = false_rtx; - unit->ops = 0; - unit->next = units; - units = unit; - } - - /* Make a new operation class structure entry and initialize it. */ - op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op)); - op->condexp = condexp; - op->num = unit->num_opclasses++; - op->ready = ready_cost; - op->issue_delay = issue_delay; - op->next = unit->ops; - unit->ops = op; - - /* Set our issue expression based on whether or not an optional conflict - vector was specified. */ - if (XVEC (def, 6)) - { - /* Compute the IOR of all the specified expressions. */ - rtx orexp = false_rtx; - int i; - - for (i = 0; i < XVECLEN (def, 6); i++) - orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2); - - op->conflict_exp = orexp; - extend_range (&unit->issue_delay, 1, issue_delay); - } - else - { - op->conflict_exp = true_rtx; - extend_range (&unit->issue_delay, issue_delay, issue_delay); - } - - /* Merge our conditional into that of the function unit so we can determine - which insns are used by the function unit. */ - unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2); -} - -/* Given a piece of RTX, print a C expression to test it's truth value. - We use AND and IOR both for logical and bit-wise operations, so - interpret them as logical unless they are inside a comparison expression. - The second operand of this function will be non-zero in that case. */ - -static void -write_test_expr (exp, in_comparison) - rtx exp; - int in_comparison; -{ - int comparison_operator = 0; - RTX_CODE code; - struct attr_desc *attr; - - /* In order not to worry about operator precedence, surround our part of - the expression with parentheses. */ - - printf ("("); - code = GET_CODE (exp); - switch (code) - { - /* Binary operators. */ - case EQ: case NE: - case GE: case GT: case GEU: case GTU: - case LE: case LT: case LEU: case LTU: - comparison_operator = 1; - - case PLUS: case MINUS: case MULT: case DIV: case MOD: - case AND: case IOR: case XOR: - case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT: - write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator); - switch (code) - { - case EQ: - printf (" == "); - break; - case NE: - printf (" != "); - break; - case GE: - printf (" >= "); - break; - case GT: - printf (" > "); - break; - case GEU: - printf (" >= (unsigned) "); - break; - case GTU: - printf (" > (unsigned) "); - break; - case LE: - printf (" <= "); - break; - case LT: - printf (" < "); - break; - case LEU: - printf (" <= (unsigned) "); - break; - case LTU: - printf (" < (unsigned) "); - break; - case PLUS: - printf (" + "); - break; - case MINUS: - printf (" - "); - break; - case MULT: - printf (" * "); - break; - case DIV: - printf (" / "); - break; - case MOD: - printf (" %% "); - break; - case AND: - if (in_comparison) - printf (" & "); - else - printf (" && "); - break; - case IOR: - if (in_comparison) - printf (" | "); - else - printf (" || "); - break; - case XOR: - printf (" ^ "); - break; - case LSHIFT: - case ASHIFT: - printf (" << "); - break; - case LSHIFTRT: - case ASHIFTRT: - printf (" >> "); - break; - } - - write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator); - break; - - case NOT: - /* Special-case (not (eq_attrq "alternative" "x")) */ - if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR - && XSTR (XEXP (exp, 0), 0) == alternative_name) - { - printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1)); - break; - } - - /* Otherwise, fall through to normal unary operator. */ - - /* Unary operators. */ - case ABS: case NEG: - switch (code) - { - case NOT: - if (in_comparison) - printf ("~ "); - else - printf ("! "); - break; - case ABS: - printf ("abs "); - break; - case NEG: - printf ("-"); - break; - } - - write_test_expr (XEXP (exp, 0), in_comparison); - break; - - /* Comparison test of an attribute with a value. Most of these will - have been removed by optimization. Handle "alternative" - specially and give error if EQ_ATTR present inside a comparison. */ - case EQ_ATTR: - if (in_comparison) - fatal ("EQ_ATTR not valid inside comparison"); - - if (XSTR (exp, 0) == alternative_name) - { - printf ("which_alternative == %s", XSTR (exp, 1)); - break; - } - - attr = find_attr (XSTR (exp, 0), 0); - if (! attr) abort (); - - /* Now is the time to expand the value of a constant attribute. */ - if (attr->is_const) - { - write_test_expr (evaluate_eq_attr (exp, attr->default_val->value, - -2, -2), - in_comparison); - } - else - { - printf ("get_attr_%s (insn) == ", attr->name); - write_attr_valueq (attr, XSTR (exp, 1)); - } - break; - - /* Comparison test of flags for define_delays. */ - case ATTR_FLAG: - if (in_comparison) - fatal ("ATTR_FLAG not valid inside comparison"); - printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0)); - break; - - /* See if an operand matches a predicate. */ - case MATCH_OPERAND: - /* If only a mode is given, just ensure the mode matches the operand. - If neither a mode nor predicate is given, error. */ - if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0') - { - if (GET_MODE (exp) == VOIDmode) - fatal ("Null MATCH_OPERAND specified as test"); - else - printf ("GET_MODE (operands[%d]) == %smode", - XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); - } - else - printf ("%s (operands[%d], %smode)", - XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); - break; - - /* Constant integer. */ - case CONST_INT: -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - printf ("%d", XWINT (exp, 0)); -#else - printf ("%ld", XWINT (exp, 0)); -#endif - break; - - /* A random C expression. */ - case SYMBOL_REF: - printf ("%s", XSTR (exp, 0)); - break; - - /* The address of the branch target. */ - case MATCH_DUP: - printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]"); - break; - - /* The address of the current insn. It would be more consistent with - other usage to make this the address of the NEXT insn, but this gets - too confusing because of the ambiguity regarding the length of the - current insn. */ - case PC: - printf ("insn_current_address"); - break; - - default: - fatal ("bad RTX code `%s' in attribute calculation\n", - GET_RTX_NAME (code)); - } - - printf (")"); -} - -/* Given an attribute value, return the maximum CONST_STRING argument - encountered. It is assumed that they are all numeric. */ - -static int -max_attr_value (exp) - rtx exp; -{ - int current_max = 0; - int n; - int i; - - if (GET_CODE (exp) == CONST_STRING) - return atoi (XSTR (exp, 0)); - - else if (GET_CODE (exp) == COND) - { - for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - n = max_attr_value (XVECEXP (exp, 0, i + 1)); - if (n > current_max) - current_max = n; - } - - n = max_attr_value (XEXP (exp, 1)); - if (n > current_max) - current_max = n; - } - - else if (GET_CODE (exp) == IF_THEN_ELSE) - { - current_max = max_attr_value (XEXP (exp, 1)); - n = max_attr_value (XEXP (exp, 2)); - if (n > current_max) - current_max = n; - } - - else - abort (); - - return current_max; -} - -/* Scan an attribute value, possibly a conditional, and record what actions - will be required to do any conditional tests in it. - - Specifically, set - `must_extract' if we need to extract the insn operands - `must_constrain' if we must compute `which_alternative' - `address_used' if an address expression was used - `length_used' if an (eq_attr "length" ...) was used - */ - -static void -walk_attr_value (exp) - rtx exp; -{ - register int i, j; - register char *fmt; - RTX_CODE code; - - if (exp == NULL) - return; - - code = GET_CODE (exp); - switch (code) - { - case SYMBOL_REF: - if (! RTX_UNCHANGING_P (exp)) - /* Since this is an arbitrary expression, it can look at anything. - However, constant expressions do not depend on any particular - insn. */ - must_extract = must_constrain = 1; - return; - - case MATCH_OPERAND: - must_extract = 1; - return; - - case EQ_ATTR: - if (XSTR (exp, 0) == alternative_name) - must_extract = must_constrain = 1; - else if (strcmp (XSTR (exp, 0), "length") == 0) - length_used = 1; - return; - - case MATCH_DUP: - case PC: - address_used = 1; - return; - - case ATTR_FLAG: - return; - } - - for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++) - switch (*fmt++) - { - case 'e': - case 'u': - walk_attr_value (XEXP (exp, i)); - break; - - case 'E': - if (XVEC (exp, i) != NULL) - for (j = 0; j < XVECLEN (exp, i); j++) - walk_attr_value (XVECEXP (exp, i, j)); - break; - } -} - -/* Write out a function to obtain the attribute for a given INSN. */ - -static void -write_attr_get (attr) - struct attr_desc *attr; -{ - struct attr_value *av, *common_av; - - /* Find the most used attribute value. Handle that as the `default' of the - switch we will generate. */ - common_av = find_most_used (attr); - - /* Write out start of function, then all values with explicit `case' lines, - then a `default', then the value with the most uses. */ - if (!attr->is_numeric) - printf ("enum attr_%s\n", attr->name); - else if (attr->unsigned_p) - printf ("unsigned int\n"); - else - printf ("int\n"); - - /* If the attribute name starts with a star, the remainder is the name of - the subroutine to use, instead of `get_attr_...'. */ - if (attr->name[0] == '*') - printf ("%s (insn)\n", &attr->name[1]); - else if (attr->is_const == 0) - printf ("get_attr_%s (insn)\n", attr->name); - else - { - printf ("get_attr_%s ()\n", attr->name); - printf ("{\n"); - - for (av = attr->first_value; av; av = av->next) - if (av->num_insns != 0) - write_attr_set (attr, 2, av->value, "return", ";", - true_rtx, av->first_insn->insn_code, - av->first_insn->insn_index); - - printf ("}\n\n"); - return; - } - printf (" rtx insn;\n"); - printf ("{\n"); - printf (" switch (recog_memoized (insn))\n"); - printf (" {\n"); - - for (av = attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); - - write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); - printf (" }\n}\n\n"); -} - -/* Given an AND tree of known true terms (because we are inside an `if' with - that as the condition or are in an `else' clause) and an expression, - replace any known true terms with TRUE. Use `simplify_and_tree' to do - the bulk of the work. */ - -static rtx -eliminate_known_true (known_true, exp, insn_code, insn_index) - rtx known_true; - rtx exp; - int insn_code, insn_index; -{ - rtx term; - - known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index); - - if (GET_CODE (known_true) == AND) - { - exp = eliminate_known_true (XEXP (known_true, 0), exp, - insn_code, insn_index); - exp = eliminate_known_true (XEXP (known_true, 1), exp, - insn_code, insn_index); - } - else - { - term = known_true; - exp = simplify_and_tree (exp, &term, insn_code, insn_index); - } - - return exp; -} - -/* Write out a series of tests and assignment statements to perform tests and - sets of an attribute value. We are passed an indentation amount and prefix - and suffix strings to write around each attribute value (e.g., "return" - and ";"). */ - -static void -write_attr_set (attr, indent, value, prefix, suffix, known_true, - insn_code, insn_index) - struct attr_desc *attr; - int indent; - rtx value; - char *prefix; - char *suffix; - rtx known_true; - int insn_code, insn_index; -{ - if (GET_CODE (value) == CONST_STRING) - { - write_indent (indent); - printf ("%s ", prefix); - write_attr_value (attr, value); - printf ("%s\n", suffix); - } - else if (GET_CODE (value) == COND) - { - /* Assume the default value will be the default of the COND unless we - find an always true expression. */ - rtx default_val = XEXP (value, 1); - rtx our_known_true = known_true; - rtx newexp; - int first_if = 1; - int i; - - for (i = 0; i < XVECLEN (value, 0); i += 2) - { - rtx testexp; - rtx inner_true; - - testexp = eliminate_known_true (our_known_true, - XVECEXP (value, 0, i), - insn_code, insn_index); - newexp = attr_rtx (NOT, testexp); - newexp = insert_right_side (AND, our_known_true, newexp, - insn_code, insn_index); - - /* If the test expression is always true or if the next `known_true' - expression is always false, this is the last case, so break - out and let this value be the `else' case. */ - if (testexp == true_rtx || newexp == false_rtx) - { - default_val = XVECEXP (value, 0, i + 1); - break; - } - - /* Compute the expression to pass to our recursive call as being - known true. */ - inner_true = insert_right_side (AND, our_known_true, - testexp, insn_code, insn_index); - - /* If this is always false, skip it. */ - if (inner_true == false_rtx) - continue; - - write_indent (indent); - printf ("%sif ", first_if ? "" : "else "); - first_if = 0; - write_test_expr (testexp, 0); - printf ("\n"); - write_indent (indent + 2); - printf ("{\n"); - - write_attr_set (attr, indent + 4, - XVECEXP (value, 0, i + 1), prefix, suffix, - inner_true, insn_code, insn_index); - write_indent (indent + 2); - printf ("}\n"); - our_known_true = newexp; - } - - if (! first_if) - { - write_indent (indent); - printf ("else\n"); - write_indent (indent + 2); - printf ("{\n"); - } - - write_attr_set (attr, first_if ? indent : indent + 4, default_val, - prefix, suffix, our_known_true, insn_code, insn_index); - - if (! first_if) - { - write_indent (indent + 2); - printf ("}\n"); - } - } - else - abort (); -} - -/* Write out the computation for one attribute value. */ - -static void -write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, - known_true) - struct attr_desc *attr; - struct attr_value *av; - int write_case_lines; - char *prefix, *suffix; - int indent; - rtx known_true; -{ - struct insn_ent *ie; - - if (av->num_insns == 0) - return; - - if (av->has_asm_insn) - { - write_indent (indent); - printf ("case -1:\n"); - write_indent (indent + 2); - printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n"); - write_indent (indent + 2); - printf (" && asm_noperands (PATTERN (insn)) < 0)\n"); - write_indent (indent + 2); - printf (" fatal_insn_not_found (insn);\n"); - } - - if (write_case_lines) - { - for (ie = av->first_insn; ie; ie = ie->next) - if (ie->insn_code != -1) - { - write_indent (indent); - printf ("case %d:\n", ie->insn_code); - } - } - else - { - write_indent (indent); - printf ("default:\n"); - } - - /* See what we have to do to output this value. */ - must_extract = must_constrain = address_used = 0; - walk_attr_value (av->value); - - if (must_extract) - { - write_indent (indent + 2); - printf ("insn_extract (insn);\n"); - } - - if (must_constrain) - { -#ifdef REGISTER_CONSTRAINTS - write_indent (indent + 2); - printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n"); - write_indent (indent + 2); - printf (" fatal_insn_not_found (insn);\n"); -#endif - } - - write_attr_set (attr, indent + 2, av->value, prefix, suffix, - known_true, av->first_insn->insn_code, - av->first_insn->insn_index); - - if (strncmp (prefix, "return", 6)) - { - write_indent (indent + 2); - printf ("break;\n"); - } - printf ("\n"); -} - -/* Utilities to write names in various forms. */ - -static void -write_attr_valueq (attr, s) - struct attr_desc *attr; - char *s; -{ - if (attr->is_numeric) - { - printf ("%s", s); - /* Make the blockage range values easier to read. */ - if (strlen (s) > 1) - printf (" /* 0x%x */", atoi (s)); - } - else - { - write_upcase (attr->name); - printf ("_"); - write_upcase (s); - } -} - -static void -write_attr_value (attr, value) - struct attr_desc *attr; - rtx value; -{ - if (GET_CODE (value) != CONST_STRING) - abort (); - - write_attr_valueq (attr, XSTR (value, 0)); -} - -static void -write_upcase (str) - char *str; -{ - while (*str) - if (*str < 'a' || *str > 'z') - printf ("%c", *str++); - else - printf ("%c", *str++ - 'a' + 'A'); -} - -static void -write_indent (indent) - int indent; -{ - for (; indent > 8; indent -= 8) - printf ("\t"); - - for (; indent; indent--) - printf (" "); -} - -/* Write a subroutine that is given an insn that requires a delay slot, a - delay slot ordinal, and a candidate insn. It returns non-zero if the - candidate can be placed in the specified delay slot of the insn. - - We can write as many as three subroutines. `eligible_for_delay' - handles normal delay slots, `eligible_for_annul_true' indicates that - the specified insn can be annulled if the branch is true, and likewise - for `eligible_for_annul_false'. - - KIND is a string distinguishing these three cases ("delay", "annul_true", - or "annul_false"). */ - -static void -write_eligible_delay (kind) - char *kind; -{ - struct delay_desc *delay; - int max_slots; - char str[50]; - struct attr_desc *attr; - struct attr_value *av, *common_av; - int i; - - /* Compute the maximum number of delay slots required. We use the delay - ordinal times this number plus one, plus the slot number as an index into - the appropriate predicate to test. */ - - for (delay = delays, max_slots = 0; delay; delay = delay->next) - if (XVECLEN (delay->def, 1) / 3 > max_slots) - max_slots = XVECLEN (delay->def, 1) / 3; - - /* Write function prelude. */ - - printf ("int\n"); - printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n", - kind); - printf (" rtx delay_insn;\n"); - printf (" int slot;\n"); - printf (" rtx candidate_insn;\n"); - printf (" int flags;\n"); - printf ("{\n"); - printf (" rtx insn;\n"); - printf ("\n"); - printf (" if (slot >= %d)\n", max_slots); - printf (" abort ();\n"); - printf ("\n"); - - /* If more than one delay type, find out which type the delay insn is. */ - - if (num_delays > 1) - { - attr = find_attr ("*delay_type", 0); - if (! attr) abort (); - common_av = find_most_used (attr); - - printf (" insn = delay_insn;\n"); - printf (" switch (recog_memoized (insn))\n"); - printf (" {\n"); - - sprintf (str, " * %d;\n break;", max_slots); - for (av = attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx); - - write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx); - printf (" }\n\n"); - - /* Ensure matched. Otherwise, shouldn't have been called. */ - printf (" if (slot < %d)\n", max_slots); - printf (" abort ();\n\n"); - } - - /* If just one type of delay slot, write simple switch. */ - if (num_delays == 1 && max_slots == 1) - { - printf (" insn = candidate_insn;\n"); - printf (" switch (recog_memoized (insn))\n"); - printf (" {\n"); - - attr = find_attr ("*delay_1_0", 0); - if (! attr) abort (); - common_av = find_most_used (attr); - - for (av = attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); - - write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); - printf (" }\n"); - } - - else - { - /* Write a nested CASE. The first indicates which condition we need to - test, and the inner CASE tests the condition. */ - printf (" insn = candidate_insn;\n"); - printf (" switch (slot)\n"); - printf (" {\n"); - - for (delay = delays; delay; delay = delay->next) - for (i = 0; i < XVECLEN (delay->def, 1); i += 3) - { - printf (" case %d:\n", - (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots)); - printf (" switch (recog_memoized (insn))\n"); - printf ("\t{\n"); - - sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3); - attr = find_attr (str, 0); - if (! attr) abort (); - common_av = find_most_used (attr); - - for (av = attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (attr, av, 1, "return", ";", 8, true_rtx); - - write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx); - printf (" }\n"); - } - - printf (" default:\n"); - printf (" abort ();\n"); - printf (" }\n"); - } - - printf ("}\n\n"); -} - -/* Write routines to compute conflict cost for function units. Then write a - table describing the available function units. */ - -static void -write_function_unit_info () -{ - struct function_unit *unit; - int i; - - /* Write out conflict routines for function units. Don't bother writing - one if there is only one issue delay value. */ - - for (unit = units; unit; unit = unit->next) - { - if (unit->needs_blockage_function) - write_complex_function (unit, "blockage", "block"); - - /* If the minimum and maximum conflict costs are the same, there - is only one value, so we don't need a function. */ - if (! unit->needs_conflict_function) - { - unit->default_cost = make_numeric_value (unit->issue_delay.max); - continue; - } - - /* The function first computes the case from the candidate insn. */ - unit->default_cost = make_numeric_value (0); - write_complex_function (unit, "conflict_cost", "cost"); - } - - /* Now that all functions have been written, write the table describing - the function units. The name is included for documentation purposes - only. */ - - printf ("struct function_unit_desc function_units[] = {\n"); - - /* Write out the descriptions in numeric order, but don't force that order - on the list. Doing so increases the runtime of genattrtab.c. */ - for (i = 0; i < num_units; i++) - { - for (unit = units; unit; unit = unit->next) - if (unit->num == i) - break; - - printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ", - unit->name, 1 << unit->num, unit->multiplicity, - unit->simultaneity, XSTR (unit->default_cost, 0), - unit->issue_delay.max, unit->name); - - if (unit->needs_conflict_function) - printf ("%s_unit_conflict_cost, ", unit->name); - else - printf ("0, "); - - printf ("%d, ", unit->max_blockage); - - if (unit->needs_range_function) - printf ("%s_unit_blockage_range, ", unit->name); - else - printf ("0, "); - - if (unit->needs_blockage_function) - printf ("%s_unit_blockage", unit->name); - else - printf ("0"); - - printf ("}, \n"); - } - - printf ("};\n\n"); -} - -static void -write_complex_function (unit, name, connection) - struct function_unit *unit; - char *name, *connection; -{ - struct attr_desc *case_attr, *attr; - struct attr_value *av, *common_av; - rtx value; - char *str; - int using_case; - int i; - - printf ("static int\n"); - printf ("%s_unit_%s (executing_insn, candidate_insn)\n", - unit->name, name); - printf (" rtx executing_insn;\n"); - printf (" rtx candidate_insn;\n"); - printf ("{\n"); - printf (" rtx insn;\n"); - printf (" int casenum;\n\n"); - printf (" insn = candidate_insn;\n"); - printf (" switch (recog_memoized (insn))\n"); - printf (" {\n"); - - /* Write the `switch' statement to get the case value. */ - str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10); - sprintf (str, "*%s_cases", unit->name); - case_attr = find_attr (str, 0); - if (! case_attr) abort (); - common_av = find_most_used (case_attr); - - for (av = case_attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (case_attr, av, 1, - "casenum =", ";", 4, unit->condexp); - - write_attr_case (case_attr, common_av, 0, - "casenum =", ";", 4, unit->condexp); - printf (" }\n\n"); - - /* Now write an outer switch statement on each case. Then write - the tests on the executing function within each. */ - printf (" insn = executing_insn;\n"); - printf (" switch (casenum)\n"); - printf (" {\n"); - - for (i = 0; i < unit->num_opclasses; i++) - { - /* Ensure using this case. */ - using_case = 0; - for (av = case_attr->first_value; av; av = av->next) - if (av->num_insns - && contained_in_p (make_numeric_value (i), av->value)) - using_case = 1; - - if (! using_case) - continue; - - printf (" case %d:\n", i); - sprintf (str, "*%s_%s_%d", unit->name, connection, i); - attr = find_attr (str, 0); - if (! attr) abort (); - - /* If single value, just write it. */ - value = find_single_value (attr); - if (value) - write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2); - else - { - common_av = find_most_used (attr); - printf (" switch (recog_memoized (insn))\n"); - printf ("\t{\n"); - - for (av = attr->first_value; av; av = av->next) - if (av != common_av) - write_attr_case (attr, av, 1, - "return", ";", 8, unit->condexp); - - write_attr_case (attr, common_av, 0, - "return", ";", 8, unit->condexp); - printf (" }\n\n"); - } - } - - printf (" }\n}\n\n"); -} - -/* This page contains miscellaneous utility routines. */ - -/* Given a string, return the number of comma-separated elements in it. - Return 0 for the null string. */ - -static int -n_comma_elts (s) - char *s; -{ - int n; - - if (*s == '\0') - return 0; - - for (n = 1; *s; s++) - if (*s == ',') - n++; - - return n; -} - -/* Given a pointer to a (char *), return a malloc'ed string containing the - next comma-separated element. Advance the pointer to after the string - scanned, or the end-of-string. Return NULL if at end of string. */ - -static char * -next_comma_elt (pstr) - char **pstr; -{ - char *out_str; - char *p; - - if (**pstr == '\0') - return NULL; - - /* Find end of string to compute length. */ - for (p = *pstr; *p != ',' && *p != '\0'; p++) - ; - - out_str = attr_string (*pstr, p - *pstr); - *pstr = p; - - if (**pstr == ',') - (*pstr)++; - - return out_str; -} - -/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE - is non-zero, build a new attribute, if one does not exist. */ - -static struct attr_desc * -find_attr (name, create) - char *name; - int create; -{ - struct attr_desc *attr; - int index; - - /* Before we resort to using `strcmp', see if the string address matches - anywhere. In most cases, it should have been canonicalized to do so. */ - if (name == alternative_name) - return NULL; - - index = name[0] & (MAX_ATTRS_INDEX - 1); - for (attr = attrs[index]; attr; attr = attr->next) - if (name == attr->name) - return attr; - - /* Otherwise, do it the slow way. */ - for (attr = attrs[index]; attr; attr = attr->next) - if (name[0] == attr->name[0] && ! strcmp (name, attr->name)) - return attr; - - if (! create) - return NULL; - - attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc)); - attr->name = attr_string (name, strlen (name)); - attr->first_value = attr->default_val = NULL; - attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0; - attr->next = attrs[index]; - attrs[index] = attr; - - return attr; -} - -/* Create internal attribute with the given default value. */ - -static void -make_internal_attr (name, value, special) - char *name; - rtx value; - int special; -{ - struct attr_desc *attr; - - attr = find_attr (name, 1); - if (attr->default_val) - abort (); - - attr->is_numeric = 1; - attr->is_const = 0; - attr->is_special = (special & 1) != 0; - attr->negative_ok = (special & 2) != 0; - attr->unsigned_p = (special & 4) != 0; - attr->default_val = get_attr_value (value, attr, -2); -} - -/* Find the most used value of an attribute. */ - -static struct attr_value * -find_most_used (attr) - struct attr_desc *attr; -{ - struct attr_value *av; - struct attr_value *most_used; - int nuses; - - most_used = NULL; - nuses = -1; - - for (av = attr->first_value; av; av = av->next) - if (av->num_insns > nuses) - nuses = av->num_insns, most_used = av; - - return most_used; -} - -/* If an attribute only has a single value used, return it. Otherwise - return NULL. */ - -static rtx -find_single_value (attr) - struct attr_desc *attr; -{ - struct attr_value *av; - rtx unique_value; - - unique_value = NULL; - for (av = attr->first_value; av; av = av->next) - if (av->num_insns) - { - if (unique_value) - return NULL; - else - unique_value = av->value; - } - - return unique_value; -} - -/* Return (attr_value "n") */ - -static rtx -make_numeric_value (n) - int n; -{ - static rtx int_values[20]; - rtx exp; - char *p; - - if (n < 0) - abort (); - - if (n < 20 && int_values[n]) - return int_values[n]; - - p = attr_printf (MAX_DIGITS, "%d", n); - exp = attr_rtx (CONST_STRING, p); - - if (n < 20) - int_values[n] = exp; - - return exp; -} - -static void -extend_range (range, min, max) - struct range *range; - int min; - int max; -{ - if (range->min > min) range->min = min; - if (range->max < max) range->max = max; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -static rtx -copy_rtx_unchanging (orig) - register rtx orig; -{ -#if 0 - register rtx copy; - register RTX_CODE code; -#endif - - if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig)) - return orig; - - MEM_IN_STRUCT_P (orig) = 1; - return orig; - -#if 0 - code = GET_CODE (orig); - switch (code) - { - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case CODE_LABEL: - return orig; - } - - copy = rtx_alloc (code); - PUT_MODE (copy, GET_MODE (orig)); - RTX_UNCHANGING_P (copy) = 1; - - bcopy (&XEXP (orig, 0), &XEXP (copy, 0), - GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx)); - return copy; -#endif -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genattrtab: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -/* Determine if an insn has a constant number of delay slots, i.e., the - number of delay slots is not a function of the length of the insn. */ - -void -write_const_num_delay_slots () -{ - struct attr_desc *attr = find_attr ("*num_delay_slots", 0); - struct attr_value *av; - struct insn_ent *ie; - int i; - - if (attr) - { - printf ("int\nconst_num_delay_slots (insn)\n"); - printf (" rtx insn;\n"); - printf ("{\n"); - printf (" switch (recog_memoized (insn))\n"); - printf (" {\n"); - - for (av = attr->first_value; av; av = av->next) - { - length_used = 0; - walk_attr_value (av->value); - if (length_used) - { - for (ie = av->first_insn; ie; ie = ie->next) - if (ie->insn_code != -1) - printf (" case %d:\n", ie->insn_code); - printf (" return 0;\n"); - } - } - - printf (" default:\n"); - printf (" return 1;\n"); - printf (" }\n}\n"); - } -} - - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - struct attr_desc *attr; - struct insn_def *id; - rtx tem; - int i; - -#ifdef RLIMIT_STACK - /* Get rid of any avoidable limit on stack size. */ - { - struct rlimit rlim; - - /* Set the stack limit huge so that alloca does not fail. */ - getrlimit (RLIMIT_STACK, &rlim); - rlim.rlim_cur = rlim.rlim_max; - setrlimit (RLIMIT_STACK, &rlim); - } -#endif /* RLIMIT_STACK defined */ - - obstack_init (rtl_obstack); - obstack_init (hash_obstack); - obstack_init (temp_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - /* Set up true and false rtx's */ - true_rtx = rtx_alloc (CONST_INT); - XWINT (true_rtx, 0) = 1; - false_rtx = rtx_alloc (CONST_INT); - XWINT (false_rtx, 0) = 0; - RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1; - RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1; - - alternative_name = attr_string ("alternative", strlen ("alternative")); - - printf ("/* Generated automatically by the program `genattrtab'\n\ -from the machine description file `md'. */\n\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN - || GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES) - gen_insn (desc); - - else if (GET_CODE (desc) == DEFINE_EXPAND) - insn_code_number++, insn_index_number++; - - else if (GET_CODE (desc) == DEFINE_SPLIT) - insn_code_number++, insn_index_number++; - - else if (GET_CODE (desc) == DEFINE_ATTR) - { - gen_attr (desc); - insn_index_number++; - } - - else if (GET_CODE (desc) == DEFINE_DELAY) - { - gen_delay (desc); - insn_index_number++; - } - - else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT) - { - gen_unit (desc); - insn_index_number++; - } - } - - /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */ - if (! got_define_asm_attributes) - { - tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES); - XVEC (tem, 0) = rtvec_alloc (0); - gen_insn (tem); - } - - /* Expand DEFINE_DELAY information into new attribute. */ - if (num_delays) - expand_delays (); - - /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */ - if (num_units) - expand_units (); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"insn-config.h\"\n"); - printf ("#include \"recog.h\"\n"); - printf ("#include \"regs.h\"\n"); - printf ("#include \"real.h\"\n"); - printf ("#include \"output.h\"\n"); - printf ("#include \"insn-attr.h\"\n"); - printf ("\n"); - printf ("#define operands recog_operand\n\n"); - - /* Make `insn_alternatives'. */ - insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int)); - for (id = defs; id; id = id->next) - if (id->insn_code >= 0) - insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1; - - /* Make `insn_n_alternatives'. */ - insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int)); - for (id = defs; id; id = id->next) - if (id->insn_code >= 0) - insn_n_alternatives[id->insn_code] = id->num_alternatives; - - /* Prepare to write out attribute subroutines by checking everything stored - away and building the attribute cases. */ - - check_defs (); - for (i = 0; i < MAX_ATTRS_INDEX; i++) - for (attr = attrs[i]; attr; attr = attr->next) - { - attr->default_val->value - = check_attr_value (attr->default_val->value, attr); - fill_attr (attr); - } - - /* Construct extra attributes for `length'. */ - make_length_attrs (); - - /* Perform any possible optimizations to speed up compilation. */ - optimize_attrs (); - - /* Now write out all the `gen_attr_...' routines. Do these before the - special routines (specifically before write_function_unit_info), so - that they get defined before they are used. */ - - for (i = 0; i < MAX_ATTRS_INDEX; i++) - for (attr = attrs[i]; attr; attr = attr->next) - { - if (! attr->is_special) - write_attr_get (attr); - } - - /* Write out delay eligibility information, if DEFINE_DELAY present. - (The function to compute the number of delay slots will be written - below.) */ - if (num_delays) - { - write_eligible_delay ("delay"); - if (have_annul_true) - write_eligible_delay ("annul_true"); - if (have_annul_false) - write_eligible_delay ("annul_false"); - } - - /* Write out information about function units. */ - if (num_units) - write_function_unit_info (); - - /* Write out constant delay slot info */ - write_const_num_delay_slots (); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/gencodes.c b/gnu/usr.bin/gcc2/arch/gencodes.c deleted file mode 100644 index d6fe68b65fb..00000000000 --- a/gnu/usr.bin/gcc2/arch/gencodes.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Generate from machine description: - - - some macros CODE_FOR_... giving the insn_code_number value - for each of the defined standard insn names. - Copyright (C) 1987, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: gencodes.c,v 1.1.1.1 1995/10/18 08:39:15 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -char *xmalloc (); -static void fatal (); -void fancy_abort (); - -static int insn_code_number; - -static void -gen_insn (insn) - rtx insn; -{ - /* Don't mention instructions whose names are the null string. - They are in the machine description just to be recognized. */ - if (strlen (XSTR (insn, 0)) != 0) - printf (" CODE_FOR_%s = %d,\n", XSTR (insn, 0), - insn_code_number); -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "gencodes: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - printf ("/* Generated automatically by the program `gencodes'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#ifndef MAX_INSN_CODE\n\n"); - - /* Read the machine description. */ - - insn_code_number = 0; - printf ("enum insn_code {\n"); - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) - { - gen_insn (desc); - insn_code_number++; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_SPLIT) - { - insn_code_number++; - } - } - - printf (" CODE_FOR_nothing };\n"); - - printf ("\n#define MAX_INSN_CODE ((int) CODE_FOR_nothing)\n"); - - printf ("#endif /* MAX_INSN_CODE */\n"); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genconfig.c b/gnu/usr.bin/gcc2/arch/genconfig.c deleted file mode 100644 index 59f1609234a..00000000000 --- a/gnu/usr.bin/gcc2/arch/genconfig.c +++ /dev/null @@ -1,358 +0,0 @@ -/* Generate from machine description: - - - some #define configuration flags. - Copyright (C) 1987, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genconfig.c,v 1.1.1.1 1995/10/18 08:39:15 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -/* flags to determine output of machine description dependent #define's. */ -static int max_recog_operands; /* Largest operand number seen. */ -static int max_dup_operands; /* Largest number of match_dup in any insn. */ -static int max_clobbers_per_insn; -static int register_constraint_flag; -static int have_cc0_flag; -static int have_cmove_flag; -static int have_lo_sum_flag; - -/* Maximum number of insns seen in a split. */ -static int max_insns_per_split = 1; - -static int clobbers_seen_this_insn; -static int dup_operands_seen_this_insn; - -char *xmalloc (); -static void fatal (); -void fancy_abort (); - -/* RECOG_P will be non-zero if this pattern was seen in a context where it will - be used to recognize, rather than just generate an insn. - - NON_PC_SET_SRC will be non-zero if this pattern was seen in a SET_SRC - of a SET whose destination is not (pc). */ - -static void -walk_insn_part (part, recog_p, non_pc_set_src) - rtx part; - int recog_p; - int non_pc_set_src; -{ - register int i, j; - register RTX_CODE code; - register char *format_ptr; - - if (part == 0) - return; - - code = GET_CODE (part); - switch (code) - { - case CLOBBER: - clobbers_seen_this_insn++; - break; - - case MATCH_OPERAND: - if (XINT (part, 0) > max_recog_operands) - max_recog_operands = XINT (part, 0); - if (XSTR (part, 2) && *XSTR (part, 2)) - register_constraint_flag = 1; - return; - - case MATCH_OP_DUP: - case MATCH_PAR_DUP: - ++dup_operands_seen_this_insn; - case MATCH_SCRATCH: - case MATCH_PARALLEL: - case MATCH_OPERATOR: - if (XINT (part, 0) > max_recog_operands) - max_recog_operands = XINT (part, 0); - /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or - MATCH_PARALLEL. */ - break; - - case LABEL_REF: - if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND) - break; - return; - - case MATCH_DUP: - ++dup_operands_seen_this_insn; - if (XINT (part, 0) > max_recog_operands) - max_recog_operands = XINT (part, 0); - return; - - case CC0: - if (recog_p) - have_cc0_flag = 1; - return; - - case LO_SUM: - if (recog_p) - have_lo_sum_flag = 1; - return; - - case SET: - walk_insn_part (SET_DEST (part), 0, recog_p); - walk_insn_part (SET_SRC (part), recog_p, - GET_CODE (SET_DEST (part)) != PC); - return; - - case IF_THEN_ELSE: - /* Only consider this machine as having a conditional move if the - two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, - we have some specific IF_THEN_ELSE construct (like the doz - instruction on the RS/6000) that can't be used in the general - context we want it for. */ - - if (recog_p && non_pc_set_src - && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND - && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) - have_cmove_flag = 1; - break; - - case REG: case CONST_INT: case SYMBOL_REF: - case PC: - return; - } - - format_ptr = GET_RTX_FORMAT (GET_CODE (part)); - - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) - switch (*format_ptr++) - { - case 'e': - case 'u': - walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); - break; - case 'E': - if (XVEC (part, i) != NULL) - for (j = 0; j < XVECLEN (part, i); j++) - walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); - break; - } -} - -static void -gen_insn (insn) - rtx insn; -{ - int i; - - /* Walk the insn pattern to gather the #define's status. */ - clobbers_seen_this_insn = 0; - dup_operands_seen_this_insn = 0; - if (XVEC (insn, 1) != 0) - for (i = 0; i < XVECLEN (insn, 1); i++) - walk_insn_part (XVECEXP (insn, 1, i), 1, 0); - - if (clobbers_seen_this_insn > max_clobbers_per_insn) - max_clobbers_per_insn = clobbers_seen_this_insn; - if (dup_operands_seen_this_insn > max_dup_operands) - max_dup_operands = dup_operands_seen_this_insn; -} - -/* Similar but scan a define_expand. */ - -static void -gen_expand (insn) - rtx insn; -{ - int i; - - /* Walk the insn pattern to gather the #define's status. */ - - /* Note that we don't bother recording the number of MATCH_DUPs - that occur in a gen_expand, because only reload cares about that. */ - if (XVEC (insn, 1) != 0) - for (i = 0; i < XVECLEN (insn, 1); i++) - { - /* Compute the maximum SETs and CLOBBERS - in any one of the sub-insns; - don't sum across all of them. */ - clobbers_seen_this_insn = 0; - - walk_insn_part (XVECEXP (insn, 1, i), 0, 0); - - if (clobbers_seen_this_insn > max_clobbers_per_insn) - max_clobbers_per_insn = clobbers_seen_this_insn; - } -} - -/* Similar but scan a define_split. */ - -static void -gen_split (split) - rtx split; -{ - int i; - - /* Look through the patterns that are matched - to compute the maximum operand number. */ - for (i = 0; i < XVECLEN (split, 0); i++) - walk_insn_part (XVECEXP (split, 0, i), 1, 0); - /* Look at the number of insns this insn could split into. */ - if (XVECLEN (split, 2) > max_insns_per_split) - max_insns_per_split = XVECLEN (split, 2); -} - -static void -gen_peephole (peep) - rtx peep; -{ - int i; - - /* Look through the patterns that are matched - to compute the maximum operand number. */ - for (i = 0; i < XVECLEN (peep, 0); i++) - walk_insn_part (XVECEXP (peep, 0, i), 1, 0); -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genconfig: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - printf ("/* Generated automatically by the program `genconfig'\n\ -from the machine description file `md'. */\n\n"); - - /* Allow at least 10 operands for the sake of asm constructs. */ - max_recog_operands = 9; /* We will add 1 later. */ - max_dup_operands = 1; - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - gen_insn (desc); - if (GET_CODE (desc) == DEFINE_EXPAND) - gen_expand (desc); - if (GET_CODE (desc) == DEFINE_SPLIT) - gen_split (desc); - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - gen_peephole (desc); - } - - printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1); - - printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands); - - /* This is conditionally defined, in case the user writes code which emits - more splits than we can readily see (and knows s/he does it). */ - printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n", - max_insns_per_split); - - if (register_constraint_flag) - printf ("#define REGISTER_CONSTRAINTS\n"); - - if (have_cc0_flag) - printf ("#define HAVE_cc0\n"); - - if (have_cmove_flag) - printf ("#define HAVE_conditional_move\n"); - - if (have_lo_sum_flag) - printf ("#define HAVE_lo_sum\n"); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genemit.c b/gnu/usr.bin/gcc2/arch/genemit.c deleted file mode 100644 index 341094abaa5..00000000000 --- a/gnu/usr.bin/gcc2/arch/genemit.c +++ /dev/null @@ -1,801 +0,0 @@ -/* Generate code from machine description to emit insns as rtl. - Copyright (C) 1987, 1988, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genemit.c,v 1.1.1.1 1995/10/18 08:39:15 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -char *xmalloc (); -static void fatal (); -void fancy_abort (); - -static int max_opno; -static int max_dup_opno; -static int register_constraints; -static int insn_code_number; -static int insn_index_number; - -/* Data structure for recording the patterns of insns that have CLOBBERs. - We use this to output a function that adds these CLOBBERs to a - previously-allocated PARALLEL expression. */ - -struct clobber_pat -{ - struct clobber_ent *insns; - rtx pattern; - int first_clobber; - struct clobber_pat *next; -} *clobber_list; - -/* Records one insn that uses the clobber list. */ - -struct clobber_ent -{ - int code_number; /* Counts only insns. */ - struct clobber_ent *next; -}; - -static void -max_operand_1 (x) - rtx x; -{ - register RTX_CODE code; - register int i; - register int len; - register char *fmt; - - if (x == 0) - return; - - code = GET_CODE (x); - - if (code == MATCH_OPERAND && XSTR (x, 2) != 0 && *XSTR (x, 2) != '\0') - register_constraints = 1; - if (code == MATCH_SCRATCH && XSTR (x, 1) != 0 && *XSTR (x, 1) != '\0') - register_constraints = 1; - if (code == MATCH_OPERAND || code == MATCH_OPERATOR - || code == MATCH_PARALLEL) - max_opno = MAX (max_opno, XINT (x, 0)); - if (code == MATCH_DUP || code == MATCH_OP_DUP || code == MATCH_PAR_DUP) - max_dup_opno = MAX (max_dup_opno, XINT (x, 0)); - - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - if (fmt[i] == 'e' || fmt[i] == 'u') - max_operand_1 (XEXP (x, i)); - else if (fmt[i] == 'E') - { - int j; - for (j = 0; j < XVECLEN (x, i); j++) - max_operand_1 (XVECEXP (x, i, j)); - } - } -} - -static int -max_operand_vec (insn, arg) - rtx insn; - int arg; -{ - register int len = XVECLEN (insn, arg); - register int i; - - max_opno = -1; - max_dup_opno = -1; - - for (i = 0; i < len; i++) - max_operand_1 (XVECEXP (insn, arg, i)); - - return max_opno + 1; -} - -static void -print_code (code) - RTX_CODE code; -{ - register char *p1; - for (p1 = GET_RTX_NAME (code); *p1; p1++) - { - if (*p1 >= 'a' && *p1 <= 'z') - putchar (*p1 + 'A' - 'a'); - else - putchar (*p1); - } -} - -/* Print a C expression to construct an RTX just like X, - substituting any operand references appearing within. */ - -static void -gen_exp (x) - rtx x; -{ - register RTX_CODE code; - register int i; - register int len; - register char *fmt; - - if (x == 0) - { - printf ("NULL_RTX"); - return; - } - - code = GET_CODE (x); - - switch (code) - { - case MATCH_OPERAND: - case MATCH_DUP: - printf ("operand%d", XINT (x, 0)); - return; - - case MATCH_OP_DUP: - printf ("gen_rtx (GET_CODE (operand%d), GET_MODE (operand%d)", - XINT (x, 0), XINT (x, 0)); - for (i = 0; i < XVECLEN (x, 1); i++) - { - printf (",\n\t\t"); - gen_exp (XVECEXP (x, 1, i)); - } - printf (")"); - return; - - case MATCH_OPERATOR: - printf ("gen_rtx (GET_CODE (operand%d)", XINT (x, 0)); - printf (", %smode", GET_MODE_NAME (GET_MODE (x))); - for (i = 0; i < XVECLEN (x, 2); i++) - { - printf (",\n\t\t"); - gen_exp (XVECEXP (x, 2, i)); - } - printf (")"); - return; - - case MATCH_PARALLEL: - case MATCH_PAR_DUP: - printf ("operand%d", XINT (x, 0)); - return; - - case MATCH_SCRATCH: - printf ("gen_rtx (SCRATCH, %smode, 0)", GET_MODE_NAME (GET_MODE (x))); - return; - - case ADDRESS: - fatal ("ADDRESS expression code used in named instruction pattern"); - - case PC: - printf ("pc_rtx"); - return; - - case CC0: - printf ("cc0_rtx"); - return; - - case CONST_INT: - if (INTVAL (x) == 0) - printf ("const0_rtx"); - else if (INTVAL (x) == 1) - printf ("const1_rtx"); - else if (INTVAL (x) == -1) - printf ("constm1_rtx"); - else if (INTVAL (x) == STORE_FLAG_VALUE) - printf ("const_true_rtx"); - else - printf ( -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - "GEN_INT (%d)", -#else - "GEN_INT (%ld)", -#endif - INTVAL (x)); - return; - - case CONST_DOUBLE: - /* These shouldn't be written in MD files. Instead, the appropriate - routines in varasm.c should be called. */ - abort (); - } - - printf ("gen_rtx ("); - print_code (code); - printf (", %smode", GET_MODE_NAME (GET_MODE (x))); - - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - if (fmt[i] == '0') - break; - printf (", "); - if (fmt[i] == 'e' || fmt[i] == 'u') - gen_exp (XEXP (x, i)); - else if (fmt[i] == 'i') - printf ("%u", XINT (x, i)); - else if (fmt[i] == 's') - printf ("\"%s\"", XSTR (x, i)); - else if (fmt[i] == 'E') - { - int j; - printf ("gen_rtvec (%d", XVECLEN (x, i)); - for (j = 0; j < XVECLEN (x, i); j++) - { - printf (",\n\t\t"); - gen_exp (XVECEXP (x, i, j)); - } - printf (")"); - } - else - abort (); - } - printf (")"); -} - -/* Generate the `gen_...' function for a DEFINE_INSN. */ - -static void -gen_insn (insn) - rtx insn; -{ - int operands; - register int i; - - /* See if the pattern for this insn ends with a group of CLOBBERs of (hard) - registers or MATCH_SCRATCHes. If so, store away the information for - later. */ - - if (XVEC (insn, 1)) - { - for (i = XVECLEN (insn, 1) - 1; i > 0; i--) - if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER - || (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != REG - && GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH)) - break; - - if (i != XVECLEN (insn, 1) - 1) - { - register struct clobber_pat *p; - register struct clobber_ent *link - = (struct clobber_ent *) xmalloc (sizeof (struct clobber_ent)); - register int j; - - link->code_number = insn_code_number; - - /* See if any previous CLOBBER_LIST entry is the same as this - one. */ - - for (p = clobber_list; p; p = p->next) - { - if (p->first_clobber != i + 1 - || XVECLEN (p->pattern, 1) != XVECLEN (insn, 1)) - continue; - - for (j = i + 1; j < XVECLEN (insn, 1); j++) - { - rtx old = XEXP (XVECEXP (p->pattern, 1, j), 0); - rtx new = XEXP (XVECEXP (insn, 1, j), 0); - - /* OLD and NEW are the same if both are to be a SCRATCH - of the same mode, - or if both are registers of the same mode and number. */ - if (! (GET_MODE (old) == GET_MODE (new) - && ((GET_CODE (old) == MATCH_SCRATCH - && GET_CODE (new) == MATCH_SCRATCH) - || (GET_CODE (old) == REG && GET_CODE (new) == REG - && REGNO (old) == REGNO (new))))) - break; - } - - if (j == XVECLEN (insn, 1)) - break; - } - - if (p == 0) - { - p = (struct clobber_pat *) xmalloc (sizeof (struct clobber_pat)); - - p->insns = 0; - p->pattern = insn; - p->first_clobber = i + 1; - p->next = clobber_list; - clobber_list = p; - } - - link->next = p->insns; - p->insns = link; - } - } - - /* Don't mention instructions whose names are the null string. - They are in the machine description just to be recognized. */ - if (strlen (XSTR (insn, 0)) == 0) - return; - - /* Find out how many operands this function has, - and also whether any of them have register constraints. */ - register_constraints = 0; - operands = max_operand_vec (insn, 1); - if (max_dup_opno >= operands) - fatal ("match_dup operand number has no match_operand"); - - /* Output the function name and argument declarations. */ - printf ("rtx\ngen_%s (", XSTR (insn, 0)); - for (i = 0; i < operands; i++) - printf (i ? ", operand%d" : "operand%d", i); - printf (")\n"); - for (i = 0; i < operands; i++) - printf (" rtx operand%d;\n", i); - printf ("{\n"); - - /* Output code to construct and return the rtl for the instruction body */ - - if (XVECLEN (insn, 1) == 1) - { - printf (" return "); - gen_exp (XVECEXP (insn, 1, 0)); - printf (";\n}\n\n"); - } - else - { - printf (" return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1)); - for (i = 0; i < XVECLEN (insn, 1); i++) - { - printf (",\n\t\t"); - gen_exp (XVECEXP (insn, 1, i)); - } - printf ("));\n}\n\n"); - } -} - -/* Generate the `gen_...' function for a DEFINE_EXPAND. */ - -static void -gen_expand (expand) - rtx expand; -{ - int operands; - register int i; - - if (strlen (XSTR (expand, 0)) == 0) - fatal ("define_expand lacks a name"); - if (XVEC (expand, 1) == 0) - fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0)); - - /* Find out how many operands this function has, - and also whether any of them have register constraints. */ - register_constraints = 0; - - operands = max_operand_vec (expand, 1); - - /* Output the function name and argument declarations. */ - printf ("rtx\ngen_%s (", XSTR (expand, 0)); - for (i = 0; i < operands; i++) - printf (i ? ", operand%d" : "operand%d", i); - printf (")\n"); - for (i = 0; i < operands; i++) - printf (" rtx operand%d;\n", i); - printf ("{\n"); - - /* If we don't have any C code to write, only one insn is being written, - and no MATCH_DUPs are present, we can just return the desired insn - like we do for a DEFINE_INSN. This saves memory. */ - if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0') - && operands > max_dup_opno - && XVECLEN (expand, 1) == 1) - { - printf (" return "); - gen_exp (XVECEXP (expand, 1, 0)); - printf (";\n}\n\n"); - return; - } - - /* For each operand referred to only with MATCH_DUPs, - make a local variable. */ - for (i = operands; i <= max_dup_opno; i++) - printf (" rtx operand%d;\n", i); - if (operands > 0 || max_dup_opno >= 0) - printf (" rtx operands[%d];\n", MAX (operands, max_dup_opno + 1)); - printf (" rtx _val = 0;\n"); - printf (" start_sequence ();\n"); - - /* The fourth operand of DEFINE_EXPAND is some code to be executed - before the actual construction. - This code expects to refer to `operands' - just as the output-code in a DEFINE_INSN does, - but here `operands' is an automatic array. - So copy the operand values there before executing it. */ - if (XSTR (expand, 3) && *XSTR (expand, 3)) - { - /* Output code to copy the arguments into `operands'. */ - for (i = 0; i < operands; i++) - printf (" operands[%d] = operand%d;\n", i, i); - - /* Output the special code to be executed before the sequence - is generated. */ - printf ("%s\n", XSTR (expand, 3)); - - /* Output code to copy the arguments back out of `operands' - (unless we aren't going to use them at all). */ - if (XVEC (expand, 1) != 0) - { - for (i = 0; i < operands; i++) - printf (" operand%d = operands[%d];\n", i, i); - for (; i <= max_dup_opno; i++) - printf (" operand%d = operands[%d];\n", i, i); - } - } - - /* Output code to construct the rtl for the instruction bodies. - Use emit_insn to add them to the sequence being accumulated. - But don't do this if the user's code has set `no_more' nonzero. */ - - for (i = 0; i < XVECLEN (expand, 1); i++) - { - rtx next = XVECEXP (expand, 1, i); - if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC) - || GET_CODE (next) == RETURN) - printf (" emit_jump_insn ("); - else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL) - || GET_CODE (next) == CALL - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == CALL)) - printf (" emit_call_insn ("); - else if (GET_CODE (next) == CODE_LABEL) - printf (" emit_label ("); - else if (GET_CODE (next) == MATCH_OPERAND - || GET_CODE (next) == MATCH_OPERATOR - || GET_CODE (next) == MATCH_PARALLEL - || GET_CODE (next) == MATCH_OP_DUP - || GET_CODE (next) == MATCH_DUP - || GET_CODE (next) == PARALLEL) - printf (" emit ("); - else - printf (" emit_insn ("); - gen_exp (next); - printf (");\n"); - if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC - && GET_CODE (SET_SRC (next)) == LABEL_REF) - printf (" emit_barrier ();"); - } - - /* Call `gen_sequence' to make a SEQUENCE out of all the - insns emitted within this gen_... function. */ - - printf (" _done:\n"); - printf (" _val = gen_sequence ();\n"); - printf (" _fail:\n"); - printf (" end_sequence ();\n"); - printf (" return _val;\n}\n\n"); -} - -/* Like gen_expand, but generates a SEQUENCE. */ -static void -gen_split (split) - rtx split; -{ - register int i; - int operands; - - if (XVEC (split, 0) == 0) - fatal ("define_split (definition %d) lacks a pattern", insn_index_number); - else if (XVEC (split, 2) == 0) - fatal ("define_split (definition %d) lacks a replacement pattern", - insn_index_number); - - /* Find out how many operands this function has. */ - - max_operand_vec (split, 2); - operands = MAX (max_opno, max_dup_opno) + 1; - - /* Output the function name and argument declarations. */ - printf ("rtx\ngen_split_%d (operands)\n rtx *operands;\n", - insn_code_number); - printf ("{\n"); - - /* Declare all local variables. */ - for (i = 0; i < operands; i++) - printf (" rtx operand%d;\n", i); - printf (" rtx _val = 0;\n"); - printf (" start_sequence ();\n"); - - /* The fourth operand of DEFINE_SPLIT is some code to be executed - before the actual construction. */ - - if (XSTR (split, 3)) - printf ("%s\n", XSTR (split, 3)); - - /* Output code to copy the arguments back out of `operands' */ - for (i = 0; i < operands; i++) - printf (" operand%d = operands[%d];\n", i, i); - - /* Output code to construct the rtl for the instruction bodies. - Use emit_insn to add them to the sequence being accumulated. - But don't do this if the user's code has set `no_more' nonzero. */ - - for (i = 0; i < XVECLEN (split, 2); i++) - { - rtx next = XVECEXP (split, 2, i); - if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC) - || GET_CODE (next) == RETURN) - printf (" emit_jump_insn ("); - else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL) - || GET_CODE (next) == CALL - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == CALL)) - printf (" emit_call_insn ("); - else if (GET_CODE (next) == CODE_LABEL) - printf (" emit_label ("); - else if (GET_CODE (next) == MATCH_OPERAND - || GET_CODE (next) == MATCH_OPERATOR - || GET_CODE (next) == MATCH_PARALLEL - || GET_CODE (next) == MATCH_OP_DUP - || GET_CODE (next) == MATCH_DUP - || GET_CODE (next) == PARALLEL) - printf (" emit ("); - else - printf (" emit_insn ("); - gen_exp (next); - printf (");\n"); - if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC - && GET_CODE (SET_SRC (next)) == LABEL_REF) - printf (" emit_barrier ();"); - } - - /* Call `gen_sequence' to make a SEQUENCE out of all the - insns emitted within this gen_... function. */ - - printf (" _done:\n"); - printf (" _val = gen_sequence ();\n"); - printf (" _fail:\n"); - printf (" end_sequence ();\n"); - printf (" return _val;\n}\n\n"); -} - -/* Write a function, `add_clobbers', that is given a PARALLEL of sufficient - size for the insn and an INSN_CODE, and inserts the required CLOBBERs at - the end of the vector. */ - -static void -output_add_clobbers () -{ - struct clobber_pat *clobber; - struct clobber_ent *ent; - int i; - - printf ("\n\nvoid\nadd_clobbers (pattern, insn_code_number)\n"); - printf (" rtx pattern;\n int insn_code_number;\n"); - printf ("{\n"); - printf (" int i;\n\n"); - printf (" switch (insn_code_number)\n"); - printf (" {\n"); - - for (clobber = clobber_list; clobber; clobber = clobber->next) - { - for (ent = clobber->insns; ent; ent = ent->next) - printf (" case %d:\n", ent->code_number); - - for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++) - { - printf (" XVECEXP (pattern, 0, %d) = ", i); - gen_exp (XVECEXP (clobber->pattern, 1, i)); - printf (";\n"); - } - - printf (" break;\n\n"); - } - - printf (" default:\n"); - printf (" abort ();\n"); - printf (" }\n"); - printf ("}\n"); -} - -/* Write a function, init_mov_optab, that is called to set up entries - in mov_optab for EXTRA_CC_MODES. */ - -static void -output_init_mov_optab () -{ -#ifdef EXTRA_CC_NAMES - static char *cc_names[] = { EXTRA_CC_NAMES }; - char *p; - int i; - - printf ("\nvoid\ninit_mov_optab ()\n{\n"); - - for (i = 0; i < sizeof cc_names / sizeof cc_names[0]; i++) - { - printf ("#ifdef HAVE_mov"); - for (p = cc_names[i]; *p; p++) - printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p); - printf ("\n"); - printf (" if (HAVE_mov"); - for (p = cc_names[i]; *p; p++) - printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p); - printf (")\n"); - printf (" mov_optab->handlers[(int) %smode].insn_code = CODE_FOR_mov", - cc_names[i]); - for (p = cc_names[i]; *p; p++) - printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p); - printf (";\n#endif\n"); - } - - printf ("}\n"); -#endif -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genemit: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - /* Assign sequential codes to all entries in the machine description - in parallel with the tables in insn-output.c. */ - - insn_code_number = 0; - insn_index_number = 0; - - printf ("/* Generated automatically by the program `genemit'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"expr.h\"\n"); - printf ("#include \"real.h\"\n"); - printf ("#include \"output.h\"\n"); - printf ("#include \"insn-config.h\"\n\n"); - printf ("#include \"insn-flags.h\"\n\n"); - printf ("#include \"insn-codes.h\"\n\n"); - printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n"); - printf ("extern rtx recog_operand[];\n"); - printf ("#define operands emit_operand\n\n"); - printf ("#define FAIL goto _fail\n\n"); - printf ("#define DONE goto _done\n\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - { - gen_insn (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_EXPAND) - { - gen_expand (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_SPLIT) - { - gen_split (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - { - ++insn_code_number; - } - ++insn_index_number; - } - - /* Write out the routine to add CLOBBERs to a pattern. */ - output_add_clobbers (); - - /* Write the routine to initialize mov_optab for the EXTRA_CC_MODES. */ - output_init_mov_optab (); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genextract.c b/gnu/usr.bin/gcc2/arch/genextract.c deleted file mode 100644 index dc1b313b3c6..00000000000 --- a/gnu/usr.bin/gcc2/arch/genextract.c +++ /dev/null @@ -1,542 +0,0 @@ -/* Generate code from machine description to extract operands from insn as rtl. - Copyright (C) 1987, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genextract.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" -#include "insn-config.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -/* This structure contains all the information needed to describe one - set of extractions methods. Each method may be used by more than - one pattern if the operands are in the same place. - - The string for each operand describes that path to the operand and - contains `0' through `9' when going into an expression and `a' through - `z' when going into a vector. We assume here that only the first operand - of an rtl expression is a vector. genrecog.c makes the same assumption - (and uses the same representation) and it is currently true. */ - -struct extraction -{ - int op_count; - char *oplocs[MAX_RECOG_OPERANDS]; - int dup_count; - char *duplocs[MAX_DUP_OPERANDS]; - int dupnums[MAX_DUP_OPERANDS]; - struct code_ptr *insns; - struct extraction *next; -}; - -/* Holds a single insn code that use an extraction method. */ - -struct code_ptr -{ - int insn_code; - struct code_ptr *next; -}; - -static struct extraction *extractions; - -/* Number instruction patterns handled, starting at 0 for first one. */ - -static int insn_code_number; - -/* Records the large operand number in this insn. */ - -static int op_count; - -/* Records the location of any operands using the string format described - above. */ - -static char *oplocs[MAX_RECOG_OPERANDS]; - -/* Number the occurrences of MATCH_DUP in each instruction, - starting at 0 for the first occurrence. */ - -static int dup_count; - -/* Records the location of any MATCH_DUP operands. */ - -static char *duplocs[MAX_DUP_OPERANDS]; - -/* Record the operand number of any MATCH_DUPs. */ - -static int dupnums[MAX_DUP_OPERANDS]; - -/* Record the list of insn_codes for peepholes. */ - -static struct code_ptr *peepholes; - -static void walk_rtx (); -static void print_path (); -char *xmalloc (); -char *xrealloc (); -static void fatal (); -static char *copystr (); -static void mybzero (); -void fancy_abort (); - -static void -gen_insn (insn) - rtx insn; -{ - register int i; - register struct extraction *p; - register struct code_ptr *link; - - op_count = 0; - dup_count = 0; - - /* No operands seen so far in this pattern. */ - mybzero (oplocs, sizeof oplocs); - - /* Walk the insn's pattern, remembering at all times the path - down to the walking point. */ - - if (XVECLEN (insn, 1) == 1) - walk_rtx (XVECEXP (insn, 1, 0), ""); - else - for (i = XVECLEN (insn, 1) - 1; i >= 0; i--) - { - char *path = (char *) alloca (2); - - path[0] = 'a' + i; - path[1] = 0; - - walk_rtx (XVECEXP (insn, 1, i), path); - } - - link = (struct code_ptr *) xmalloc (sizeof (struct code_ptr)); - link->insn_code = insn_code_number; - - /* See if we find something that already had this extraction method. */ - - for (p = extractions; p; p = p->next) - { - if (p->op_count != op_count || p->dup_count != dup_count) - continue; - - for (i = 0; i < op_count; i++) - if (p->oplocs[i] != oplocs[i] - && ! (p->oplocs[i] != 0 && oplocs[i] != 0 - && ! strcmp (p->oplocs[i], oplocs[i]))) - break; - - if (i != op_count) - continue; - - for (i = 0; i < dup_count; i++) - if (p->dupnums[i] != dupnums[i] - || strcmp (p->duplocs[i], duplocs[i])) - break; - - if (i != dup_count) - continue; - - /* This extraction is the same as ours. Just link us in. */ - link->next = p->insns; - p->insns = link; - return; - } - - /* Otherwise, make a new extraction method. */ - - p = (struct extraction *) xmalloc (sizeof (struct extraction)); - p->op_count = op_count; - p->dup_count = dup_count; - p->next = extractions; - extractions = p; - p->insns = link; - link->next = 0; - - for (i = 0; i < op_count; i++) - p->oplocs[i] = oplocs[i]; - - for (i = 0; i < dup_count; i++) - p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i]; -} - -static void -walk_rtx (x, path) - rtx x; - char *path; -{ - register RTX_CODE code; - register int i; - register int len; - register char *fmt; - register struct code_ptr *link; - int depth = strlen (path); - char *newpath; - - if (x == 0) - return; - - code = GET_CODE (x); - - switch (code) - { - case PC: - case CC0: - case CONST_INT: - case SYMBOL_REF: - return; - - case MATCH_OPERAND: - case MATCH_SCRATCH: - oplocs[XINT (x, 0)] = copystr (path); - op_count = MAX (op_count, XINT (x, 0) + 1); - break; - - case MATCH_DUP: - case MATCH_OP_DUP: - case MATCH_PAR_DUP: - duplocs[dup_count] = copystr (path); - dupnums[dup_count] = XINT (x, 0); - dup_count++; - break; - - case MATCH_OPERATOR: - oplocs[XINT (x, 0)] = copystr (path); - op_count = MAX (op_count, XINT (x, 0) + 1); - - newpath = (char *) alloca (depth + 2); - strcpy (newpath, path); - newpath[depth + 1] = 0; - - for (i = XVECLEN (x, 2) - 1; i >= 0; i--) - { - newpath[depth] = '0' + i; - walk_rtx (XVECEXP (x, 2, i), newpath); - } - return; - - case MATCH_PARALLEL: - oplocs[XINT (x, 0)] = copystr (path); - op_count = MAX (op_count, XINT (x, 0) + 1); - - newpath = (char *) alloca (depth + 2); - strcpy (newpath, path); - newpath[depth + 1] = 0; - - for (i = XVECLEN (x, 2) - 1; i >= 0; i--) - { - newpath[depth] = 'a' + i; - walk_rtx (XVECEXP (x, 2, i), newpath); - } - return; - - case ADDRESS: - walk_rtx (XEXP (x, 0), path); - return; - } - - newpath = (char *) alloca (depth + 2); - strcpy (newpath, path); - newpath[depth + 1] = 0; - - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - if (fmt[i] == 'e' || fmt[i] == 'u') - { - newpath[depth] = '0' + i; - walk_rtx (XEXP (x, i), newpath); - } - else if (fmt[i] == 'E') - { - int j; - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - { - newpath[depth] = 'a' + j; - walk_rtx (XVECEXP (x, i, j), newpath); - } - } - } -} - -/* Given a PATH, representing a path down the instruction's - pattern from the root to a certain point, output code to - evaluate to the rtx at that point. */ - -static void -print_path (path) - char *path; -{ - register int len = strlen (path); - register int i; - - /* We first write out the operations (XEXP or XVECEXP) in reverse - order, then write "insn", then the indices in forward order. */ - - for (i = len - 1; i >=0 ; i--) - { - if (path[i] >= 'a' && path[i] <= 'z') - printf ("XVECEXP ("); - else if (path[i] >= '0' && path[i] <= '9') - printf ("XEXP ("); - else - abort (); - } - - printf ("pat"); - - for (i = 0; i < len; i++) - { - if (path[i] >= 'a' && path[i] <= 'z') - printf (", 0, %d)", path[i] - 'a'); - else if (path[i] >= '0' && path[i] <= '9') - printf (", %d)", path[i] - '0'); - else - abort (); - } -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genextract: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -static char * -copystr (s1) - char *s1; -{ - register char *tem; - - if (s1 == 0) - return 0; - - tem = (char *) xmalloc (strlen (s1) + 1); - strcpy (tem, s1); - - return tem; -} - -static void -mybzero (b, length) - register char *b; - register unsigned length; -{ - while (length-- > 0) - *b++ = 0; -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c, i; - struct extraction *p; - struct code_ptr *link; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - /* Assign sequential codes to all entries in the machine description - in parallel with the tables in insn-output.c. */ - - insn_code_number = 0; - - printf ("/* Generated automatically by the program `genextract'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n\n"); - - /* This variable exists only so it can be the "location" - of any missing operand whose numbers are skipped by a given pattern. */ - printf ("static rtx junk;\n"); - - printf ("extern rtx recog_operand[];\n"); - printf ("extern rtx *recog_operand_loc[];\n"); - printf ("extern rtx *recog_dup_loc[];\n"); - printf ("extern char recog_dup_num[];\n"); - printf ("extern\n#ifdef __GNUC__\n__volatile__\n#endif\n"); - printf ("void fatal_insn_not_found ();\n\n"); - - printf ("void\ninsn_extract (insn)\n"); - printf (" rtx insn;\n"); - printf ("{\n"); - printf (" register rtx *ro = recog_operand;\n"); - printf (" register rtx **ro_loc = recog_operand_loc;\n"); - printf (" rtx pat = PATTERN (insn);\n"); - printf (" switch (INSN_CODE (insn))\n"); - printf (" {\n"); - printf (" case -1:\n"); - printf (" fatal_insn_not_found (insn);\n\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - { - gen_insn (desc); - ++insn_code_number; - } - - else if (GET_CODE (desc) == DEFINE_PEEPHOLE) - { - struct code_ptr *link - = (struct code_ptr *) xmalloc (sizeof (struct code_ptr)); - - link->insn_code = insn_code_number; - link->next = peepholes; - peepholes = link; - ++insn_code_number; - } - - else if (GET_CODE (desc) == DEFINE_EXPAND - || GET_CODE (desc) == DEFINE_SPLIT) - ++insn_code_number; - } - - /* Write out code to handle peepholes and the insn_codes that it should - be called for. */ - if (peepholes) - { - for (link = peepholes; link; link = link->next) - printf (" case %d:\n", link->insn_code); - - /* The vector in the insn says how many operands it has. - And all it contains are operands. In fact, the vector was - created just for the sake of this function. */ - printf ("#if __GNUC__ > 1 && !defined (bcopy)\n"); - printf ("#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)\n"); - printf ("#endif\n"); - printf (" bcopy (&XVECEXP (pat, 0, 0), ro,\n"); - printf (" sizeof (rtx) * XVECLEN (pat, 0));\n"); - printf (" break;\n\n"); - } - - /* Write out all the ways to extract insn operands. */ - for (p = extractions; p; p = p->next) - { - for (link = p->insns; link; link = link->next) - printf (" case %d:\n", link->insn_code); - - for (i = 0; i < p->op_count; i++) - { - if (p->oplocs[i] == 0) - { - printf (" ro[%d] = const0_rtx;\n", i); - printf (" ro_loc[%d] = &junk;\n", i); - } - else - { - printf (" ro[%d] = *(ro_loc[%d] = &", i, i); - print_path (p->oplocs[i]); - printf (");\n"); - } - } - - for (i = 0; i < p->dup_count; i++) - { - printf (" recog_dup_loc[%d] = &", i); - print_path (p->duplocs[i]); - printf (";\n"); - printf (" recog_dup_num[%d] = %d;\n", i, p->dupnums[i]); - } - - printf (" break;\n\n"); - } - - /* This should never be reached. Note that we would also reach this abort - if we tried to extract something whose INSN_CODE was a DEFINE_EXPAND or - DEFINE_SPLIT, but that is correct. */ - printf (" default:\n abort ();\n"); - - printf (" }\n}\n"); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genflags.c b/gnu/usr.bin/gcc2/arch/genflags.c deleted file mode 100644 index 053ec3f8571..00000000000 --- a/gnu/usr.bin/gcc2/arch/genflags.c +++ /dev/null @@ -1,294 +0,0 @@ -/* Generate from machine description: - - - some flags HAVE_... saying which simple standard instructions are - available for this machine. - Copyright (C) 1987, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genflags.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -char *xmalloc (); -static void fatal (); -void fancy_abort (); - -/* Names for patterns. Need to allow linking with print-rtl. */ -char **insn_name_ptr; - -/* Obstacks to remember normal, and call insns. */ -static struct obstack call_obstack, normal_obstack; - -/* Max size of names encountered. */ -static int max_id_len; - -/* Count the number of match_operand's found. */ -static int -num_operands (x) - rtx x; -{ - int count = 0; - int i, j; - enum rtx_code code = GET_CODE (x); - char *format_ptr = GET_RTX_FORMAT (code); - - if (code == MATCH_OPERAND) - return 1; - - if (code == MATCH_OPERATOR || code == MATCH_PARALLEL) - count++; - - for (i = 0; i < GET_RTX_LENGTH (code); i++) - { - switch (*format_ptr++) - { - case 'u': - case 'e': - count += num_operands (XEXP (x, i)); - break; - - case 'E': - if (XVEC (x, i) != NULL) - for (j = 0; j < XVECLEN (x, i); j++) - count += num_operands (XVECEXP (x, i, j)); - - break; - } - } - - return count; -} - -/* Print out prototype information for a function. */ -static void -gen_proto (insn) - rtx insn; -{ - int num = num_operands (insn); - printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0)); - - if (num == 0) - printf ("void"); - else - { - while (num-- > 1) - printf ("rtx, "); - - printf ("rtx"); - } - - printf ("));\n"); -} - -/* Print out a function declaration without a prototype. */ -static void -gen_nonproto (insn) - rtx insn; -{ - printf ("extern rtx gen_%s ();\n", XSTR (insn, 0)); -} - -static void -gen_insn (insn) - rtx insn; -{ - char *name = XSTR (insn, 0); - char *p; - struct obstack *obstack_ptr; - int len; - - /* Don't mention instructions whose names are the null string. - They are in the machine description just to be recognized. */ - len = strlen (name); - if (len == 0) - return; - - if (len > max_id_len) - max_id_len = len; - - printf ("#define HAVE_%s ", name); - if (strlen (XSTR (insn, 2)) == 0) - printf ("1\n"); - else - { - /* Write the macro definition, putting \'s at the end of each line, - if more than one. */ - printf ("("); - for (p = XSTR (insn, 2); *p; p++) - { - if (*p == '\n') - printf (" \\\n"); - else - printf ("%c", *p); - } - printf (")\n"); - } - - /* Save the current insn, so that we can later put out appropriate - prototypes. At present, most md files have the wrong number of - arguments for the call insns (call, call_value, call_pop, - call_value_pop) ignoring the extra arguments that are passed for - some machines, so by default, turn off the prototype. */ - - obstack_ptr = (name[0] == 'c' - && (!strcmp (name, "call") - || !strcmp (name, "call_value") - || !strcmp (name, "call_pop") - || !strcmp (name, "call_value_pop"))) - ? &call_obstack : &normal_obstack; - - obstack_grow (obstack_ptr, &insn, sizeof (rtx)); -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genflags: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - rtx dummy; - rtx *call_insns; - rtx *normal_insns; - rtx *insn_ptr; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - obstack_init (&call_obstack); - obstack_init (&normal_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - printf ("/* Generated automatically by the program `genflags'\n\ -from the machine description file `md'. */\n\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) - gen_insn (desc); - } - - /* Print out the prototypes now. */ - dummy = (rtx)0; - obstack_grow (&call_obstack, &dummy, sizeof (rtx)); - call_insns = (rtx *) obstack_finish (&call_obstack); - - obstack_grow (&normal_obstack, &dummy, sizeof (rtx)); - normal_insns = (rtx *) obstack_finish (&normal_obstack); - - printf ("\n#ifndef NO_MD_PROTOTYPES\n"); - for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++) - gen_proto (*insn_ptr); - - printf ("\n#ifdef MD_CALL_PROTOTYPES\n"); - for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) - gen_proto (*insn_ptr); - - printf ("\n#else /* !MD_CALL_PROTOTYPES */\n"); - for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) - gen_nonproto (*insn_ptr); - - printf ("#endif /* !MD_CALL_PROTOTYPES */\n"); - printf ("\n#else /* NO_MD_PROTOTYPES */\n"); - for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++) - gen_nonproto (*insn_ptr); - - for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) - gen_nonproto (*insn_ptr); - - printf ("#endif /* NO_MD_PROTOTYPES */\n"); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genopinit.c b/gnu/usr.bin/gcc2/arch/genopinit.c deleted file mode 100644 index d2f8392875f..00000000000 --- a/gnu/usr.bin/gcc2/arch/genopinit.c +++ /dev/null @@ -1,385 +0,0 @@ -/* Generate code to initialize optabs from machine description. - Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genopinit.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" -#include - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -char *xmalloc (); -static void fatal (); -void fancy_abort (); - -/* Many parts of GCC use arrays that are indexed by machine mode and - contain the insn codes for pattern in the MD file that perform a given - operation on operands of that mode. - - These patterns are present in the MD file with names that contain - the mode(s) used and the name of the operation. This program - writes a function `init_all_optabs' that initializes the optabs with - all the insn codes of the relevant patterns present in the MD file. - - This array contains a list of optabs that need to be initialized. Within - each string, the name of the pattern to be matched against is delimited - with %( and %). In the string, %a and %b are used to match a short mode - name (the part of the mode name not including `mode' and converted to - lower-case). When writing out the initializer, the entire string is - used. %A and %B are replaced with the full name of the mode; %a and %b - are replaced with the short form of the name, as above. - - If %N is present in the pattern, it means the two modes must be consecutive - widths in the same mode class (e.g, QImode and HImode). %I means that - only integer modes should be considered for the next mode, and %F means - that only float modes should be considered. - - For some optabs, we store the operation by RTL codes. These are only - used for comparisons. In that case, %c and %C are the lower-case and - upper-case forms of the comparison, respectively. */ - -/* The reason we use \% is to avoid sequences of the form %-capletter-% - which SCCS treats as magic. This gets warnings which you should ignore. */ - -char *optabs[] = -{ "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)", - "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)", - "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)", - "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)", - "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)", - "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)", - "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)", - "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)", - "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)", - "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)", - "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)", - "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N", - "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N", - "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)", - "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)", - "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)", - "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)", - "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)", - "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)", - "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)", - "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)", - "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)", - "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)", - "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)", - "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)", - "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)", - "lshl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshl%a3%)", - "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)", - "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)", - "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)", - "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)", - "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)", - "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)", - "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)", - "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)", - "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)", - "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)", - "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)", - "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)", - "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)", - "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)", - "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)", - "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)", - "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)", - "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)", - "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)", - "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)", - "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)", - "bcc_gen_fctn[(int) %C] = gen_%(b%c%)", - "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)", - "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)", - "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)", - "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)" }; - -/* Allow linking with print-rtl.c. */ -char **insn_name_ptr; - -static void -gen_insn (insn) - rtx insn; -{ - char *name = XSTR (insn, 0); - int m1, m2, op; - int pindex; - int i; - char *np, *pp, *p, *q; - struct obstack *obstack_ptr; - - /* Don't mention instructions whose names are the null string. - They are in the machine description just to be recognized. */ - if (*name == 0) - return; - - /* See if NAME matches one of the patterns we have for the optabs we know - about. */ - - for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++) - { - int force_float = 0, force_int = 0; - int force_consec = 0; - int matches = 1; - - for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++) - ; - - for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')'); - pp++) - { - if (*pp != '%') - { - if (*pp != *np++) - break; - } - else - switch (*++pp) - { - case 'N': - force_consec = 1; - break; - case 'I': - force_int = 1; - break; - case 'F': - force_float = 1; - break; - case 'c': - for (op = 0; op < NUM_RTX_CODE; op++) - { - for (p = rtx_name[op], q = np; *p; p++, q++) - if (*p != *q) - break; - - /* We have to be concerned about matching "gt" and - missing "gtu", e.g., so verify we have reached the - end of thing we are to match. We do not have this - problem with modes since no mode is a prefix of - another. */ - if (*p == 0 && *q == 0 && rtx_class[op] == '<') - break; - } - - if (op == NUM_RTX_CODE) - matches = 0; - else - np += strlen (rtx_name[op]); - break; - case 'a': - case 'b': - for (i = 0; i < (int) MAX_MACHINE_MODE; i++) - { - for (p = mode_name[i], q = np; *p; p++, q++) - if (tolower (*p) != *q) - break; - - if (*p == 0 - && (! force_int || mode_class[i] == MODE_INT) - && (! force_float || mode_class[i] == MODE_FLOAT)) - break; - } - - if (i == (int) MAX_MACHINE_MODE) - matches = 0; - else if (*pp == 'a') - m1 = i, np += strlen (mode_name[i]); - else - m2 = i, np += strlen (mode_name[i]); - - force_int = force_float = 0; - break; - - default: - abort (); - } - } - - if (matches && pp[0] == '%' && pp[1] == ')' - && *np == 0 - && (! force_consec || (int) mode_wider_mode[m1] == m2)) - break; - } - - if (pindex == sizeof optabs / sizeof optabs[0]) - return; - - /* We found a match. If this pattern is only conditionally present, - write out the "if" and two extra blanks. */ - - if (*XSTR (insn, 2) != 0) - printf (" if (HAVE_%s)\n ", name); - - printf (" "); - - /* Now write out the initialization, making all required substitutions. */ - for (pp = optabs[pindex]; *pp; pp++) - { - if (*pp != '%') - printf ("%c", *pp); - else - switch (*++pp) - { - case '(': case ')': - case 'I': case 'F': case 'N': - break; - case 'a': - for (np = mode_name[m1]; *np; np++) - printf ("%c", tolower (*np)); - break; - case 'b': - for (np = mode_name[m2]; *np; np++) - printf ("%c", tolower (*np)); - break; - case 'A': - printf ("%smode", mode_name[m1]); - break; - case 'B': - printf ("%smode", mode_name[m2]); - break; - case 'c': - printf ("%s", rtx_name[op]); - break; - case 'C': - for (np = rtx_name[op]; *np; np++) - printf ("%c", toupper (*np)); - break; - } - } - - printf (";\n"); -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genopinit: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - rtx dummy; - rtx *insn_ptr; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - printf ("/* Generated automatically by the program `genopinit'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"flags.h\"\n"); - printf ("#include \"insn-flags.h\"\n"); - printf ("#include \"insn-codes.h\"\n"); - printf ("#include \"insn-config.h\"\n"); - printf ("#include \"recog.h\"\n"); - printf ("#include \"expr.h\"\n"); - printf ("#include \"reload.h\"\n\n"); - - printf ("void\ninit_all_optabs ()\n{\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) - gen_insn (desc); - } - - printf ("}\n"); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genoutput.c b/gnu/usr.bin/gcc2/arch/genoutput.c deleted file mode 100644 index d8cf4d68d65..00000000000 --- a/gnu/usr.bin/gcc2/arch/genoutput.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* Generate code from to output assembler insns as recognized from rtl. - Copyright (C) 1987, 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genoutput.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -/* This program reads the machine description for the compiler target machine - and produces a file containing these things: - - 1. An array of strings `insn_template' which is indexed by insn code number - and contains the template for output of that insn, - - 2. An array of functions `insn_outfun' which, indexed by the insn code - number, gives the function that returns a template to use for output of - that insn. This is used only in the cases where the template is not - constant. These cases are specified by a * or @ at the beginning of the - template string in the machine description. They are identified for the - sake of other parts of the compiler by a zero element in `insn_template'. - - 3. An array of functions `insn_gen_function' which, indexed - by insn code number, gives the function to generate a body - for that pattern, given operands as arguments. - - 4. An array of strings `insn_name' which, indexed by insn code number, - gives the name for that pattern. Nameless patterns are given a name. - - 5. An array of ints `insn_n_operands' which is indexed by insn code number - and contains the number of distinct operands in the pattern for that insn, - - 6. An array of ints `insn_n_dups' which is indexed by insn code number - and contains the number of match_dup's that appear in the insn's pattern. - This says how many elements of `recog_dup_loc' are significant - after an insn has been recognized. - - 7. An array of arrays of operand constraint strings, - `insn_operand_constraint', - indexed first by insn code number and second by operand number, - containing the constraint for that operand. - - This array is generated only if register constraints appear in - match_operand rtx's. - - 8. An array of arrays of chars which indicate which operands of - which insn patterns appear within ADDRESS rtx's. This array is - called `insn_operand_address_p' and is generated only if there - are *no* register constraints in the match_operand rtx's. - - 9. An array of arrays of machine modes, `insn_operand_mode', - indexed first by insn code number and second by operand number, - containing the machine mode that that operand is supposed to have. - Also `insn_operand_strict_low', which is nonzero for operands - contained in a STRICT_LOW_PART. - - 10. An array of arrays of int-valued functions, `insn_operand_predicate', - indexed first by insn code number and second by operand number, - containing the match_operand predicate for this operand. - - 11. An array of ints, `insn_n_alternatives', that gives the number - of alternatives in the constraints of each pattern. - -The code number of an insn is simply its position in the machine description; -code numbers are assigned sequentially to entries in the description, -starting with code number 0. - -Thus, the following entry in the machine description - - (define_insn "clrdf" - [(set (match_operand:DF 0 "general_operand" "") - (const_int 0))] - "" - "clrd %0") - -assuming it is the 25th entry present, would cause -insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1. -It would not make an case in output_insn_hairy because the template -given in the entry is a constant (it does not start with `*'). */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -/* No instruction can have more operands than this. - Sorry for this arbitrary limit, but what machine will - have an instruction with this many operands? */ - -#define MAX_MAX_OPERANDS 40 - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -char *xmalloc (); -static void fatal (); -void fancy_abort (); -static void error (); -static void mybcopy (); -static void mybzero (); -static int n_occurrences (); - -/* insns in the machine description are assigned sequential code numbers - that are used by insn-recog.c (produced by genrecog) to communicate - to insn-output.c (produced by this program). */ - -static int next_code_number; - -/* This counts all definitions in the md file, - for the sake of error messages. */ - -static int next_index_number; - -/* Record in this chain all information that we will output, - associated with the code number of the insn. */ - -struct data -{ - int code_number; - int index_number; - char *name; - char *template; /* string such as "movl %1,%0" */ - int n_operands; /* Number of operands this insn recognizes */ - int n_dups; /* Number times match_dup appears in pattern */ - int n_alternatives; /* Number of alternatives in each constraint */ - struct data *next; - char *constraints[MAX_MAX_OPERANDS]; - /* Number of alternatives in constraints of operand N. */ - int op_n_alternatives[MAX_MAX_OPERANDS]; - char *predicates[MAX_MAX_OPERANDS]; - char address_p[MAX_MAX_OPERANDS]; - enum machine_mode modes[MAX_MAX_OPERANDS]; - char strict_low[MAX_MAX_OPERANDS]; - char outfun; /* Nonzero means this has an output function */ -}; - -/* This variable points to the first link in the chain. */ - -struct data *insn_data; - -/* Pointer to the last link in the chain, so new elements - can be added at the end. */ - -struct data *end_of_insn_data; - -/* Nonzero if any match_operand has a constraint string; - implies that REGISTER_CONSTRAINTS will be defined - for this machine description. */ - -int have_constraints; - -/* Nonzero if some error has occurred. We will make all errors fatal, but - might as well continue until we see all of them. */ - -static int have_error; - -static void -output_prologue () -{ - - printf ("/* Generated automatically by the program `genoutput'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"regs.h\"\n"); - printf ("#include \"hard-reg-set.h\"\n"); - printf ("#include \"real.h\"\n"); - printf ("#include \"insn-config.h\"\n\n"); - printf ("#include \"conditions.h\"\n"); - printf ("#include \"insn-flags.h\"\n"); - printf ("#include \"insn-attr.h\"\n\n"); - printf ("#include \"insn-codes.h\"\n\n"); - printf ("#include \"recog.h\"\n\n"); - - printf ("#include \n"); - printf ("#include \"output.h\"\n"); -} - -static void -output_epilogue () -{ - register struct data *d; - - printf ("\nchar * const insn_template[] =\n {\n"); - for (d = insn_data; d; d = d->next) - { - if (d->template) - printf (" \"%s\",\n", d->template); - else - printf (" 0,\n"); - } - printf (" };\n"); - - printf ("\nchar *(*const insn_outfun[])() =\n {\n"); - for (d = insn_data; d; d = d->next) - { - if (d->outfun) - printf (" output_%d,\n", d->code_number); - else - printf (" 0,\n"); - } - printf (" };\n"); - - printf ("\nrtx (*const insn_gen_function[]) () =\n {\n"); - for (d = insn_data; d; d = d->next) - { - if (d->name) - printf (" gen_%s,\n", d->name); - else - printf (" 0,\n"); - } - printf (" };\n"); - - printf ("\nchar *insn_name[] =\n {\n"); - { - int offset = 0; - int next; - char * last_name = 0; - char * next_name; - register struct data *n; - - for (n = insn_data, next = 0; n; n = n->next, next++) - if (n->name) - { - next_name = n->name; - break; - } - - for (d = insn_data; d; d = d->next) - { - if (d->name) - { - printf (" \"%s\",\n", d->name); - offset = 0; - last_name = d->name; - next_name = 0; - for (n = d->next, next = 1; n; n = n->next, next++) - if (n->name) - { - next_name = n->name; - break; - } - } - else - { - offset++; - if (next_name && (last_name == 0 || offset > next / 2)) - printf (" \"%s-%d\",\n", next_name, next - offset); - else - printf (" \"%s+%d\",\n", last_name, offset); - } - } - } - printf (" };\n"); - printf ("char **insn_name_ptr = insn_name;\n"); - - printf ("\nconst int insn_n_operands[] =\n {\n"); - for (d = insn_data; d; d = d->next) - printf (" %d,\n", d->n_operands); - printf (" };\n"); - - printf ("\nconst int insn_n_dups[] =\n {\n"); - for (d = insn_data; d; d = d->next) - printf (" %d,\n", d->n_dups); - printf (" };\n"); - - if (have_constraints) - { - printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n"); - for (d = insn_data; d; d = d->next) - { - register int i; - printf (" {"); - for (i = 0; i < d->n_operands; i++) - { - if (d->constraints[i] == 0) - printf (" \"\","); - else - printf (" \"%s\",", d->constraints[i]); - } - if (d->n_operands == 0) - printf (" 0"); - printf (" },\n"); - } - printf (" };\n"); - } - else - { - printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n"); - for (d = insn_data; d; d = d->next) - { - register int i; - printf (" {"); - for (i = 0; i < d->n_operands; i++) - printf (" %d,", d->address_p[i]); - if (d->n_operands == 0) - printf (" 0"); - printf (" },\n"); - } - printf (" };\n"); - } - - printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n"); - for (d = insn_data; d; d = d->next) - { - register int i; - printf (" {"); - for (i = 0; i < d->n_operands; i++) - printf (" %smode,", GET_MODE_NAME (d->modes[i])); - if (d->n_operands == 0) - printf (" VOIDmode"); - printf (" },\n"); - } - printf (" };\n"); - - printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n"); - for (d = insn_data; d; d = d->next) - { - register int i; - printf (" {"); - for (i = 0; i < d->n_operands; i++) - printf (" %d,", d->strict_low[i]); - if (d->n_operands == 0) - printf (" 0"); - printf (" },\n"); - } - printf (" };\n"); - - { - /* We need to define all predicates used. Keep a list of those we - have defined so far. There normally aren't very many predicates used, - so a linked list should be fast enough. */ - struct predicate { char *name; struct predicate *next; } *predicates = 0; - struct predicate *p; - int i; - - printf ("\n"); - for (d = insn_data; d; d = d->next) - for (i = 0; i < d->n_operands; i++) - if (d->predicates[i] && d->predicates[i][0]) - { - for (p = predicates; p; p = p->next) - if (! strcmp (p->name, d->predicates[i])) - break; - - if (p == 0) - { - printf ("extern int %s ();\n", d->predicates[i]); - p = (struct predicate *) alloca (sizeof (struct predicate)); - p->name = d->predicates[i]; - p->next = predicates; - predicates = p; - } - } - - printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n"); - for (d = insn_data; d; d = d->next) - { - printf (" {"); - for (i = 0; i < d->n_operands; i++) - printf (" %s,", ((d->predicates[i] && d->predicates[i][0]) - ? d->predicates[i] : "0")); - if (d->n_operands == 0) - printf (" 0"); - printf (" },\n"); - } - printf (" };\n"); - } - - printf ("\nconst int insn_n_alternatives[] =\n {\n"); - for (d = insn_data; d; d = d->next) - printf (" %d,\n", d->n_alternatives); - printf(" };\n"); -} - -/* scan_operands (X) stores in max_opno the largest operand - number present in X, if that is larger than the previous - value of max_opno. It stores all the constraints in `constraints' - and all the machine modes in `modes'. - - THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS. - THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */ - -static int max_opno; -static int num_dups; -static char *constraints[MAX_MAX_OPERANDS]; -static int op_n_alternatives[MAX_MAX_OPERANDS]; -static char *predicates[MAX_MAX_OPERANDS]; -static char address_p[MAX_MAX_OPERANDS]; -static enum machine_mode modes[MAX_MAX_OPERANDS]; -static char strict_low[MAX_MAX_OPERANDS]; -static char seen[MAX_MAX_OPERANDS]; - -static void -scan_operands (part, this_address_p, this_strict_low) - rtx part; - int this_address_p; - int this_strict_low; -{ - register int i, j; - register char *format_ptr; - int opno; - - if (part == 0) - return; - - switch (GET_CODE (part)) - { - case MATCH_OPERAND: - opno = XINT (part, 0); - if (opno > max_opno) - max_opno = opno; - if (max_opno >= MAX_MAX_OPERANDS) - { - error ("Too many operands (%d) in definition %d.\n", - max_opno + 1, next_index_number); - return; - } - if (seen[opno]) - error ("Definition %d specified operand number %d more than once.\n", - next_index_number, opno); - seen[opno] = 1; - modes[opno] = GET_MODE (part); - strict_low[opno] = this_strict_low; - predicates[opno] = XSTR (part, 1); - constraints[opno] = XSTR (part, 2); - if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0) - { - op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1; - have_constraints = 1; - } - address_p[opno] = this_address_p; - return; - - case MATCH_SCRATCH: - opno = XINT (part, 0); - if (opno > max_opno) - max_opno = opno; - if (max_opno >= MAX_MAX_OPERANDS) - { - error ("Too many operands (%d) in definition %d.\n", - max_opno + 1, next_index_number); - return; - } - if (seen[opno]) - error ("Definition %d specified operand number %d more than once.\n", - next_index_number, opno); - seen[opno] = 1; - modes[opno] = GET_MODE (part); - strict_low[opno] = 0; - predicates[opno] = "scratch_operand"; - constraints[opno] = XSTR (part, 1); - if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0) - { - op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1; - have_constraints = 1; - } - address_p[opno] = 0; - return; - - case MATCH_OPERATOR: - case MATCH_PARALLEL: - opno = XINT (part, 0); - if (opno > max_opno) - max_opno = opno; - if (max_opno >= MAX_MAX_OPERANDS) - { - error ("Too many operands (%d) in definition %d.\n", - max_opno + 1, next_index_number); - return; - } - if (seen[opno]) - error ("Definition %d specified operand number %d more than once.\n", - next_index_number, opno); - seen[opno] = 1; - modes[opno] = GET_MODE (part); - strict_low[opno] = 0; - predicates[opno] = XSTR (part, 1); - constraints[opno] = 0; - address_p[opno] = 0; - for (i = 0; i < XVECLEN (part, 2); i++) - scan_operands (XVECEXP (part, 2, i), 0, 0); - return; - - case MATCH_DUP: - case MATCH_OP_DUP: - case MATCH_PAR_DUP: - ++num_dups; - return; - - case ADDRESS: - scan_operands (XEXP (part, 0), 1, 0); - return; - - case STRICT_LOW_PART: - scan_operands (XEXP (part, 0), 0, 1); - return; - } - - format_ptr = GET_RTX_FORMAT (GET_CODE (part)); - - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) - switch (*format_ptr++) - { - case 'e': - scan_operands (XEXP (part, i), 0, 0); - break; - case 'E': - if (XVEC (part, i) != NULL) - for (j = 0; j < XVECLEN (part, i); j++) - scan_operands (XVECEXP (part, i, j), 0, 0); - break; - } -} - -/* Process an assembler template from a define_insn or a define_peephole. - It is either the assembler code template, a list of assembler code - templates, or C code to generate the assembler code template. */ - -static void -process_template (d, template) - struct data *d; - char *template; -{ - register char *cp; - register int i; - - /* We need to consider only the instructions whose assembler code template - starts with a * or @. These are the ones where C code is run to decide - on a template to use. So for all others just return now. */ - - if (template[0] != '*' && template[0] != '@') - { - d->template = template; - d->outfun = 0; - return; - } - - d->template = 0; - d->outfun = 1; - - printf ("\nstatic char *\n"); - printf ("output_%d (operands, insn)\n", d->code_number); - printf (" rtx *operands;\n"); - printf (" rtx insn;\n"); - printf ("{\n"); - - /* If the assembler code template starts with a @ it is a newline-separated - list of assembler code templates, one for each alternative. So produce - a routine to select the correct one. */ - - if (template[0] == '@') - { - - printf (" static /*const*/ char *const strings_%d[] = {\n", - d->code_number); - - for (i = 0, cp = &template[1]; *cp; ) - { - while (*cp == '\n' || *cp == ' ' || *cp== '\t') - cp++; - - printf (" \""); - while (*cp != '\n' && *cp != '\0') - putchar (*cp++); - - printf ("\",\n"); - i++; - } - - printf (" };\n"); - printf (" return strings_%d[which_alternative];\n", d->code_number); - - if (i != d->n_alternatives) - fatal ("Insn pattern %d has %d alternatives but %d assembler choices", - d->index_number, d->n_alternatives, i); - - } - else - { - /* The following is done in a funny way to get around problems in - VAX-11 "C" on VMS. It is the equivalent of: - printf ("%s\n", &template[1])); */ - cp = &template[1]; - while (*cp) putchar (*cp++); - putchar ('\n'); - } - - printf ("}\n"); -} - -/* Check insn D for consistency in number of constraint alternatives. */ - -static void -validate_insn_alternatives (d) - struct data *d; -{ - register int n = 0, start; - /* Make sure all the operands have the same number of - alternatives in their constraints. - Let N be that number. */ - for (start = 0; start < d->n_operands; start++) - if (d->op_n_alternatives[start] > 0) - { - if (n == 0) - n = d->op_n_alternatives[start]; - else if (n != d->op_n_alternatives[start]) - error ("wrong number of alternatives in operand %d of insn number %d", - start, d->index_number); - } - /* Record the insn's overall number of alternatives. */ - d->n_alternatives = n; -} - -/* Look at a define_insn just read. Assign its code number. - Record on insn_data the template and the number of arguments. - If the insn has a hairy output action, output a function for now. */ - -static void -gen_insn (insn) - rtx insn; -{ - register struct data *d = (struct data *) xmalloc (sizeof (struct data)); - register int i; - - d->code_number = next_code_number++; - d->index_number = next_index_number; - if (XSTR (insn, 0)[0]) - d->name = XSTR (insn, 0); - else - d->name = 0; - - /* Build up the list in the same order as the insns are seen - in the machine description. */ - d->next = 0; - if (end_of_insn_data) - end_of_insn_data->next = d; - else - insn_data = d; - - end_of_insn_data = d; - - max_opno = -1; - num_dups = 0; - - mybzero (constraints, sizeof constraints); - mybzero (op_n_alternatives, sizeof op_n_alternatives); - mybzero (predicates, sizeof predicates); - mybzero (address_p, sizeof address_p); - mybzero (modes, sizeof modes); - mybzero (strict_low, sizeof strict_low); - mybzero (seen, sizeof seen); - - for (i = 0; i < XVECLEN (insn, 1); i++) - scan_operands (XVECEXP (insn, 1, i), 0, 0); - - d->n_operands = max_opno + 1; - d->n_dups = num_dups; - - mybcopy (constraints, d->constraints, sizeof constraints); - mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); - mybcopy (predicates, d->predicates, sizeof predicates); - mybcopy (address_p, d->address_p, sizeof address_p); - mybcopy (modes, d->modes, sizeof modes); - mybcopy (strict_low, d->strict_low, sizeof strict_low); - - validate_insn_alternatives (d); - process_template (d, XSTR (insn, 3)); -} - -/* Look at a define_peephole just read. Assign its code number. - Record on insn_data the template and the number of arguments. - If the insn has a hairy output action, output it now. */ - -static void -gen_peephole (peep) - rtx peep; -{ - register struct data *d = (struct data *) xmalloc (sizeof (struct data)); - register int i; - - d->code_number = next_code_number++; - d->index_number = next_index_number; - d->name = 0; - - /* Build up the list in the same order as the insns are seen - in the machine description. */ - d->next = 0; - if (end_of_insn_data) - end_of_insn_data->next = d; - else - insn_data = d; - - end_of_insn_data = d; - - max_opno = -1; - mybzero (constraints, sizeof constraints); - mybzero (op_n_alternatives, sizeof op_n_alternatives); - mybzero (predicates, sizeof predicates); - mybzero (address_p, sizeof address_p); - mybzero (modes, sizeof modes); - mybzero (strict_low, sizeof strict_low); - mybzero (seen, sizeof seen); - - /* Get the number of operands by scanning all the - patterns of the peephole optimizer. - But ignore all the rest of the information thus obtained. */ - for (i = 0; i < XVECLEN (peep, 0); i++) - scan_operands (XVECEXP (peep, 0, i), 0, 0); - - d->n_operands = max_opno + 1; - d->n_dups = 0; - - mybcopy (constraints, d->constraints, sizeof constraints); - mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); - mybzero (d->predicates, sizeof predicates); - mybzero (d->address_p, sizeof address_p); - mybzero (d->modes, sizeof modes); - mybzero (d->strict_low, sizeof strict_low); - - validate_insn_alternatives (d); - process_template (d, XSTR (peep, 2)); -} - -/* Process a define_expand just read. Assign its code number, - only for the purposes of `insn_gen_function'. */ - -static void -gen_expand (insn) - rtx insn; -{ - register struct data *d = (struct data *) xmalloc (sizeof (struct data)); - register int i; - - d->code_number = next_code_number++; - d->index_number = next_index_number; - if (XSTR (insn, 0)[0]) - d->name = XSTR (insn, 0); - else - d->name = 0; - - /* Build up the list in the same order as the insns are seen - in the machine description. */ - d->next = 0; - if (end_of_insn_data) - end_of_insn_data->next = d; - else - insn_data = d; - - end_of_insn_data = d; - - max_opno = -1; - num_dups = 0; - - /* Scan the operands to get the specified predicates and modes, - since expand_binop needs to know them. */ - - mybzero (constraints, sizeof constraints); - mybzero (op_n_alternatives, sizeof op_n_alternatives); - mybzero (predicates, sizeof predicates); - mybzero (address_p, sizeof address_p); - mybzero (modes, sizeof modes); - mybzero (strict_low, sizeof strict_low); - mybzero (seen, sizeof seen); - - if (XVEC (insn, 1)) - for (i = 0; i < XVECLEN (insn, 1); i++) - scan_operands (XVECEXP (insn, 1, i), 0, 0); - - d->n_operands = max_opno + 1; - d->n_dups = num_dups; - - mybcopy (constraints, d->constraints, sizeof constraints); - mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); - mybcopy (predicates, d->predicates, sizeof predicates); - mybcopy (address_p, d->address_p, sizeof address_p); - mybcopy (modes, d->modes, sizeof modes); - mybcopy (strict_low, d->strict_low, sizeof strict_low); - - d->template = 0; - d->outfun = 0; - validate_insn_alternatives (d); -} - -/* Process a define_split just read. Assign its code number, - only for reasons of consistency and to simplify genrecog. */ - - -static void -gen_split (split) - rtx split; -{ - register struct data *d = (struct data *) xmalloc (sizeof (struct data)); - register int i; - - d->code_number = next_code_number++; - d->index_number = next_index_number; - d->name = 0; - - /* Build up the list in the same order as the insns are seen - in the machine description. */ - d->next = 0; - if (end_of_insn_data) - end_of_insn_data->next = d; - else - insn_data = d; - - end_of_insn_data = d; - - max_opno = -1; - num_dups = 0; - - mybzero (constraints, sizeof constraints); - mybzero (op_n_alternatives, sizeof op_n_alternatives); - mybzero (predicates, sizeof predicates); - mybzero (address_p, sizeof address_p); - mybzero (modes, sizeof modes); - mybzero (strict_low, sizeof strict_low); - mybzero (seen, sizeof seen); - - /* Get the number of operands by scanning all the - patterns of the split patterns. - But ignore all the rest of the information thus obtained. */ - for (i = 0; i < XVECLEN (split, 0); i++) - scan_operands (XVECEXP (split, 0, i), 0, 0); - - d->n_operands = max_opno + 1; - - mybzero (d->constraints, sizeof constraints); - mybzero (d->op_n_alternatives, sizeof op_n_alternatives); - mybzero (d->predicates, sizeof predicates); - mybzero (d->address_p, sizeof address_p); - mybzero (d->modes, sizeof modes); - mybzero (d->strict_low, sizeof strict_low); - - d->n_dups = 0; - d->n_alternatives = 0; - d->template = 0; - d->outfun = 0; -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -mybzero (b, length) - register char *b; - register unsigned length; -{ - while (length-- > 0) - *b++ = 0; -} - -static void -mybcopy (b1, b2, length) - register char *b1; - register char *b2; - register unsigned length; -{ - while (length-- > 0) - *b2++ = *b1++; -} - -static void -fatal (s, a1, a2, a3, a4) - char *s; -{ - fprintf (stderr, "genoutput: "); - fprintf (stderr, s, a1, a2, a3, a4); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -static void -error (s, a1, a2) - char *s; -{ - fprintf (stderr, "genoutput: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - - have_error = 1; -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - output_prologue (); - next_code_number = 0; - next_index_number = 0; - have_constraints = 0; - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - gen_insn (desc); - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - gen_peephole (desc); - if (GET_CODE (desc) == DEFINE_EXPAND) - gen_expand (desc); - if (GET_CODE (desc) == DEFINE_SPLIT) - gen_split (desc); - next_index_number++; - } - - output_epilogue (); - - fflush (stdout); - exit (ferror (stdout) != 0 || have_error - ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - - /* NOTREACHED */ - return 0; -} - -static int -n_occurrences (c, s) - char c; - char *s; -{ - int n = 0; - while (*s) - n += (*s++ == c); - return n; -} diff --git a/gnu/usr.bin/gcc2/arch/genpeep.c b/gnu/usr.bin/gcc2/arch/genpeep.c deleted file mode 100644 index 749b66a800f..00000000000 --- a/gnu/usr.bin/gcc2/arch/genpeep.c +++ /dev/null @@ -1,511 +0,0 @@ -/* Generate code from machine description to perform peephole optimizations. - Copyright (C) 1987, 1989, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genpeep.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -/* While tree-walking an instruction pattern, we keep a chain - of these `struct link's to record how to get down to the - current position. In each one, POS is the operand number, - and if the operand is a vector VEC is the element number. - VEC is -1 if the operand is not a vector. */ - -struct link -{ - struct link *next; - int pos; - int vecelt; -}; - -char *xmalloc (); -static void match_rtx (); -static void gen_exp (); -static void fatal (); -void fancy_abort (); - -static int max_opno; - -/* Number of operands used in current peephole definition. */ - -static int n_operands; - -/* Peephole optimizations get insn codes just like insn patterns. - Count them so we know the code of the define_peephole we are handling. */ - -static int insn_code_number = 0; - -static void print_path (); -static void print_code (); - -static void -gen_peephole (peep) - rtx peep; -{ - int ninsns = XVECLEN (peep, 0); - int i; - - n_operands = 0; - - printf (" insn = ins1;\n"); -#if 0 - printf (" want_jump = 0;\n"); -#endif - - for (i = 0; i < ninsns; i++) - { - if (i > 0) - { - printf (" do { insn = NEXT_INSN (insn);\n"); - printf (" if (insn == 0) goto L%d; }\n", - insn_code_number); - printf (" while (GET_CODE (insn) == NOTE\n"); - printf ("\t || (GET_CODE (insn) == INSN\n"); - printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n"); - printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n"); - - printf (" if (GET_CODE (insn) == CODE_LABEL\n\ - || GET_CODE (insn) == BARRIER)\n goto L%d;\n", - insn_code_number); - } - -#if 0 - printf (" if (GET_CODE (insn) == JUMP_INSN)\n"); - printf (" want_jump = JUMP_LABEL (insn);\n"); -#endif - - printf (" pat = PATTERN (insn);\n"); - - /* Walk the insn's pattern, remembering at all times the path - down to the walking point. */ - - match_rtx (XVECEXP (peep, 0, i), NULL_PTR, insn_code_number); - } - - /* We get this far if the pattern matches. - Now test the extra condition. */ - - if (XSTR (peep, 1) && XSTR (peep, 1)[0]) - printf (" if (! (%s)) goto L%d;\n", - XSTR (peep, 1), insn_code_number); - - /* If that matches, construct new pattern and put it in the first insn. - This new pattern will never be matched. - It exists only so that insn-extract can get the operands back. - So use a simple regular form: a PARALLEL containing a vector - of all the operands. */ - - printf (" PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands); - -#if 0 - printf (" if (want_jump && GET_CODE (ins1) != JUMP_INSN)\n"); - printf (" {\n"); - printf (" rtx insn2 = emit_jump_insn_before (PATTERN (ins1), ins1);\n"); - printf (" delete_insn (ins1);\n"); - printf (" ins1 = ins2;\n"); - printf (" }\n"); -#endif - - /* Record this define_peephole's insn code in the insn, - as if it had been recognized to match this. */ - printf (" INSN_CODE (ins1) = %d;\n", - insn_code_number); - - /* Delete the remaining insns. */ - if (ninsns > 1) - printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n"); - - /* See reload1.c for insertion of NOTE which guarantees that this - cannot be zero. */ - printf (" return NEXT_INSN (insn);\n"); - - printf (" L%d:\n\n", insn_code_number); -} - -static void -match_rtx (x, path, fail_label) - rtx x; - struct link *path; - int fail_label; -{ - register RTX_CODE code; - register int i; - register int len; - register char *fmt; - struct link link; - - if (x == 0) - return; - - - code = GET_CODE (x); - - switch (code) - { - case MATCH_OPERAND: - if (XINT (x, 0) > max_opno) - max_opno = XINT (x, 0); - if (XINT (x, 0) >= n_operands) - n_operands = 1 + XINT (x, 0); - - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" operands[%d] = x;\n", XINT (x, 0)); - if (XSTR (x, 1) && XSTR (x, 1)[0]) - printf (" if (! %s (x, %smode)) goto L%d;\n", - XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label); - return; - - case MATCH_DUP: - case MATCH_PAR_DUP: - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" if (!rtx_equal_p (operands[%d], x)) goto L%d;\n", - XINT (x, 0), fail_label); - return; - - case MATCH_OP_DUP: - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" if (GET_CODE (operands[%d]) != GET_CODE (x)\n", XINT (x, 0)); - printf (" || GET_MODE (operands[%d]) != GET_MODE (x)) goto L%d;\n", - XINT (x, 0), fail_label); - printf (" operands[%d] = x;\n", XINT (x, 0)); - link.next = path; - link.vecelt = -1; - for (i = 0; i < XVECLEN (x, 1); i++) - { - link.pos = i; - match_rtx (XVECEXP (x, 1, i), &link, fail_label); - } - return; - - case MATCH_OPERATOR: - if (XINT (x, 0) > max_opno) - max_opno = XINT (x, 0); - if (XINT (x, 0) >= n_operands) - n_operands = 1 + XINT (x, 0); - - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" operands[%d] = x;\n", XINT (x, 0)); - if (XSTR (x, 1) && XSTR (x, 1)[0]) - printf (" if (! %s (x, %smode)) goto L%d;\n", - XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label); - link.next = path; - link.vecelt = -1; - for (i = 0; i < XVECLEN (x, 2); i++) - { - link.pos = i; - match_rtx (XVECEXP (x, 2, i), &link, fail_label); - } - return; - - case MATCH_PARALLEL: - if (XINT (x, 0) > max_opno) - max_opno = XINT (x, 0); - if (XINT (x, 0) >= n_operands) - n_operands = 1 + XINT (x, 0); - - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" if (GET_CODE (x) != PARALLEL) goto L%d;\n", fail_label); - printf (" operands[%d] = x;\n", XINT (x, 0)); - if (XSTR (x, 1) && XSTR (x, 1)[0]) - printf (" if (! %s (x, %smode)) goto L%d;\n", - XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label); - link.next = path; - link.pos = 0; - for (i = 0; i < XVECLEN (x, 2); i++) - { - link.vecelt = i; - match_rtx (XVECEXP (x, 2, i), &link, fail_label); - } - return; - - case ADDRESS: - match_rtx (XEXP (x, 0), path, fail_label); - return; - } - - printf (" x = "); - print_path (path); - printf (";\n"); - - printf (" if (GET_CODE (x) != "); - print_code (code); - printf (") goto L%d;\n", fail_label); - - if (GET_MODE (x) != VOIDmode) - { - printf (" if (GET_MODE (x) != %smode) goto L%d;\n", - GET_MODE_NAME (GET_MODE (x)), fail_label); - } - - link.next = path; - link.vecelt = -1; - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - link.pos = i; - if (fmt[i] == 'e' || fmt[i] == 'u') - match_rtx (XEXP (x, i), &link, fail_label); - else if (fmt[i] == 'E') - { - int j; - printf (" if (XVECLEN (x, %d) != %d) goto L%d;\n", - i, XVECLEN (x, i), fail_label); - for (j = 0; j < XVECLEN (x, i); j++) - { - link.vecelt = j; - match_rtx (XVECEXP (x, i, j), &link, fail_label); - } - } - else if (fmt[i] == 'i') - { - /* Make sure that at run time `x' is the RTX we want to test. */ - if (i != 0) - { - printf (" x = "); - print_path (path); - printf (";\n"); - } - - printf (" if (XINT (x, %d) != %d) goto L%d;\n", - i, XINT (x, i), fail_label); - } - else if (fmt[i] == 'w') - { - /* Make sure that at run time `x' is the RTX we want to test. */ - if (i != 0) - { - printf (" x = "); - print_path (path); - printf (";\n"); - } - -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - printf (" if (XWINT (x, %d) != %d) goto L%d;\n", - i, XWINT (x, i), fail_label); -#else - printf (" if (XWINT (x, %d) != %ld) goto L%d;\n", - i, XWINT (x, i), fail_label); -#endif - } - else if (fmt[i] == 's') - { - /* Make sure that at run time `x' is the RTX we want to test. */ - if (i != 0) - { - printf (" x = "); - print_path (path); - printf (";\n"); - } - - printf (" if (strcmp (XSTR (x, %d), \"%s\")) goto L%d;\n", - i, XSTR (x, i), fail_label); - } - } -} - -/* Given a PATH, representing a path down the instruction's - pattern from the root to a certain point, output code to - evaluate to the rtx at that point. */ - -static void -print_path (path) - struct link *path; -{ - if (path == 0) - printf ("pat"); - else if (path->vecelt >= 0) - { - printf ("XVECEXP ("); - print_path (path->next); - printf (", %d, %d)", path->pos, path->vecelt); - } - else - { - printf ("XEXP ("); - print_path (path->next); - printf (", %d)", path->pos); - } -} - -static void -print_code (code) - RTX_CODE code; -{ - register char *p1; - for (p1 = GET_RTX_NAME (code); *p1; p1++) - { - if (*p1 >= 'a' && *p1 <= 'z') - putchar (*p1 + 'A' - 'a'); - else - putchar (*p1); - } -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (s, a1, a2) - char *s; -{ - fprintf (stderr, "genpeep: "); - fprintf (stderr, s, a1, a2); - fprintf (stderr, "\n"); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - FILE *infile; - register int c; - - max_opno = -1; - - obstack_init (rtl_obstack); - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - - printf ("/* Generated automatically by the program `genpeep'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"regs.h\"\n"); - printf ("#include \"output.h\"\n"); - printf ("#include \"real.h\"\n\n"); - - printf ("extern rtx peep_operand[];\n\n"); - printf ("#define operands peep_operand\n\n"); - - printf ("rtx\npeephole (ins1)\n rtx ins1;\n{\n"); - printf (" rtx insn, x, pat;\n"); - printf (" int i;\n\n"); - - /* Early out: no peepholes for insns followed by barriers. */ - printf (" if (NEXT_INSN (ins1)\n"); - printf (" && GET_CODE (NEXT_INSN (ins1)) == BARRIER)\n"); - printf (" return 0;\n\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - { - gen_peephole (desc); - insn_code_number++; - } - if (GET_CODE (desc) == DEFINE_INSN - || GET_CODE (desc) == DEFINE_EXPAND - || GET_CODE (desc) == DEFINE_SPLIT) - { - insn_code_number++; - } - } - - printf (" return 0;\n}\n\n"); - - if (max_opno == -1) - max_opno = 1; - - printf ("rtx peep_operand[%d];\n", max_opno + 1); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/genrecog.c b/gnu/usr.bin/gcc2/arch/genrecog.c deleted file mode 100644 index 67e85e825d5..00000000000 --- a/gnu/usr.bin/gcc2/arch/genrecog.c +++ /dev/null @@ -1,1797 +0,0 @@ -/* Generate code from machine description to recognize rtl as insns. - Copyright (C) 1987, 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: genrecog.c,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $"; -#endif /* not lint */ - -/* This program is used to produce insn-recog.c, which contains - a function called `recog' plus its subroutines. - These functions contain a decision tree - that recognizes whether an rtx, the argument given to recog, - is a valid instruction. - - recog returns -1 if the rtx is not valid. - If the rtx is valid, recog returns a nonnegative number - which is the insn code number for the pattern that matched. - This is the same as the order in the machine description of the - entry that matched. This number can be used as an index into various - insn_* tables, such as insn_template, insn_outfun, and insn_n_operands - (found in insn-output.c). - - The third argument to recog is an optional pointer to an int. - If present, recog will accept a pattern if it matches except for - missing CLOBBER expressions at the end. In that case, the value - pointed to by the optional pointer will be set to the number of - CLOBBERs that need to be added (it should be initialized to zero by - the caller). If it is set nonzero, the caller should allocate a - PARALLEL of the appropriate size, copy the initial entries, and call - add_clobbers (found in insn-emit.c) to fill in the CLOBBERs. - - This program also generates the function `split_insns', - which returns 0 if the rtl could not be split, or - it returns the split rtl in a SEQUENCE. */ - -#include -#include "config.h" -#include "rtl.h" -#include "obstack.h" - -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern rtx read_rtx (); - -/* Data structure for a listhead of decision trees. The alternatives - to a node are kept in a doublely-linked list so we can easily add nodes - to the proper place when merging. */ - -struct decision_head { struct decision *first, *last; }; - -/* Data structure for decision tree for recognizing - legitimate instructions. */ - -struct decision -{ - int number; /* Node number, used for labels */ - char *position; /* String denoting position in pattern */ - RTX_CODE code; /* Code to test for or UNKNOWN to suppress */ - char ignore_code; /* If non-zero, need not test code */ - char ignore_mode; /* If non-zero, need not test mode */ - int veclen; /* Length of vector, if nonzero */ - enum machine_mode mode; /* Machine mode of node */ - char enforce_mode; /* If non-zero, test `mode' */ - char retest_code, retest_mode; /* See write_tree_1 */ - int test_elt_zero_int; /* Nonzero if should test XINT (rtl, 0) */ - int elt_zero_int; /* Required value for XINT (rtl, 0) */ - int test_elt_one_int; /* Nonzero if should test XINT (rtl, 1) */ - int elt_one_int; /* Required value for XINT (rtl, 1) */ - int test_elt_zero_wide; /* Nonzero if should test XWINT (rtl, 0) */ - HOST_WIDE_INT elt_zero_wide; /* Required value for XWINT (rtl, 0) */ - char *tests; /* If nonzero predicate to call */ - int pred; /* `preds' index of predicate or -1 */ - char *c_test; /* Additional test to perform */ - struct decision_head success; /* Nodes to test on success */ - int insn_code_number; /* Insn number matched, if success */ - int num_clobbers_to_add; /* Number of CLOBBERs to be added to pattern */ - struct decision *next; /* Node to test on failure */ - struct decision *prev; /* Node whose failure tests us */ - struct decision *afterward; /* Node to test on success, but failure of - successor nodes */ - int opno; /* Operand number, if >= 0 */ - int dupno; /* Number of operand to compare against */ - int label_needed; /* Nonzero if label needed when writing tree */ - int subroutine_number; /* Number of subroutine this node starts */ -}; - -#define SUBROUTINE_THRESHOLD 50 - -static int next_subroutine_number; - -/* We can write two types of subroutines: One for insn recognition and - one to split insns. This defines which type is being written. */ - -enum routine_type {RECOG, SPLIT}; - -/* Next available node number for tree nodes. */ - -static int next_number; - -/* Next number to use as an insn_code. */ - -static int next_insn_code; - -/* Similar, but counts all expressions in the MD file; used for - error messages. */ - -static int next_index; - -/* Record the highest depth we ever have so we know how many variables to - allocate in each subroutine we make. */ - -static int max_depth; - -/* This table contains a list of the rtl codes that can possibly match a - predicate defined in recog.c. The function `not_both_true' uses it to - deduce that there are no expressions that can be matches by certain pairs - of tree nodes. Also, if a predicate can match only one code, we can - hardwire that code into the node testing the predicate. */ - -static struct pred_table -{ - char *name; - RTX_CODE codes[NUM_RTX_CODE]; -} preds[] - = {{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, - LABEL_REF, SUBREG, REG, MEM}}, -#ifdef PREDICATE_CODES - PREDICATE_CODES -#endif - {"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, - LABEL_REF, SUBREG, REG, MEM, PLUS, MINUS, MULT}}, - {"register_operand", {SUBREG, REG}}, - {"scratch_operand", {SCRATCH, REG}}, - {"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, - LABEL_REF}}, - {"const_int_operand", {CONST_INT}}, - {"const_double_operand", {CONST_INT, CONST_DOUBLE}}, - {"nonimmediate_operand", {SUBREG, REG, MEM}}, - {"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, - LABEL_REF, SUBREG, REG}}, - {"push_operand", {MEM}}, - {"memory_operand", {SUBREG, MEM}}, - {"indirect_operand", {SUBREG, MEM}}, - {"comparison_operation", {EQ, NE, LE, LT, GE, LT, LEU, LTU, GEU, GTU}}, - {"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, - LABEL_REF, SUBREG, REG, MEM}}}; - -#define NUM_KNOWN_PREDS (sizeof preds / sizeof preds[0]) - -static struct decision_head make_insn_sequence PROTO((rtx, enum routine_type)); -static struct decision *add_to_sequence PROTO((rtx, struct decision_head *, - char *)); -static int not_both_true PROTO((struct decision *, struct decision *, - int)); -static int position_merit PROTO((struct decision *, enum machine_mode, - enum rtx_code)); -static struct decision_head merge_trees PROTO((struct decision_head, - struct decision_head)); -static int break_out_subroutines PROTO((struct decision_head, - enum routine_type, int)); -static void write_subroutine PROTO((struct decision *, enum routine_type)); -static void write_tree_1 PROTO((struct decision *, char *, - struct decision *, enum routine_type)); -static void print_code PROTO((enum rtx_code)); -static int same_codes PROTO((struct decision *, enum rtx_code)); -static void clear_codes PROTO((struct decision *)); -static int same_modes PROTO((struct decision *, enum machine_mode)); -static void clear_modes PROTO((struct decision *)); -static void write_tree PROTO((struct decision *, char *, - struct decision *, int, - enum routine_type)); -static void change_state PROTO((char *, char *, int)); -static char *copystr PROTO((char *)); -static void mybzero PROTO((char *, unsigned)); -static void mybcopy PROTO((char *, char *, unsigned)); -static char *concat PROTO((char *, char *)); -static void fatal PROTO((char *)); -char *xrealloc PROTO((char *, unsigned)); -char *xmalloc PROTO((unsigned)); -void fancy_abort PROTO((void)); - -/* Construct and return a sequence of decisions - that will recognize INSN. - - TYPE says what type of routine we are recognizing (RECOG or SPLIT). */ - -static struct decision_head -make_insn_sequence (insn, type) - rtx insn; - enum routine_type type; -{ - rtx x; - char *c_test = XSTR (insn, type == RECOG ? 2 : 1); - struct decision *last; - struct decision_head head; - - if (XVECLEN (insn, type == RECOG) == 1) - x = XVECEXP (insn, type == RECOG, 0); - else - { - x = rtx_alloc (PARALLEL); - XVEC (x, 0) = XVEC (insn, type == RECOG); - PUT_MODE (x, VOIDmode); - } - - last = add_to_sequence (x, &head, ""); - - if (c_test[0]) - last->c_test = c_test; - last->insn_code_number = next_insn_code; - last->num_clobbers_to_add = 0; - - /* If this is not a DEFINE_SPLIT and X is a PARALLEL, see if it ends with a - group of CLOBBERs of (hard) registers or MATCH_SCRATCHes. If so, set up - to recognize the pattern without these CLOBBERs. */ - - if (type == RECOG && GET_CODE (x) == PARALLEL) - { - int i; - - for (i = XVECLEN (x, 0); i > 0; i--) - if (GET_CODE (XVECEXP (x, 0, i - 1)) != CLOBBER - || (GET_CODE (XEXP (XVECEXP (x, 0, i - 1), 0)) != REG - && GET_CODE (XEXP (XVECEXP (x, 0, i - 1), 0)) != MATCH_SCRATCH)) - break; - - if (i != XVECLEN (x, 0)) - { - rtx new; - struct decision_head clobber_head; - - if (i == 1) - new = XVECEXP (x, 0, 0); - else - { - int j; - - new = rtx_alloc (PARALLEL); - XVEC (new, 0) = rtvec_alloc (i); - for (j = i - 1; j >= 0; j--) - XVECEXP (new, 0, j) = XVECEXP (x, 0, j); - } - - last = add_to_sequence (new, &clobber_head, ""); - - if (c_test[0]) - last->c_test = c_test; - last->insn_code_number = next_insn_code; - last->num_clobbers_to_add = XVECLEN (x, 0) - i; - - head = merge_trees (head, clobber_head); - } - } - - next_insn_code++; - - if (type == SPLIT) - /* Define the subroutine we will call below and emit in genemit. */ - printf ("extern rtx gen_split_%d ();\n", last->insn_code_number); - - return head; -} - -/* Create a chain of nodes to verify that an rtl expression matches - PATTERN. - - LAST is a pointer to the listhead in the previous node in the chain (or - in the calling function, for the first node). - - POSITION is the string representing the current position in the insn. - - A pointer to the final node in the chain is returned. */ - -static struct decision * -add_to_sequence (pattern, last, position) - rtx pattern; - struct decision_head *last; - char *position; -{ - register RTX_CODE code; - register struct decision *new - = (struct decision *) xmalloc (sizeof (struct decision)); - struct decision *this; - char *newpos; - register char *fmt; - register int i; - int depth = strlen (position); - int len; - - if (depth > max_depth) - max_depth = depth; - - new->number = next_number++; - new->position = copystr (position); - new->ignore_code = 0; - new->ignore_mode = 0; - new->enforce_mode = 1; - new->retest_code = new->retest_mode = 0; - new->veclen = 0; - new->test_elt_zero_int = 0; - new->test_elt_one_int = 0; - new->test_elt_zero_wide = 0; - new->elt_zero_int = 0; - new->elt_one_int = 0; - new->elt_zero_wide = 0; - new->tests = 0; - new->pred = -1; - new->c_test = 0; - new->success.first = new->success.last = 0; - new->insn_code_number = -1; - new->num_clobbers_to_add = 0; - new->next = 0; - new->prev = 0; - new->afterward = 0; - new->opno = -1; - new->dupno = -1; - new->label_needed = 0; - new->subroutine_number = 0; - - this = new; - - last->first = last->last = new; - - newpos = (char *) alloca (depth + 2); - strcpy (newpos, position); - newpos[depth + 1] = 0; - - restart: - - new->mode = GET_MODE (pattern); - new->code = code = GET_CODE (pattern); - - switch (code) - { - case MATCH_OPERAND: - case MATCH_SCRATCH: - case MATCH_OPERATOR: - case MATCH_PARALLEL: - new->opno = XINT (pattern, 0); - new->code = (code == MATCH_PARALLEL ? PARALLEL : UNKNOWN); - new->enforce_mode = 0; - - if (code == MATCH_SCRATCH) - new->tests = "scratch_operand"; - else - new->tests = XSTR (pattern, 1); - - if (*new->tests == 0) - new->tests = 0; - - /* See if we know about this predicate and save its number. If we do, - and it only accepts one code, note that fact. The predicate - `const_int_operand' only tests for a CONST_INT, so if we do so we - can avoid calling it at all. - - Finally, if we know that the predicate does not allow CONST_INT, we - know that the only way the predicate can match is if the modes match - (here we use the kluge of relying on the fact that "address_operand" - accepts CONST_INT; otherwise, it would have to be a special case), - so we can test the mode (but we need not). This fact should - considerably simplify the generated code. */ - - if (new->tests) - for (i = 0; i < NUM_KNOWN_PREDS; i++) - if (! strcmp (preds[i].name, new->tests)) - { - int j; - int allows_const_int = 0; - - new->pred = i; - - if (preds[i].codes[1] == 0 && new->code == UNKNOWN) - { - new->code = preds[i].codes[0]; - if (! strcmp ("const_int_operand", new->tests)) - new->tests = 0, new->pred = -1; - } - - for (j = 0; j < NUM_RTX_CODE && preds[i].codes[j] != 0; j++) - if (preds[i].codes[j] == CONST_INT) - allows_const_int = 1; - - if (! allows_const_int) - new->enforce_mode = new->ignore_mode= 1; - - break; - } - - if (code == MATCH_OPERATOR || code == MATCH_PARALLEL) - { - for (i = 0; i < XVECLEN (pattern, 2); i++) - { - newpos[depth] = i + (code == MATCH_OPERATOR ? '0': 'a'); - new = add_to_sequence (XVECEXP (pattern, 2, i), - &new->success, newpos); - } - } - - return new; - - case MATCH_OP_DUP: - new->opno = XINT (pattern, 0); - new->dupno = XINT (pattern, 0); - new->code = UNKNOWN; - new->tests = 0; - for (i = 0; i < XVECLEN (pattern, 1); i++) - { - newpos[depth] = i + '0'; - new = add_to_sequence (XVECEXP (pattern, 1, i), - &new->success, newpos); - } - return new; - - case MATCH_DUP: - case MATCH_PAR_DUP: - new->dupno = XINT (pattern, 0); - new->code = UNKNOWN; - new->enforce_mode = 0; - return new; - - case ADDRESS: - pattern = XEXP (pattern, 0); - goto restart; - - case SET: - newpos[depth] = '0'; - new = add_to_sequence (SET_DEST (pattern), &new->success, newpos); - this->success.first->enforce_mode = 1; - newpos[depth] = '1'; - new = add_to_sequence (SET_SRC (pattern), &new->success, newpos); - - /* If set are setting CC0 from anything other than a COMPARE, we - must enforce the mode so that we do not produce ambiguous insns. */ - if (GET_CODE (SET_DEST (pattern)) == CC0 - && GET_CODE (SET_SRC (pattern)) != COMPARE) - this->success.first->enforce_mode = 1; - return new; - - case SIGN_EXTEND: - case ZERO_EXTEND: - case STRICT_LOW_PART: - newpos[depth] = '0'; - new = add_to_sequence (XEXP (pattern, 0), &new->success, newpos); - this->success.first->enforce_mode = 1; - return new; - - case SUBREG: - this->test_elt_one_int = 1; - this->elt_one_int = XINT (pattern, 1); - newpos[depth] = '0'; - new = add_to_sequence (XEXP (pattern, 0), &new->success, newpos); - this->success.first->enforce_mode = 1; - return new; - - case ZERO_EXTRACT: - case SIGN_EXTRACT: - newpos[depth] = '0'; - new = add_to_sequence (XEXP (pattern, 0), &new->success, newpos); - this->success.first->enforce_mode = 1; - newpos[depth] = '1'; - new = add_to_sequence (XEXP (pattern, 1), &new->success, newpos); - newpos[depth] = '2'; - new = add_to_sequence (XEXP (pattern, 2), &new->success, newpos); - return new; - - case EQ: case NE: case LE: case LT: case GE: case GT: - case LEU: case LTU: case GEU: case GTU: - /* If the first operand is (cc0), we don't have to do anything - special. */ - if (GET_CODE (XEXP (pattern, 0)) == CC0) - break; - - /* ... fall through ... */ - - case COMPARE: - /* Enforce the mode on the first operand to avoid ambiguous insns. */ - newpos[depth] = '0'; - new = add_to_sequence (XEXP (pattern, 0), &new->success, newpos); - this->success.first->enforce_mode = 1; - newpos[depth] = '1'; - new = add_to_sequence (XEXP (pattern, 1), &new->success, newpos); - return new; - } - - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - newpos[depth] = '0' + i; - if (fmt[i] == 'e' || fmt[i] == 'u') - new = add_to_sequence (XEXP (pattern, i), &new->success, newpos); - else if (fmt[i] == 'i' && i == 0) - { - this->test_elt_zero_int = 1; - this->elt_zero_int = XINT (pattern, i); - } - else if (fmt[i] == 'i' && i == 1) - { - this->test_elt_one_int = 1; - this->elt_one_int = XINT (pattern, i); - } - else if (fmt[i] == 'w' && i == 0) - { - this->test_elt_zero_wide = 1; - this->elt_zero_wide = XWINT (pattern, i); - } - else if (fmt[i] == 'E') - { - register int j; - /* We do not handle a vector appearing as other than - the first item, just because nothing uses them - and by handling only the special case - we can use one element in newpos for either - the item number of a subexpression - or the element number in a vector. */ - if (i != 0) - abort (); - this->veclen = XVECLEN (pattern, i); - for (j = 0; j < XVECLEN (pattern, i); j++) - { - newpos[depth] = 'a' + j; - new = add_to_sequence (XVECEXP (pattern, i, j), - &new->success, newpos); - } - } - else if (fmt[i] != '0') - abort (); - } - return new; -} - -/* Return 1 if we can prove that there is no RTL that can match both - D1 and D2. Otherwise, return 0 (it may be that there is an RTL that - can match both or just that we couldn't prove there wasn't such an RTL). - - TOPLEVEL is non-zero if we are to only look at the top level and not - recursively descend. */ - -static int -not_both_true (d1, d2, toplevel) - struct decision *d1, *d2; - int toplevel; -{ - struct decision *p1, *p2; - - /* If they are both to test modes and the modes are different, they aren't - both true. Similarly for codes, integer elements, and vector lengths. */ - - if ((d1->enforce_mode && d2->enforce_mode - && d1->mode != VOIDmode && d2->mode != VOIDmode && d1->mode != d2->mode) - || (d1->code != UNKNOWN && d2->code != UNKNOWN && d1->code != d2->code) - || (d1->test_elt_zero_int && d2->test_elt_zero_int - && d1->elt_zero_int != d2->elt_zero_int) - || (d1->test_elt_one_int && d2->test_elt_one_int - && d1->elt_one_int != d2->elt_one_int) - || (d1->test_elt_zero_wide && d2->test_elt_zero_wide - && d1->elt_zero_wide != d2->elt_zero_wide) - || (d1->veclen && d2->veclen && d1->veclen != d2->veclen)) - return 1; - - /* If either is a wild-card MATCH_OPERAND without a predicate, it can match - absolutely anything, so we can't say that no intersection is possible. - This case is detected by having a zero TESTS field with a code of - UNKNOWN. */ - - if ((d1->tests == 0 && d1->code == UNKNOWN) - || (d2->tests == 0 && d2->code == UNKNOWN)) - return 0; - - /* If either has a predicate that we know something about, set things up so - that D1 is the one that always has a known predicate. Then see if they - have any codes in common. */ - - if (d1->pred >= 0 || d2->pred >= 0) - { - int i, j; - - if (d2->pred >= 0) - p1 = d1, d1 = d2, d2 = p1; - - /* If D2 tests an explicit code, see if it is in the list of valid codes - for D1's predicate. */ - if (d2->code != UNKNOWN) - { - for (i = 0; i < NUM_RTX_CODE && preds[d1->pred].codes[i] != 0; i++) - if (preds[d1->pred].codes[i] == d2->code) - break; - - if (preds[d1->pred].codes[i] == 0) - return 1; - } - - /* Otherwise see if the predicates have any codes in common. */ - - else if (d2->pred >= 0) - { - for (i = 0; i < NUM_RTX_CODE && preds[d1->pred].codes[i] != 0; i++) - { - for (j = 0; j < NUM_RTX_CODE; j++) - if (preds[d2->pred].codes[j] == 0 - || preds[d2->pred].codes[j] == preds[d1->pred].codes[i]) - break; - - if (preds[d2->pred].codes[j] != 0) - break; - } - - if (preds[d1->pred].codes[i] == 0) - return 1; - } - } - - /* If we got here, we can't prove that D1 and D2 cannot both be true. - If we are only to check the top level, return 0. Otherwise, see if - we can prove that all choices in both successors are mutually - exclusive. If either does not have any successors, we can't prove - they can't both be true. */ - - if (toplevel || d1->success.first == 0 || d2->success.first == 0) - return 0; - - for (p1 = d1->success.first; p1; p1 = p1->next) - for (p2 = d2->success.first; p2; p2 = p2->next) - if (! not_both_true (p1, p2, 0)) - return 0; - - return 1; -} - -/* Assuming that we can reorder all the alternatives at a specific point in - the tree (see discussion in merge_trees), we would prefer an ordering of - nodes where groups of consecutive nodes test the same mode and, within each - mode, groups of nodes test the same code. With this order, we can - construct nested switch statements, the inner one to test the code and - the outer one to test the mode. - - We would like to list nodes testing for specific codes before those - that test predicates to avoid unnecessary function calls. Similarly, - tests for specific modes should precede nodes that allow any mode. - - This function returns the merit (with 0 being the best) of inserting - a test involving the specified MODE and CODE after node P. If P is - zero, we are to determine the merit of inserting the test at the front - of the list. */ - -static int -position_merit (p, mode, code) - struct decision *p; - enum machine_mode mode; - enum rtx_code code; -{ - enum machine_mode p_mode; - - /* The only time the front of the list is anything other than the worst - position is if we are testing a mode that isn't VOIDmode. */ - if (p == 0) - return mode == VOIDmode ? 3 : 2; - - p_mode = p->enforce_mode ? p->mode : VOIDmode; - - /* The best case is if the codes and modes both match. */ - if (p_mode == mode && p->code== code) - return 0; - - /* If the codes don't match, the next best case is if the modes match. - In that case, the best position for this node depends on whether - we are testing for a specific code or not. If we are, the best place - is after some other test for an explicit code and our mode or after - the last test in the previous mode if every test in our mode is for - an unknown code. - - If we are testing for UNKNOWN, then the next best case is at the end of - our mode. */ - - if ((code != UNKNOWN - && ((p_mode == mode && p->code != UNKNOWN) - || (p_mode != mode && p->next - && (p->next->enforce_mode ? p->next->mode : VOIDmode) == mode - && (p->next->code == UNKNOWN)))) - || (code == UNKNOWN && p_mode == mode - && (p->next == 0 - || (p->next->enforce_mode ? p->next->mode : VOIDmode) != mode))) - return 1; - - /* The third best case occurs when nothing is testing MODE. If MODE - is not VOIDmode, then the third best case is after something of any - mode that is not VOIDmode. If we are testing VOIDmode, the third best - place is the end of the list. */ - - if (p_mode != mode - && ((mode != VOIDmode && p_mode != VOIDmode) - || (mode == VOIDmode && p->next == 0))) - return 2; - - /* Otherwise, we have the worst case. */ - return 3; -} - -/* Merge two decision tree listheads OLDH and ADDH, - modifying OLDH destructively, and return the merged tree. */ - -static struct decision_head -merge_trees (oldh, addh) - register struct decision_head oldh, addh; -{ - struct decision *add, *next; - - if (oldh.first == 0) - return addh; - - if (addh.first == 0) - return oldh; - - /* If we are adding things at different positions, something is wrong. */ - if (strcmp (oldh.first->position, addh.first->position)) - abort (); - - for (add = addh.first; add; add = next) - { - enum machine_mode add_mode = add->enforce_mode ? add->mode : VOIDmode; - struct decision *best_position = 0; - int best_merit = 4; - struct decision *old; - - next = add->next; - - /* The semantics of pattern matching state that the tests are done in - the order given in the MD file so that if an insn matches two - patterns, the first one will be used. However, in practice, most, - if not all, patterns are unambiguous so that their order is - independent. In that case, we can merge identical tests and - group all similar modes and codes together. - - Scan starting from the end of OLDH until we reach a point - where we reach the head of the list or where we pass a pattern - that could also be true if NEW is true. If we find an identical - pattern, we can merge them. Also, record the last node that tests - the same code and mode and the last one that tests just the same mode. - - If we have no match, place NEW after the closest match we found. */ - - for (old = oldh.last; old; old = old->prev) - { - int our_merit; - - /* If we don't have anything to test except an additional test, - do not consider the two nodes equal. If we did, the test below - would cause an infinite recursion. */ - if (old->tests == 0 && old->test_elt_zero_int == 0 - && old->test_elt_one_int == 0 && old->veclen == 0 - && old->test_elt_zero_wide == 0 - && old->dupno == -1 && old->mode == VOIDmode - && old->code == UNKNOWN - && (old->c_test != 0 || add->c_test != 0)) - ; - - else if ((old->tests == add->tests - || (old->pred >= 0 && old->pred == add->pred) - || (old->tests && add->tests - && !strcmp (old->tests, add->tests))) - && old->test_elt_zero_int == add->test_elt_zero_int - && old->elt_zero_int == add->elt_zero_int - && old->test_elt_one_int == add->test_elt_one_int - && old->elt_one_int == add->elt_one_int - && old->test_elt_zero_wide == add->test_elt_zero_wide - && old->elt_zero_wide == add->elt_zero_wide - && old->veclen == add->veclen - && old->dupno == add->dupno - && old->opno == add->opno - && old->code == add->code - && old->enforce_mode == add->enforce_mode - && old->mode == add->mode) - { - /* If the additional test is not the same, split both nodes - into nodes that just contain all things tested before the - additional test and nodes that contain the additional test - and actions when it is true. This optimization is important - because of the case where we have almost identical patterns - with different tests on target flags. */ - - if (old->c_test != add->c_test - && ! (old->c_test && add->c_test - && !strcmp (old->c_test, add->c_test))) - { - if (old->insn_code_number >= 0 || old->opno >= 0) - { - struct decision *split - = (struct decision *) xmalloc (sizeof (struct decision)); - - mybcopy ((char *) old, (char *) split, - sizeof (struct decision)); - - old->success.first = old->success.last = split; - old->c_test = 0; - old->opno = -1; - old->insn_code_number = -1; - old->num_clobbers_to_add = 0; - - split->number = next_number++; - split->next = split->prev = 0; - split->mode = VOIDmode; - split->code = UNKNOWN; - split->veclen = 0; - split->test_elt_zero_int = 0; - split->test_elt_one_int = 0; - split->test_elt_zero_wide = 0; - split->tests = 0; - split->pred = -1; - split->dupno = -1; - } - - if (add->insn_code_number >= 0 || add->opno >= 0) - { - struct decision *split - = (struct decision *) xmalloc (sizeof (struct decision)); - - mybcopy ((char *) add, (char *) split, - sizeof (struct decision)); - - add->success.first = add->success.last = split; - add->c_test = 0; - add->opno = -1; - add->insn_code_number = -1; - add->num_clobbers_to_add = 0; - - split->number = next_number++; - split->next = split->prev = 0; - split->mode = VOIDmode; - split->code = UNKNOWN; - split->veclen = 0; - split->test_elt_zero_int = 0; - split->test_elt_one_int = 0; - split->test_elt_zero_wide = 0; - split->tests = 0; - split->pred = -1; - split->dupno = -1; - } - } - - if (old->insn_code_number >= 0 && add->insn_code_number >= 0) - { - /* If one node is for a normal insn and the second is - for the base insn with clobbers stripped off, the - second node should be ignored. */ - - if (old->num_clobbers_to_add == 0 - && add->num_clobbers_to_add > 0) - /* Nothing to do here. */ - ; - else if (old->num_clobbers_to_add > 0 - && add->num_clobbers_to_add == 0) - { - /* In this case, replace OLD with ADD. */ - old->insn_code_number = add->insn_code_number; - old->num_clobbers_to_add = 0; - } - else - fatal ("Two actions at one point in tree"); - } - - if (old->insn_code_number == -1) - old->insn_code_number = add->insn_code_number; - old->success = merge_trees (old->success, add->success); - add = 0; - break; - } - - /* Unless we have already found the best possible insert point, - see if this position is better. If so, record it. */ - - if (best_merit != 0 - && ((our_merit = position_merit (old, add_mode, add->code)) - < best_merit)) - best_merit = our_merit, best_position = old; - - if (! not_both_true (old, add, 0)) - break; - } - - /* If ADD was duplicate, we are done. */ - if (add == 0) - continue; - - /* Otherwise, find the best place to insert ADD. Normally this is - BEST_POSITION. However, if we went all the way to the top of - the list, it might be better to insert at the top. */ - - if (best_position == 0) - abort (); - - if (old == 0 - && position_merit (NULL_PTR, add_mode, add->code) < best_merit) - { - add->prev = 0; - add->next = oldh.first; - oldh.first->prev = add; - oldh.first = add; - } - - else - { - add->prev = best_position; - add->next = best_position->next; - best_position->next = add; - if (best_position == oldh.last) - oldh.last = add; - else - add->next->prev = add; - } - } - - return oldh; -} - -/* Count the number of subnodes of HEAD. If the number is high enough, - make the first node in HEAD start a separate subroutine in the C code - that is generated. - - TYPE gives the type of routine we are writing. - - INITIAL is non-zero if this is the highest-level node. We never write - it out here. */ - -static int -break_out_subroutines (head, type, initial) - struct decision_head head; - enum routine_type type; - int initial; -{ - int size = 0; - struct decision *node, *sub; - - for (sub = head.first; sub; sub = sub->next) - size += 1 + break_out_subroutines (sub->success, type, 0); - - if (size > SUBROUTINE_THRESHOLD && ! initial) - { - head.first->subroutine_number = ++next_subroutine_number; - write_subroutine (head.first, type); - size = 1; - } - return size; -} - -/* Write out a subroutine of type TYPE to do comparisons starting at node - TREE. */ - -static void -write_subroutine (tree, type) - struct decision *tree; - enum routine_type type; -{ - int i; - - if (type == SPLIT) - printf ("rtx\nsplit"); - else - printf ("int\nrecog"); - - if (tree != 0 && tree->subroutine_number > 0) - printf ("_%d", tree->subroutine_number); - else if (type == SPLIT) - printf ("_insns"); - - printf (" (x0, insn"); - if (type == RECOG) - printf (", pnum_clobbers"); - - printf (")\n"); - printf (" register rtx x0;\n rtx insn;\n"); - if (type == RECOG) - printf (" int *pnum_clobbers;\n"); - - printf ("{\n"); - printf (" register rtx *ro = &recog_operand[0];\n"); - - printf (" register rtx "); - for (i = 1; i < max_depth; i++) - printf ("x%d, ", i); - - printf ("x%d;\n", max_depth); - printf (" %s tem;\n", type == SPLIT ? "rtx" : "int"); - write_tree (tree, "", NULL_PTR, 1, type); - printf (" ret0: return %d;\n}\n\n", type == SPLIT ? 0 : -1); -} - -/* This table is used to indent the recog_* functions when we are inside - conditions or switch statements. We only support small indentations - and always indent at least two spaces. */ - -static char *indents[] - = {" ", " ", " ", " ", " ", " ", " ", " ", - "\t", "\t ", "\t ", "\t ", "\t ", "\t ", "\t ", - "\t\t", "\t\t ", "\t\t ", "\t\t ", "\t\t ", "\t\t "}; - -/* Write out C code to perform the decisions in TREE for a subroutine of - type TYPE. If all of the choices fail, branch to node AFTERWARD, if - non-zero, otherwise return. PREVPOS is the position of the node that - branched to this test. - - When we merged all alternatives, we tried to set up a convenient order. - Specifically, tests involving the same mode are all grouped together, - followed by a group that does not contain a mode test. Within each group - of the same mode, we also group tests with the same code, followed by a - group that does not test a code. - - Occasionally, we cannot arbitrarily reorder the tests so that multiple - sequence of groups as described above are present. - - We generate two nested switch statements, the outer statement for - testing modes, and the inner switch for testing RTX codes. It is - not worth optimizing cases when only a small number of modes or - codes is tested, since the compiler can do that when compiling the - resulting function. We do check for when every test is the same mode - or code. */ - -static void -write_tree_1 (tree, prevpos, afterward, type) - struct decision *tree; - char *prevpos; - struct decision *afterward; - enum routine_type type; -{ - register struct decision *p, *p1; - register int depth = tree ? strlen (tree->position) : 0; - enum machine_mode switch_mode = VOIDmode; - RTX_CODE switch_code = UNKNOWN; - int uncond = 0; - char modemap[NUM_MACHINE_MODES]; - char codemap[NUM_RTX_CODE]; - int indent = 2; - int i; - - /* One tricky area is what is the exact state when we branch to a - node's label. There are two cases where we branch: when looking at - successors to a node, or when a set of tests fails. - - In the former case, we are always branching to the first node in a - decision list and we want all required tests to be performed. We - put the labels for such nodes in front of any switch or test statements. - These branches are done without updating the position to that of the - target node. - - In the latter case, we are branching to a node that is not the first - node in a decision list. We have already checked that it is possible - for both the node we originally tested at this level and the node we - are branching to to be both match some pattern. That means that they - usually will be testing the same mode and code. So it is normally safe - for such labels to be inside switch statements, since the tests done - by virtue of arriving at that label will usually already have been - done. The exception is a branch from a node that does not test a - mode or code to one that does. In such cases, we set the `retest_mode' - or `retest_code' flags. That will ensure that we start a new switch - at that position and put the label before the switch. - - The branches in the latter case must set the position to that of the - target node. */ - - - printf ("\n"); - if (tree && tree->subroutine_number == 0) - { - printf (" L%d:\n", tree->number); - tree->label_needed = 0; - } - - if (tree) - { - change_state (prevpos, tree->position, 2); - prevpos = tree->position; - } - - for (p = tree; p; p = p->next) - { - enum machine_mode mode = p->enforce_mode ? p->mode : VOIDmode; - int need_bracket; - int wrote_bracket = 0; - int inner_indent; - - if (p->success.first == 0 && p->insn_code_number < 0) - abort (); - - /* Find the next alternative to p that might be true when p is true. - Test that one next if p's successors fail. */ - - for (p1 = p->next; p1 && not_both_true (p, p1, 1); p1 = p1->next) - ; - p->afterward = p1; - - if (p1) - { - if (mode == VOIDmode && p1->enforce_mode && p1->mode != VOIDmode) - p1->retest_mode = 1; - if (p->code == UNKNOWN && p1->code != UNKNOWN) - p1->retest_code = 1; - p1->label_needed = 1; - } - - /* If we have a different code or mode than the last node and - are in a switch on codes, we must either end the switch or - go to another case. We must also end the switch if this - node needs a label and to retest either the mode or code. */ - - if (switch_code != UNKNOWN - && (switch_code != p->code || switch_mode != mode - || (p->label_needed && (p->retest_mode || p->retest_code)))) - { - enum rtx_code code = p->code; - - /* If P is testing a predicate that we know about and we haven't - seen any of the codes that are valid for the predicate, we - can write a series of "case" statement, one for each possible - code. Since we are already in a switch, these redundant tests - are very cheap and will reduce the number of predicate called. */ - - if (p->pred >= 0) - { - for (i = 0; i < NUM_RTX_CODE && preds[p->pred].codes[i] != 0; i++) - if (codemap[(int) preds[p->pred].codes[i]]) - break; - - if (preds[p->pred].codes[i] == 0) - code = MATCH_OPERAND; - } - - if (code == UNKNOWN || codemap[(int) code] - || switch_mode != mode - || (p->label_needed && (p->retest_mode || p->retest_code))) - { - printf ("%s}\n", indents[indent - 2]); - switch_code = UNKNOWN; - indent -= 4; - } - else - { - if (! uncond) - printf ("%sbreak;\n", indents[indent]); - - if (code == MATCH_OPERAND) - { - for (i = 0; i < NUM_RTX_CODE && preds[p->pred].codes[i] != 0; i++) - { - printf ("%scase ", indents[indent - 2]); - print_code (preds[p->pred].codes[i]); - printf (":\n"); - codemap[(int) preds[p->pred].codes[i]] = 1; - } - } - else - { - printf ("%scase ", indents[indent - 2]); - print_code (code); - printf (":\n"); - codemap[(int) p->code] = 1; - } - - switch_code = code; - } - - uncond = 0; - } - - /* If we were previously in a switch on modes and now have a different - mode, end at least the case, and maybe end the switch if we are - not testing a mode or testing a mode whose case we already saw. */ - - if (switch_mode != VOIDmode - && (switch_mode != mode || (p->label_needed && p->retest_mode))) - { - if (mode == VOIDmode || modemap[(int) mode] - || (p->label_needed && p->retest_mode)) - { - printf ("%s}\n", indents[indent - 2]); - switch_mode = VOIDmode; - indent -= 4; - } - else - { - if (! uncond) - printf (" break;\n"); - printf (" case %smode:\n", GET_MODE_NAME (mode)); - switch_mode = mode; - modemap[(int) mode] = 1; - } - - uncond = 0; - } - - /* If we are about to write dead code, something went wrong. */ - if (! p->label_needed && uncond) - abort (); - - /* If we need a label and we will want to retest the mode or code at - that label, write the label now. We have already ensured that - things will be valid for the test. */ - - if (p->label_needed && (p->retest_mode || p->retest_code)) - { - printf ("%sL%d:\n", indents[indent - 2], p->number); - p->label_needed = 0; - } - - uncond = 0; - - /* If we are not in any switches, see if we can shortcut things - by checking for identical modes and codes. */ - - if (switch_mode == VOIDmode && switch_code == UNKNOWN) - { - /* If p and its alternatives all want the same mode, - reject all others at once, first, then ignore the mode. */ - - if (mode != VOIDmode && p->next && same_modes (p, mode)) - { - printf (" if (GET_MODE (x%d) != %smode)\n", - depth, GET_MODE_NAME (p->mode)); - if (afterward) - { - printf (" {\n"); - change_state (p->position, afterward->position, 6); - printf (" goto L%d;\n }\n", afterward->number); - } - else - printf (" goto ret0;\n"); - clear_modes (p); - mode = VOIDmode; - } - - /* If p and its alternatives all want the same code, - reject all others at once, first, then ignore the code. */ - - if (p->code != UNKNOWN && p->next && same_codes (p, p->code)) - { - printf (" if (GET_CODE (x%d) != ", depth); - print_code (p->code); - printf (")\n"); - if (afterward) - { - printf (" {\n"); - change_state (p->position, afterward->position, indent + 4); - printf (" goto L%d;\n }\n", afterward->number); - } - else - printf (" goto ret0;\n"); - clear_codes (p); - } - } - - /* If we are not in a mode switch and we are testing for a specific - mode, start a mode switch unless we have just one node or the next - node is not testing a mode (we have already tested for the case of - more than one mode, but all of the same mode). */ - - if (switch_mode == VOIDmode && mode != VOIDmode && p->next != 0 - && p->next->enforce_mode && p->next->mode != VOIDmode) - { - mybzero (modemap, sizeof modemap); - printf ("%sswitch (GET_MODE (x%d))\n", indents[indent], depth); - printf ("%s{\n", indents[indent + 2]); - indent += 4; - printf ("%scase %smode:\n", indents[indent - 2], - GET_MODE_NAME (mode)); - modemap[(int) mode] = 1; - switch_mode = mode; - } - - /* Similarly for testing codes. */ - - if (switch_code == UNKNOWN && p->code != UNKNOWN && ! p->ignore_code - && p->next != 0 && p->next->code != UNKNOWN) - { - mybzero (codemap, sizeof codemap); - printf ("%sswitch (GET_CODE (x%d))\n", indents[indent], depth); - printf ("%s{\n", indents[indent + 2]); - indent += 4; - printf ("%scase ", indents[indent - 2]); - print_code (p->code); - printf (":\n"); - codemap[(int) p->code] = 1; - switch_code = p->code; - } - - /* Now that most mode and code tests have been done, we can write out - a label for an inner node, if we haven't already. */ - if (p->label_needed) - printf ("%sL%d:\n", indents[indent - 2], p->number); - - inner_indent = indent; - - /* The only way we can have to do a mode or code test here is if - this node needs such a test but is the only node to be tested. - In that case, we won't have started a switch. Note that this is - the only way the switch and test modes can disagree. */ - - if ((mode != switch_mode && ! p->ignore_mode) - || (p->code != switch_code && p->code != UNKNOWN && ! p->ignore_code) - || p->test_elt_zero_int || p->test_elt_one_int - || p->test_elt_zero_wide || p->veclen - || p->dupno >= 0 || p->tests || p->num_clobbers_to_add) - { - printf ("%sif (", indents[indent]); - - if (mode != switch_mode && ! p->ignore_mode) - printf ("GET_MODE (x%d) == %smode && ", - depth, GET_MODE_NAME (mode)); - if (p->code != switch_code && p->code != UNKNOWN && ! p->ignore_code) - { - printf ("GET_CODE (x%d) == ", depth); - print_code (p->code); - printf (" && "); - } - - if (p->test_elt_zero_int) - printf ("XINT (x%d, 0) == %d && ", depth, p->elt_zero_int); - if (p->test_elt_one_int) - printf ("XINT (x%d, 1) == %d && ", depth, p->elt_one_int); - if (p->test_elt_zero_wide) - printf ( -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - "XWINT (x%d, 0) == %d && ", -#else - "XWINT (x%d, 0) == %ld && ", -#endif - depth, p->elt_zero_wide); - if (p->veclen) - printf ("XVECLEN (x%d, 0) == %d && ", depth, p->veclen); - if (p->dupno >= 0) - printf ("rtx_equal_p (x%d, ro[%d]) && ", depth, p->dupno); - if (p->num_clobbers_to_add) - printf ("pnum_clobbers != 0 && "); - if (p->tests) - printf ("%s (x%d, %smode)", p->tests, depth, - GET_MODE_NAME (p->mode)); - else - printf ("1"); - - printf (")\n"); - inner_indent += 2; - } - else - uncond = 1; - - need_bracket = ! uncond; - - if (p->opno >= 0) - { - if (need_bracket) - { - printf ("%s{\n", indents[inner_indent]); - inner_indent += 2; - wrote_bracket = 1; - need_bracket = 0; - } - - printf ("%sro[%d] = x%d;\n", indents[inner_indent], p->opno, depth); - } - - if (p->c_test) - { - printf ("%sif (%s)\n", indents[inner_indent], p->c_test); - inner_indent += 2; - uncond = 0; - need_bracket = 1; - } - - if (p->insn_code_number >= 0) - { - if (type == SPLIT) - printf ("%sreturn gen_split_%d (operands);\n", - indents[inner_indent], p->insn_code_number); - else - { - if (p->num_clobbers_to_add) - { - if (need_bracket) - { - printf ("%s{\n", indents[inner_indent]); - inner_indent += 2; - } - - printf ("%s*pnum_clobbers = %d;\n", - indents[inner_indent], p->num_clobbers_to_add); - printf ("%sreturn %d;\n", - indents[inner_indent], p->insn_code_number); - - if (need_bracket) - { - inner_indent -= 2; - printf ("%s}\n", indents[inner_indent]); - } - } - else - printf ("%sreturn %d;\n", - indents[inner_indent], p->insn_code_number); - } - } - else - printf ("%sgoto L%d;\n", indents[inner_indent], - p->success.first->number); - - if (wrote_bracket) - printf ("%s}\n", indents[inner_indent - 2]); - } - - /* We have now tested all alternatives. End any switches we have open - and branch to the alternative node unless we know that we can't fall - through to the branch. */ - - if (switch_code != UNKNOWN) - { - printf ("%s}\n", indents[indent - 2]); - indent -= 4; - uncond = 0; - } - - if (switch_mode != VOIDmode) - { - printf ("%s}\n", indents[indent - 2]); - indent -= 4; - uncond = 0; - } - - if (indent != 2) - abort (); - - if (uncond) - return; - - if (afterward) - { - change_state (prevpos, afterward->position, 2); - printf (" goto L%d;\n", afterward->number); - } - else - printf (" goto ret0;\n"); -} - -static void -print_code (code) - enum rtx_code code; -{ - register char *p1; - for (p1 = GET_RTX_NAME (code); *p1; p1++) - { - if (*p1 >= 'a' && *p1 <= 'z') - putchar (*p1 + 'A' - 'a'); - else - putchar (*p1); - } -} - -static int -same_codes (p, code) - register struct decision *p; - register enum rtx_code code; -{ - for (; p; p = p->next) - if (p->code != code) - return 0; - - return 1; -} - -static void -clear_codes (p) - register struct decision *p; -{ - for (; p; p = p->next) - p->ignore_code = 1; -} - -static int -same_modes (p, mode) - register struct decision *p; - register enum machine_mode mode; -{ - for (; p; p = p->next) - if ((p->enforce_mode ? p->mode : VOIDmode) != mode) - return 0; - - return 1; -} - -static void -clear_modes (p) - register struct decision *p; -{ - for (; p; p = p->next) - p->enforce_mode = 0; -} - -/* Write out the decision tree starting at TREE for a subroutine of type TYPE. - - PREVPOS is the position at the node that branched to this node. - - INITIAL is nonzero if this is the first node we are writing in a subroutine. - - If all nodes are false, branch to the node AFTERWARD. */ - -static void -write_tree (tree, prevpos, afterward, initial, type) - struct decision *tree; - char *prevpos; - struct decision *afterward; - int initial; - enum routine_type type; -{ - register struct decision *p; - char *name_prefix = (type == SPLIT ? "split" : "recog"); - char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers"); - - if (! initial && tree->subroutine_number > 0) - { - printf (" L%d:\n", tree->number); - - if (afterward) - { - printf (" tem = %s_%d (x0, insn%s);\n", - name_prefix, tree->subroutine_number, call_suffix); - if (type == SPLIT) - printf (" if (tem != 0) return tem;\n"); - else - printf (" if (tem >= 0) return tem;\n"); - change_state (tree->position, afterward->position, 2); - printf (" goto L%d;\n", afterward->number); - } - else - printf (" return %s_%d (x0, insn%s);\n", - name_prefix, tree->subroutine_number, call_suffix); - return; - } - - write_tree_1 (tree, prevpos, afterward, type); - - for (p = tree; p; p = p->next) - if (p->success.first) - write_tree (p->success.first, p->position, - p->afterward ? p->afterward : afterward, 0, type); -} - - -/* Assuming that the state of argument is denoted by OLDPOS, take whatever - actions are necessary to move to NEWPOS. - - INDENT says how many blanks to place at the front of lines. */ - -static void -change_state (oldpos, newpos, indent) - char *oldpos; - char *newpos; - int indent; -{ - int odepth = strlen (oldpos); - int depth = odepth; - int ndepth = strlen (newpos); - - /* Pop up as many levels as necessary. */ - - while (strncmp (oldpos, newpos, depth)) - --depth; - - /* Go down to desired level. */ - - while (depth < ndepth) - { - if (newpos[depth] >= 'a' && newpos[depth] <= 'z') - printf ("%sx%d = XVECEXP (x%d, 0, %d);\n", - indents[indent], depth + 1, depth, newpos[depth] - 'a'); - else - printf ("%sx%d = XEXP (x%d, %c);\n", - indents[indent], depth + 1, depth, newpos[depth]); - ++depth; - } -} - -static char * -copystr (s1) - char *s1; -{ - register char *tem; - - if (s1 == 0) - return 0; - - tem = (char *) xmalloc (strlen (s1) + 1); - strcpy (tem, s1); - - return tem; -} - -static void -mybzero (b, length) - register char *b; - register unsigned length; -{ - while (length-- > 0) - *b++ = 0; -} - -static void -mybcopy (in, out, length) - register char *in, *out; - register unsigned length; -{ - while (length-- > 0) - *out++ = *in++; -} - -static char * -concat (s1, s2) - char *s1, *s2; -{ - register char *tem; - - if (s1 == 0) - return s2; - if (s2 == 0) - return s1; - - tem = (char *) xmalloc (strlen (s1) + strlen (s2) + 2); - strcpy (tem, s1); - strcat (tem, " "); - strcat (tem, s2); - - return tem; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - char *result = (char *) realloc (ptr, size); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -char * -xmalloc (size) - unsigned size; -{ - register char *val = (char *) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - return val; -} - -static void -fatal (s) - char *s; -{ - fprintf (stderr, "genrecog: "); - fprintf (stderr, s); - fprintf (stderr, "\n"); - fprintf (stderr, "after %d definitions\n", next_index); - exit (FATAL_EXIT_CODE); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - rtx desc; - struct decision_head recog_tree; - struct decision_head split_tree; - FILE *infile; - register int c; - - obstack_init (rtl_obstack); - recog_tree.first = recog_tree.last = split_tree.first = split_tree.last = 0; - - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } - - init_rtl (); - next_insn_code = 0; - next_index = 0; - - printf ("/* Generated automatically by the program `genrecog'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#include \"config.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"insn-config.h\"\n"); - printf ("#include \"recog.h\"\n"); - printf ("#include \"real.h\"\n"); - printf ("#include \"output.h\"\n"); - printf ("#include \"flags.h\"\n"); - printf ("\n"); - - /* Read the machine description. */ - - while (1) - { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - recog_tree = merge_trees (recog_tree, - make_insn_sequence (desc, RECOG)); - else if (GET_CODE (desc) == DEFINE_SPLIT) - split_tree = merge_trees (split_tree, - make_insn_sequence (desc, SPLIT)); - if (GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_EXPAND) - next_insn_code++; - next_index++; - } - - printf ("\n\ -/* `recog' contains a decision tree\n\ - that recognizes whether the rtx X0 is a valid instruction.\n\ -\n\ - recog returns -1 if the rtx is not valid.\n\ - If the rtx is valid, recog returns a nonnegative number\n\ - which is the insn code number for the pattern that matched.\n"); - printf (" This is the same as the order in the machine description of\n\ - the entry that matched. This number can be used as an index into\n\ - entry that matched. This number can be used as an index into various\n\ - insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands\n\ - (found in insn-output.c).\n\n"); - printf (" The third argument to recog is an optional pointer to an int.\n\ - If present, recog will accept a pattern if it matches except for\n\ - missing CLOBBER expressions at the end. In that case, the value\n\ - pointed to by the optional pointer will be set to the number of\n\ - CLOBBERs that need to be added (it should be initialized to zero by\n\ - the caller). If it is set nonzero, the caller should allocate a\n\ - PARALLEL of the appropriate size, copy the initial entries, and call\n\ - add_clobbers (found in insn-emit.c) to fill in the CLOBBERs."); - - if (split_tree.first) - printf ("\n\n The function split_insns returns 0 if the rtl could not\n\ - be split or the split rtl in a SEQUENCE if it can be."); - - printf ("*/\n\n"); - - printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n"); - printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n"); - printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n"); - printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n"); - printf ("#define operands recog_operand\n\n"); - - next_subroutine_number = 0; - break_out_subroutines (recog_tree, RECOG, 1); - write_subroutine (recog_tree.first, RECOG); - - next_subroutine_number = 0; - break_out_subroutines (split_tree, SPLIT, 1); - write_subroutine (split_tree.first, SPLIT); - - fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/m68k/Makefile b/gnu/usr.bin/gcc2/arch/m68k/Makefile deleted file mode 100644 index b1143647ca2..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:19 deraadt Exp $ - -.include diff --git a/gnu/usr.bin/gcc2/arch/m68k/aux-output.c b/gnu/usr.bin/gcc2/arch/m68k/aux-output.c deleted file mode 100644 index 9a88e67809f..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/aux-output.c +++ /dev/null @@ -1,2243 +0,0 @@ -/* Subroutines for insn-output.c for Motorola 68000 family. - Copyright (C) 1987, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: aux-output.c,v 1.1.1.1 1995/10/18 08:39:19 deraadt Exp $"; -#endif /* not lint */ - -/* Some output-actions in m68k.md need these. */ -#include -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" - -/* Needed for use_return_insn. */ -#include "flags.h" - -#ifdef SUPPORT_SUN_FPA - -/* Index into this array by (register number >> 3) to find the - smallest class which contains that register. */ -enum reg_class regno_reg_class[] - = { DATA_REGS, ADDR_REGS, FP_REGS, - LO_FPA_REGS, LO_FPA_REGS, FPA_REGS, FPA_REGS }; - -#endif /* defined SUPPORT_SUN_FPA */ - -/* This flag is used to communicate between movhi and ASM_OUTPUT_CASE_END, - if SGS_SWITCH_TABLE. */ -int switch_table_difference_label_flag; - -static rtx find_addr_reg (); -rtx legitimize_pic_address (); - - -/* This function generates the assembly code for function entry. - STREAM is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This function is responsible for - knowing which registers should not be saved even if used. */ - - -/* Note that the order of the bit mask for fmovem is the opposite - of the order for movem! */ - - -void -output_function_prologue (stream, size) - FILE *stream; - int size; -{ - register int regno; - register int mask = 0; - int num_saved_regs = 0; - extern char call_used_regs[]; - int fsize = (size + 3) & -4; - - - if (frame_pointer_needed) - { - /* Adding negative number is faster on the 68040. */ - if (fsize < 0x8000 && !TARGET_68040) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tlink.w %s,%0I%d\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#else - asm_fprintf (stream, "\tlink %s,%0I%d\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#endif - } - else if (TARGET_68020) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tlink.l %s,%0I%d\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#else - asm_fprintf (stream, "\tlink %s,%0I%d\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tlink.w %s,%0I0\n\tadd.l %0I%d,%Rsp\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#else - asm_fprintf (stream, "\tlink %s,%0I0\n\taddl %0I%d,%Rsp\n", - reg_names[FRAME_POINTER_REGNUM], -fsize); -#endif - } - } - else if (fsize) - { - /* Adding negative number is faster on the 68040. */ - if (fsize + 4 < 0x8000) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", - (fsize + 4)); -#else - asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", - (fsize + 4)); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", - (fsize + 4)); -#else - asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", - (fsize + 4)); -#endif - } - } -#ifdef SUPPORT_SUN_FPA - for (regno = 24; regno < 56; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n", - reg_names[regno]); -#else - asm_fprintf (stream, "\tfpmoved %s,%Rsp@-\n", - reg_names[regno]); -#endif - } -#endif - for (regno = 16; regno < 24; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - mask |= 1 << (regno - 16); - if ((mask & 0xff) != 0) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfmovm %0I0x%x,-(%Rsp)\n", mask & 0xff); -#else - asm_fprintf (stream, "\tfmovem %0I0x%x,%Rsp@-\n", mask & 0xff); -#endif - } - mask = 0; - for (regno = 0; regno < 16; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - { - mask |= 1 << (15 - regno); - num_saved_regs++; - } - if (frame_pointer_needed) - { - mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM)); - num_saved_regs--; - } - -#if NEED_PROBE - fprintf (stream, "\ttstl sp@(%d)\n", NEED_PROBE - num_saved_regs * 4); -#endif - - if (num_saved_regs <= 2) - { - /* Store each separately in the same order moveml uses. - Using two movel instructions instead of a single moveml - is about 15% faster for the 68020 and 68030 at no expense - in code size */ - - int i; - - /* Undo the work from above. */ - for (i = 0; i< 16; i++) - if (mask & (1 << i)) - asm_fprintf (stream, -#ifdef MOTOROLA - "\t%Omove.l %s,-(%Rsp)\n", -#else - "\tmovel %s,%Rsp@-\n", -#endif - reg_names[15 - i]); - } - else if (mask) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tmovm.l %0I0x%x,-(%Rsp)\n", mask); -#else - asm_fprintf (stream, "\tmoveml %0I0x%x,%Rsp@-\n", mask); -#endif - } - if (flag_pic && current_function_uses_pic_offset_table) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM]); -#else - asm_fprintf (stream, "\tmovel %0I__GLOBAL_OFFSET_TABLE_, %s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM]); - asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM], - reg_names[PIC_OFFSET_TABLE_REGNUM]); -#endif - } -} - -/* Return true if this function's epilogue can be output as RTL. */ - -int -use_return_insn () -{ - int regno; - - if (!reload_completed || frame_pointer_needed || get_frame_size () != 0) - return 0; - - /* Copied from output_function_epilogue (). We should probably create a - separate layout routine to perform the common work. */ - - for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - return 0; - - return 1; -} - -/* This function generates the assembly code for function exit, - on machines that need it. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer! - It should use the frame pointer only, if there is a frame pointer. - This is mandatory because of alloca; we also take advantage of it to - omit stack adjustments before returning. */ - -void -output_function_epilogue (stream, size) - FILE *stream; - int size; -{ - register int regno; - register int mask, fmask; - register int nregs; - int offset, foffset, fpoffset; - extern char call_used_regs[]; - int fsize = (size + 3) & -4; - int big = 0; - rtx insn = get_last_insn (); - - /* If the last insn was a BARRIER, we don't have to write any code. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn && GET_CODE (insn) == BARRIER) - { - /* Output just a no-op so that debuggers don't get confused - about which function the pc is in at this address. */ - asm_fprintf (stream, "\tnop\n"); - return; - } - -#ifdef FUNCTION_EXTRA_EPILOGUE - FUNCTION_EXTRA_EPILOGUE (stream, size); -#endif - nregs = 0; fmask = 0; fpoffset = 0; -#ifdef SUPPORT_SUN_FPA - for (regno = 24 ; regno < 56 ; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - nregs++; - fpoffset = nregs * 8; -#endif - nregs = 0; - for (regno = 16; regno < 24; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - { - nregs++; - fmask |= 1 << (23 - regno); - } - foffset = fpoffset + nregs * 12; - nregs = 0; mask = 0; - if (frame_pointer_needed) - regs_ever_live[FRAME_POINTER_REGNUM] = 0; - for (regno = 0; regno < 16; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - { - nregs++; - mask |= 1 << regno; - } - offset = foffset + nregs * 4; - if (offset + fsize >= 0x8000 - && frame_pointer_needed - && (mask || fmask || fpoffset)) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l %0I%d,%Ra0\n", -fsize); -#else - asm_fprintf (stream, "\tmovel %0I%d,%Ra0\n", -fsize); -#endif - fsize = 0, big = 1; - } - if (nregs <= 2) - { - /* Restore each separately in the same order moveml does. - Using two movel instructions instead of a single moveml - is about 15% faster for the 68020 and 68030 at no expense - in code size. */ - - int i; - - /* Undo the work from above. */ - for (i = 0; i< 16; i++) - if (mask & (1 << i)) - { - if (big) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l -%d(%s,%Ra0.l),%s\n", - offset + fsize, - reg_names[FRAME_POINTER_REGNUM], - reg_names[i]); -#else - asm_fprintf (stream, "\tmovel %s@(-%d,%Ra0:l),%s\n", - reg_names[FRAME_POINTER_REGNUM], - offset + fsize, reg_names[i]); -#endif - } - else if (! frame_pointer_needed) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l (%Rsp)+,%s\n", - reg_names[i]); -#else - asm_fprintf (stream, "\tmovel %Rsp@+,%s\n", - reg_names[i]); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\t%Omove.l -%d(%s),%s\n", - offset + fsize, - reg_names[FRAME_POINTER_REGNUM], - reg_names[i]); -#else - asm_fprintf (stream, "\tmovel %s@(-%d),%s\n", - reg_names[FRAME_POINTER_REGNUM], - offset + fsize, reg_names[i]); -#endif - } - offset = offset - 4; - } - } - else if (mask) - { - if (big) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tmovm.l -%d(%s,%Ra0.l),%0I0x%x\n", - offset + fsize, - reg_names[FRAME_POINTER_REGNUM], - mask); -#else - asm_fprintf (stream, "\tmoveml %s@(-%d,%Ra0:l),%0I0x%x\n", - reg_names[FRAME_POINTER_REGNUM], - offset + fsize, mask); -#endif - } - else if (! frame_pointer_needed) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask); -#else - asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n", - offset + fsize, - reg_names[FRAME_POINTER_REGNUM], - mask); -#else - asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n", - reg_names[FRAME_POINTER_REGNUM], - offset + fsize, mask); -#endif - } - } - if (fmask) - { - if (big) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfmovm -%d(%s,%Ra0.l),%0I0x%x\n", - foffset + fsize, - reg_names[FRAME_POINTER_REGNUM], - fmask); -#else - asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra0:l),%0I0x%x\n", - reg_names[FRAME_POINTER_REGNUM], - foffset + fsize, fmask); -#endif - } - else if (! frame_pointer_needed) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask); -#else - asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n", - foffset + fsize, - reg_names[FRAME_POINTER_REGNUM], - fmask); -#else - asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n", - reg_names[FRAME_POINTER_REGNUM], - foffset + fsize, fmask); -#endif - } - } - if (fpoffset != 0) - for (regno = 55; regno >= 24; regno--) - if (regs_ever_live[regno] && ! call_used_regs[regno]) - { - if (big) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra0.l), %s\n", - fpoffset + fsize, - reg_names[FRAME_POINTER_REGNUM], - reg_names[regno]); -#else - asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra0:l), %s\n", - reg_names[FRAME_POINTER_REGNUM], - fpoffset + fsize, reg_names[regno]); -#endif - } - else if (! frame_pointer_needed) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n", - reg_names[regno]); -#else - asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n", - reg_names[regno]); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tfpmovd -%d(%s), %s\n", - fpoffset + fsize, - reg_names[FRAME_POINTER_REGNUM], - reg_names[regno]); -#else - asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n", - reg_names[FRAME_POINTER_REGNUM], - fpoffset + fsize, reg_names[regno]); -#endif - } - fpoffset -= 8; - } - if (frame_pointer_needed) - fprintf (stream, "\tunlk %s\n", - reg_names[FRAME_POINTER_REGNUM]); - else if (fsize) - { - if (fsize + 4 < 0x8000) - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4); -#else - asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4); -#endif - } - else - { -#ifdef MOTOROLA - asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4); -#else - asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4); -#endif - } - } - if (current_function_pops_args) - asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args); - else - fprintf (stream, "\trts\n"); -} - -/* Similar to general_operand, but exclude stack_pointer_rtx. */ - -int -not_sp_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return op != stack_pointer_rtx && general_operand (op, mode); -} - -/* Return TRUE if X is a valid comparison operator for the dbcc - instruction. - - Note it rejects floating point comparison operators. - (In the future we could use Fdbcc). - - It also rejects some comparisons when CC_NO_OVERFLOW is set. */ - -int -valid_dbcc_comparison_p (x, mode) - rtx x; - enum machine_mode mode; -{ - /* We could add support for these in the future */ - if (cc_prev_status.flags & CC_IN_68881) - return 0; - - switch (GET_CODE (x)) - { - - case EQ: case NE: case GTU: case LTU: - case GEU: case LEU: - return 1; - - /* Reject some when CC_NO_OVERFLOW is set. This may be over - conservative */ - case GT: case LT: case GE: case LE: - return ! (cc_prev_status.flags & CC_NO_OVERFLOW); - default: - return 0; - } -} - -/* Output a dbCC; jCC sequence. Note we do not handle the - floating point version of this sequence (Fdbcc). We also - do not handle alternative conditions when CC_NO_OVERFLOW is - set. It is assumed that valid_dbcc_comparison_p will kick - those out before we get here. */ - -output_dbcc_and_branch (operands) - rtx *operands; -{ - - switch (GET_CODE (operands[3])) - { - case EQ: -#ifdef MOTOROLA - output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands); -#else - output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands); -#endif - break; - - case NE: -#ifdef MOTOROLA - output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands); -#else - output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands); -#endif - break; - - case GT: -#ifdef MOTOROLA - output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands); -#else - output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands); -#endif - break; - - case GTU: -#ifdef MOTOROLA - output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands); -#else - output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands); -#endif - break; - - case LT: -#ifdef MOTOROLA - output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands); -#else - output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands); -#endif - break; - - case LTU: -#ifdef MOTOROLA - output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands); -#else - output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands); -#endif - break; - - case GE: -#ifdef MOTOROLA - output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands); -#else - output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands); -#endif - break; - - case GEU: -#ifdef MOTOROLA - output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands); -#else - output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands); -#endif - break; - - case LE: -#ifdef MOTOROLA - output_asm_insn ("dble %0,%l1\n\tjble %l2", operands); -#else - output_asm_insn ("dble %0,%l1\n\tjle %l2", operands); -#endif - break; - - case LEU: -#ifdef MOTOROLA - output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands); -#else - output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands); -#endif - break; - - default: - abort (); - } - - /* If the decrement is to be done in SImode, then we have - to compensate for the fact that dbcc decrements in HImode. */ - switch (GET_MODE (operands[0])) - { - case SImode: -#ifdef MOTOROLA - output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands); -#else - output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands); -#endif - break; - - case HImode: - break; - - default: - abort (); - } -} - -char * -output_btst (operands, countop, dataop, insn, signpos) - rtx *operands; - rtx countop, dataop; - rtx insn; - int signpos; -{ - operands[0] = countop; - operands[1] = dataop; - - if (GET_CODE (countop) == CONST_INT) - { - register int count = INTVAL (countop); - /* If COUNT is bigger than size of storage unit in use, - advance to the containing unit of same size. */ - if (count > signpos) - { - int offset = (count & ~signpos) / 8; - count = count & signpos; - operands[1] = dataop = adj_offsettable_operand (dataop, offset); - } - if (count == signpos) - cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N; - else - cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N; - - /* These three statements used to use next_insns_test_no... - but it appears that this should do the same job. */ - if (count == 31 - && next_insn_tests_no_inequality (insn)) - return "tst%.l %1"; - if (count == 15 - && next_insn_tests_no_inequality (insn)) - return "tst%.w %1"; - if (count == 7 - && next_insn_tests_no_inequality (insn)) - return "tst%.b %1"; - - cc_status.flags = CC_NOT_NEGATIVE; - } - return "btst %0,%1"; -} - -/* Returns 1 if OP is either a symbol reference or a sum of a symbol - reference and a constant. */ - -int -symbolic_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - switch (GET_CODE (op)) - { - case SYMBOL_REF: - case LABEL_REF: - return 1; - - case CONST: - op = XEXP (op, 0); - return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF) - && GET_CODE (XEXP (op, 1)) == CONST_INT); - -#if 0 /* Deleted, with corresponding change in m68k.h, - so as to fit the specs. No CONST_DOUBLE is ever symbolic. */ - case CONST_DOUBLE: - return GET_MODE (op) == mode; -#endif - - default: - return 0; - } -} - - -/* Legitimize PIC addresses. If the address is already - position-independent, we return ORIG. Newly generated - position-independent addresses go to REG. If we need more - than one register, we lose. - - An address is legitimized by making an indirect reference - through the Global Offset Table with the name of the symbol - used as an offset. - - The assembler and linker are responsible for placing the - address of the symbol in the GOT. The function prologue - is responsible for initializing a5 to the starting address - of the GOT. - - The assembler is also responsible for translating a symbol name - into a constant displacement from the start of the GOT. - - A quick example may make things a little clearer: - - When not generating PIC code to store the value 12345 into _foo - we would generate the following code: - - movel #12345, _foo - - When generating PIC two transformations are made. First, the compiler - loads the address of foo into a register. So the first transformation makes: - - lea _foo, a0 - movel #12345, a0@ - - The code in movsi will intercept the lea instruction and call this - routine which will transform the instructions into: - - movel a5@(_foo:w), a0 - movel #12345, a0@ - - - That (in a nutshell) is how *all* symbol and label references are - handled. */ - -rtx -legitimize_pic_address (orig, mode, reg) - rtx orig, reg; - enum machine_mode mode; -{ - rtx pic_ref = orig; - - /* First handle a simple SYMBOL_REF or LABEL_REF */ - if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF) - { - if (reg == 0) - abort (); - - pic_ref = gen_rtx (MEM, Pmode, - gen_rtx (PLUS, Pmode, - pic_offset_table_rtx, orig)); - - /* We could have a function which didn't use the GOT after RTL - generation, but because of some action from a later pass - (reload in particular) uses the GOT now. So emit both a USE - insn and set regs_ever_live for the GOT register. */ - - current_function_uses_pic_offset_table = 1; - emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); - regs_ever_live[REGNO (pic_offset_table_rtx)] = 1; - RTX_UNCHANGING_P (pic_ref) = 1; - emit_move_insn (reg, pic_ref); - return reg; - } - else if (GET_CODE (orig) == CONST) - { - rtx base, offset; - - /* Make sure this is CONST has not already been legitimized */ - if (GET_CODE (XEXP (orig, 0)) == PLUS - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) - return orig; - - if (reg == 0) - abort (); - - /* legitimize both operands of the PLUS */ - if (GET_CODE (XEXP (orig, 0)) == PLUS) - { - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); - orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, - base == reg ? 0 : reg); - } - else abort (); - - if (GET_CODE (orig) == CONST_INT) - return plus_constant_for_output (base, INTVAL (orig)); - pic_ref = gen_rtx (PLUS, Pmode, base, orig); - /* Likewise, should we set special REG_NOTEs here? */ - } - return pic_ref; -} - - -/* Return the best assembler insn template - for moving operands[1] into operands[0] as a fullword. */ - -static char * -singlemove_string (operands) - rtx *operands; -{ -#ifdef SUPPORT_SUN_FPA - if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) - return "fpmoves %1,%0"; -#endif - if (DATA_REG_P (operands[0]) - && GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 128 - && INTVAL (operands[1]) >= -128) - { -#if defined (MOTOROLA) && !defined (CRDS) - return "moveq%.l %1,%0"; -#else - return "moveq %1,%0"; -#endif - } - if (operands[1] != const0_rtx) - return "move%.l %1,%0"; - if (! ADDRESS_REG_P (operands[0])) - return "clr%.l %0"; - return "sub%.l %0,%0"; -} - - -/* Output assembler code to perform a doubleword move insn - with operands OPERANDS. */ - -char * -output_move_double (operands) - rtx *operands; -{ - enum - { - REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP - } optype0, optype1; - rtx latehalf[2]; - rtx middlehalf[2]; - rtx addreg0 = 0, addreg1 = 0; - int size = GET_MODE_SIZE (GET_MODE (operands[0])); - - middlehalf[0] = 0; - middlehalf[1] = 0; - - /* First classify both operands. */ - - if (REG_P (operands[0])) - optype0 = REGOP; - else if (offsettable_memref_p (operands[0])) - optype0 = OFFSOP; - else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) - optype0 = POPOP; - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - optype0 = PUSHOP; - else if (GET_CODE (operands[0]) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (operands[1])) - optype1 = REGOP; - else if (CONSTANT_P (operands[1])) - optype1 = CNSTOP; - else if (offsettable_memref_p (operands[1])) - optype1 = OFFSOP; - else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC) - optype1 = POPOP; - else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) - optype1 = PUSHOP; - else if (GET_CODE (operands[1]) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP) - abort (); - - /* If one operand is decrementing and one is incrementing - decrement the former register explicitly - and change that operand into ordinary indexing. */ - - if (optype0 == PUSHOP && optype1 == POPOP) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); - if (size == 12) - output_asm_insn ("sub%.l %#12,%0", operands); - else - output_asm_insn ("subq%.l %#8,%0", operands); - if (GET_MODE (operands[1]) == XFmode) - operands[0] = gen_rtx (MEM, XFmode, operands[0]); - else if (GET_MODE (operands[0]) == DFmode) - operands[0] = gen_rtx (MEM, DFmode, operands[0]); - else - operands[0] = gen_rtx (MEM, DImode, operands[0]); - optype0 = OFFSOP; - } - if (optype0 == POPOP && optype1 == PUSHOP) - { - operands[1] = XEXP (XEXP (operands[1], 0), 0); - if (size == 12) - output_asm_insn ("sub%.l %#12,%1", operands); - else - output_asm_insn ("subq%.l %#8,%1", operands); - if (GET_MODE (operands[1]) == XFmode) - operands[1] = gen_rtx (MEM, XFmode, operands[1]); - else if (GET_MODE (operands[1]) == DFmode) - operands[1] = gen_rtx (MEM, DFmode, operands[1]); - else - operands[1] = gen_rtx (MEM, DImode, operands[1]); - optype1 = OFFSOP; - } - - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the second word. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (operands[0], 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (operands[1], 0)); - - /* Ok, we can do one word at a time. - Normally we do the low-numbered word first, - but if either operand is autodecrementing then we - do the high-numbered word first. - - In either case, set up in LATEHALF the operands to use - for the high-numbered word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ - - if (size == 12) - { - if (optype0 == REGOP) - { - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); - middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - } - else if (optype0 == OFFSOP) - { - middlehalf[0] = adj_offsettable_operand (operands[0], 4); - latehalf[0] = adj_offsettable_operand (operands[0], size - 4); - } - else - { - middlehalf[0] = operands[0]; - latehalf[0] = operands[0]; - } - - if (optype1 == REGOP) - { - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - } - else if (optype1 == OFFSOP) - { - middlehalf[1] = adj_offsettable_operand (operands[1], 4); - latehalf[1] = adj_offsettable_operand (operands[1], size - 4); - } - else if (optype1 == CNSTOP) - { - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - REAL_VALUE_TYPE r; - long l[3]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); - operands[1] = GEN_INT (l[0]); - middlehalf[1] = GEN_INT (l[1]); - latehalf[1] = GEN_INT (l[2]); - } - else if (CONSTANT_P (operands[1])) - { - /* actually, no non-CONST_DOUBLE constant should ever - appear here. */ - abort (); - if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) - latehalf[1] = constm1_rtx; - else - latehalf[1] = const0_rtx; - } - } - else - { - middlehalf[1] = operands[1]; - latehalf[1] = operands[1]; - } - } - else - /* size is not 12: */ - { - if (optype0 == REGOP) - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (operands[0], size - 4); - else - latehalf[0] = operands[0]; - - if (optype1 == REGOP) - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (operands[1], size - 4); - else if (optype1 == CNSTOP) - split_double (operands[1], &operands[1], &latehalf[1]); - else - latehalf[1] = operands[1]; - } - - /* If insn is effectively movd N(sp),-(sp) then we will do the - high word first. We should use the adjusted operand 1 (which is N+4(sp)) - for the low word as well, to compensate for the first decrement of sp. */ - if (optype0 == PUSHOP - && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM - && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) - operands[1] = latehalf[1]; - - /* If one or both operands autodecrementing, - do the two words, high-numbered first. */ - - /* Likewise, the first move would clobber the source of the second one, - do them in the other order. This happens only for registers; - such overlap can't happen in memory unless the user explicitly - sets it up, and that is an undefined circumstance. */ - - if (optype0 == PUSHOP || optype1 == PUSHOP - || (optype0 == REGOP && optype1 == REGOP - && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1])) - || REGNO (operands[0]) == REGNO (latehalf[1])))) - { - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - { - if (size == 12) - output_asm_insn ("addql %#8,%0", &addreg0); - else - output_asm_insn ("addql %#4,%0", &addreg0); - } - if (addreg1) - { - if (size == 12) - output_asm_insn ("addql %#8,%0", &addreg1); - else - output_asm_insn ("addql %#4,%0", &addreg1); - } - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - output_asm_insn ("subql %#4,%0", &addreg0); - if (addreg1) - output_asm_insn ("subql %#4,%0", &addreg1); - - if (size == 12) - { - output_asm_insn (singlemove_string (middlehalf), middlehalf); - if (addreg0) - output_asm_insn ("subql %#4,%0", &addreg0); - if (addreg1) - output_asm_insn ("subql %#4,%0", &addreg1); - } - - /* Do low-numbered word. */ - return singlemove_string (operands); - } - - /* Normal case: do the two words, low-numbered first. */ - - output_asm_insn (singlemove_string (operands), operands); - - /* Do the middle one of the three words for long double */ - if (size == 12) - { - if (addreg0) - output_asm_insn ("addql %#4,%0", &addreg0); - if (addreg1) - output_asm_insn ("addql %#4,%0", &addreg1); - - output_asm_insn (singlemove_string (middlehalf), middlehalf); - } - - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - output_asm_insn ("addql %#4,%0", &addreg0); - if (addreg1) - output_asm_insn ("addql %#4,%0", &addreg1); - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - { - if (size == 12) - output_asm_insn ("subql %#8,%0", &addreg0); - else - output_asm_insn ("subql %#4,%0", &addreg0); - } - if (addreg1) - { - if (size == 12) - output_asm_insn ("subql %#8,%0", &addreg1); - else - output_asm_insn ("subql %#4,%0", &addreg1); - } - - return ""; -} - -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. */ - -static rtx -find_addr_reg (addr) - rtx addr; -{ - while (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - abort (); - } - if (GET_CODE (addr) == REG) - return addr; - abort (); -} - -/* Store in cc_status the expressions that the condition codes will - describe after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -/* On the 68000, all the insns to store in an address register fail to - set the cc's. However, in some cases these instructions can make it - possibly invalid to use the saved cc's. In those cases we clear out - some or all of the saved cc's so they won't be used. */ - -notice_update_cc (exp, insn) - rtx exp; - rtx insn; -{ - /* If the cc is being set from the fpa and the expression is not an - explicit floating point test instruction (which has code to deal with - this), reinit the CC. */ - if (((cc_status.value1 && FPA_REG_P (cc_status.value1)) - || (cc_status.value2 && FPA_REG_P (cc_status.value2))) - && !(GET_CODE (exp) == PARALLEL - && GET_CODE (XVECEXP (exp, 0, 0)) == SET - && XEXP (XVECEXP (exp, 0, 0), 0) == cc0_rtx)) - { - CC_STATUS_INIT; - } - else if (GET_CODE (exp) == SET) - { - if (GET_CODE (SET_SRC (exp)) == CALL) - { - CC_STATUS_INIT; - } - else if (ADDRESS_REG_P (SET_DEST (exp))) - { - if (cc_status.value1 - && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)) - cc_status.value1 = 0; - if (cc_status.value2 - && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)) - cc_status.value2 = 0; - } - else if (!FP_REG_P (SET_DEST (exp)) - && SET_DEST (exp) != cc0_rtx - && (FP_REG_P (SET_SRC (exp)) - || GET_CODE (SET_SRC (exp)) == FIX - || GET_CODE (SET_SRC (exp)) == FLOAT_TRUNCATE - || GET_CODE (SET_SRC (exp)) == FLOAT_EXTEND)) - { - CC_STATUS_INIT; - } - /* A pair of move insns doesn't produce a useful overall cc. */ - else if (!FP_REG_P (SET_DEST (exp)) - && !FP_REG_P (SET_SRC (exp)) - && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4 - && (GET_CODE (SET_SRC (exp)) == REG - || GET_CODE (SET_SRC (exp)) == MEM - || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE)) - { - CC_STATUS_INIT; - } - else if (GET_CODE (SET_SRC (exp)) == CALL) - { - CC_STATUS_INIT; - } - else if (XEXP (exp, 0) != pc_rtx) - { - cc_status.flags = 0; - cc_status.value1 = XEXP (exp, 0); - cc_status.value2 = XEXP (exp, 1); - } - } - else if (GET_CODE (exp) == PARALLEL - && GET_CODE (XVECEXP (exp, 0, 0)) == SET) - { - if (ADDRESS_REG_P (XEXP (XVECEXP (exp, 0, 0), 0))) - CC_STATUS_INIT; - else if (XEXP (XVECEXP (exp, 0, 0), 0) != pc_rtx) - { - cc_status.flags = 0; - cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0); - cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1); - } - } - else - CC_STATUS_INIT; - if (cc_status.value2 != 0 - && ADDRESS_REG_P (cc_status.value2) - && GET_MODE (cc_status.value2) == QImode) - CC_STATUS_INIT; - if (cc_status.value2 != 0 - && !(cc_status.value1 && FPA_REG_P (cc_status.value1))) - switch (GET_CODE (cc_status.value2)) - { - case PLUS: case MINUS: case MULT: - case DIV: case UDIV: case MOD: case UMOD: case NEG: - case ASHIFT: case LSHIFT: case ASHIFTRT: case LSHIFTRT: - case ROTATE: case ROTATERT: - if (GET_MODE (cc_status.value2) != VOIDmode) - cc_status.flags |= CC_NO_OVERFLOW; - break; - case ZERO_EXTEND: - /* (SET r1 (ZERO_EXTEND r2)) on this machine - ends with a move insn moving r2 in r2's mode. - Thus, the cc's are set for r2. - This can set N bit spuriously. */ - cc_status.flags |= CC_NOT_NEGATIVE; - } - if (cc_status.value1 && GET_CODE (cc_status.value1) == REG - && cc_status.value2 - && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) - cc_status.value2 = 0; - if (((cc_status.value1 && FP_REG_P (cc_status.value1)) - || (cc_status.value2 && FP_REG_P (cc_status.value2))) - && !((cc_status.value1 && FPA_REG_P (cc_status.value1)) - || (cc_status.value2 && FPA_REG_P (cc_status.value2)))) - cc_status.flags = CC_IN_68881; -} - -char * -output_move_const_double (operands) - rtx *operands; -{ -#ifdef SUPPORT_SUN_FPA - if (TARGET_FPA && FPA_REG_P (operands[0])) - { - int code = standard_sun_fpa_constant_p (operands[1]); - - if (code != 0) - { - static char buf[40]; - - sprintf (buf, "fpmove%%.d %%%%%d,%%0", code & 0x1ff); - return buf; - } - return "fpmove%.d %1,%0"; - } - else -#endif - { - int code = standard_68881_constant_p (operands[1]); - - if (code != 0) - { - static char buf[40]; - - sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff); - return buf; - } - return "fmove%.d %1,%0"; - } -} - -char * -output_move_const_single (operands) - rtx *operands; -{ -#ifdef SUPPORT_SUN_FPA - if (TARGET_FPA) - { - int code = standard_sun_fpa_constant_p (operands[1]); - - if (code != 0) - { - static char buf[40]; - - sprintf (buf, "fpmove%%.s %%%%%d,%%0", code & 0x1ff); - return buf; - } - return "fpmove%.s %1,%0"; - } - else -#endif /* defined SUPPORT_SUN_FPA */ - { - int code = standard_68881_constant_p (operands[1]); - - if (code != 0) - { - static char buf[40]; - - sprintf (buf, "fmovecr %%#0x%x,%%0", code & 0xff); - return buf; - } - return "fmove%.s %f1,%0"; - } -} - -/* Return nonzero if X, a CONST_DOUBLE, has a value that we can get - from the "fmovecr" instruction. - The value, anded with 0xff, gives the code to use in fmovecr - to get the desired constant. */ - -/* This code has been fixed for cross-compilation. */ - -static int inited_68881_table = 0; - -char *strings_68881[7] = { - "0.0", - "1.0", - "10.0", - "100.0", - "10000.0", - "1e8", - "1e16" - }; - -int codes_68881[7] = { - 0x0f, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37 - }; - -REAL_VALUE_TYPE values_68881[7]; - -/* Set up values_68881 array by converting the decimal values - strings_68881 to binary. */ - -void -init_68881_table () -{ - int i; - REAL_VALUE_TYPE r; - enum machine_mode mode; - - mode = DFmode; - for (i = 0; i < 7; i++) - { - if (i == 6) - mode = SFmode; - r = REAL_VALUE_ATOF (strings_68881[i], mode); - values_68881[i] = r; - } - inited_68881_table = 1; -} - -int -standard_68881_constant_p (x) - rtx x; -{ - REAL_VALUE_TYPE r; - int i; - enum machine_mode mode; - - /* fmovecr must be emulated on the 68040, so it shouldn't be used at all. */ - if (TARGET_68040) - return 0; - -#ifndef REAL_ARITHMETIC -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - if (! flag_pretend_float) - return 0; -#endif -#endif - - if (! inited_68881_table) - init_68881_table (); - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - - for (i = 0; i < 6; i++) - { - if (REAL_VALUES_EQUAL (r, values_68881[i])) - return (codes_68881[i]); - } - - if (GET_MODE (x) == SFmode) - return 0; - - if (REAL_VALUES_EQUAL (r, values_68881[6])) - return (codes_68881[6]); - - /* larger powers of ten in the constants ram are not used - because they are not equal to a `double' C constant. */ - return 0; -} - -/* If X is a floating-point constant, return the logarithm of X base 2, - or 0 if X is not a power of 2. */ - -int -floating_exact_log2 (x) - rtx x; -{ - REAL_VALUE_TYPE r, r1; - int i; - -#ifndef REAL_ARITHMETIC -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - if (! flag_pretend_float) - return 0; -#endif -#endif - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - - if (REAL_VALUES_LESS (r, dconst0)) - return 0; - - r1 = dconst1; - i = 0; - while (REAL_VALUES_LESS (r1, r)) - { - r1 = REAL_VALUE_LDEXP (dconst1, i); - if (REAL_VALUES_EQUAL (r1, r)) - return i; - i = i + 1; - } - return 0; -} - -#ifdef SUPPORT_SUN_FPA -/* Return nonzero if X, a CONST_DOUBLE, has a value that we can get - from the Sun FPA's constant RAM. - The value returned, anded with 0x1ff, gives the code to use in fpmove - to get the desired constant. */ - -static int inited_FPA_table = 0; - -char *strings_FPA[38] = { -/* small rationals */ - "0.0", - "1.0", - "0.5", - "-1.0", - "2.0", - "3.0", - "4.0", - "8.0", - "0.25", - "0.125", - "10.0", - "-0.5", -/* Decimal equivalents of double precision values */ - "2.718281828459045091", /* D_E */ - "6.283185307179586477", /* 2 pi */ - "3.141592653589793116", /* D_PI */ - "1.570796326794896619", /* pi/2 */ - "1.414213562373095145", /* D_SQRT2 */ - "0.7071067811865475244", /* 1/sqrt(2) */ - "-1.570796326794896619", /* -pi/2 */ - "1.442695040888963387", /* D_LOG2ofE */ - "3.321928024887362182", /* D_LOG2of10 */ - "0.6931471805599452862", /* D_LOGEof2 */ - "2.302585092994045901", /* D_LOGEof10 */ - "0.3010299956639811980", /* D_LOG10of2 */ - "0.4342944819032518167", /* D_LOG10ofE */ -/* Decimal equivalents of single precision values */ - "2.718281745910644531", /* S_E */ - "6.283185307179586477", /* 2 pi */ - "3.141592741012573242", /* S_PI */ - "1.570796326794896619", /* pi/2 */ - "1.414213538169860840", /* S_SQRT2 */ - "0.7071067811865475244", /* 1/sqrt(2) */ - "-1.570796326794896619", /* -pi/2 */ - "1.442695021629333496", /* S_LOG2ofE */ - "3.321928024291992188", /* S_LOG2of10 */ - "0.6931471824645996094", /* S_LOGEof2 */ - "2.302585124969482442", /* S_LOGEof10 */ - "0.3010300099849700928", /* S_LOG10of2 */ - "0.4342944920063018799", /* S_LOG10ofE */ -}; - - -int codes_FPA[38] = { -/* small rationals */ - 0x200, - 0xe, - 0xf, - 0x10, - 0x11, - 0xb1, - 0x12, - 0x13, - 0x15, - 0x16, - 0x17, - 0x2e, -/* double precision */ - 0x8, - 0x9, - 0xa, - 0xb, - 0xc, - 0xd, - 0x27, - 0x28, - 0x29, - 0x2a, - 0x2b, - 0x2c, - 0x2d, -/* single precision */ - 0x8, - 0x9, - 0xa, - 0xb, - 0xc, - 0xd, - 0x27, - 0x28, - 0x29, - 0x2a, - 0x2b, - 0x2c, - 0x2d - }; - -REAL_VALUE_TYPE values_FPA[38]; - -/* This code has been fixed for cross-compilation. */ - -void -init_FPA_table () -{ - enum machine_mode mode; - int i; - REAL_VALUE_TYPE r; - - mode = DFmode; - for (i = 0; i < 38; i++) - { - if (i == 25) - mode = SFmode; - r = REAL_VALUE_ATOF (strings_FPA[i], mode); - values_FPA[i] = r; - } - inited_FPA_table = 1; -} - - -int -standard_sun_fpa_constant_p (x) - rtx x; -{ - REAL_VALUE_TYPE r; - int i; - -#ifndef REAL_ARITHMETIC -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - if (! flag_pretend_float) - return 0; -#endif -#endif - - if (! inited_FPA_table) - init_FPA_table (); - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - - for (i=0; i<12; i++) - { - if (REAL_VALUES_EQUAL (r, values_FPA[i])) - return (codes_FPA[i]); - } - - if (GET_MODE (x) == SFmode) - { - for (i=25; i<38; i++) - { - if (REAL_VALUES_EQUAL (r, values_FPA[i])) - return (codes_FPA[i]); - } - } - else - { - for (i=12; i<25; i++) - { - if (REAL_VALUES_EQUAL (r, values_FPA[i])) - return (codes_FPA[i]); - } - } - return 0x0; -} -#endif /* define SUPPORT_SUN_FPA */ - -/* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand X. X is an RTL - expression. - - CODE is a value that can be used to specify one of several ways - of printing the operand. It is used when identical operands - must be printed differently depending on the context. CODE - comes from the `%' specification that was used to request - printing of the operand. If the specification was just `%DIGIT' - then CODE is 0; if the specification was `%LTR DIGIT' then CODE - is the ASCII code for LTR. - - If X is a register, this macro should print the register's name. - The names can be found in an array `reg_names' whose type is - `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'. - - When the machine description has a specification `%PUNCT' (a `%' - followed by a punctuation character), this macro is called with - a null pointer for X and the punctuation character for CODE. - - The m68k specific codes are: - - '.' for dot needed in Motorola-style opcode names. - '-' for an operand pushing on the stack: - sp@-, -(sp) or -(%sp) depending on the style of syntax. - '+' for an operand pushing on the stack: - sp@+, (sp)+ or (%sp)+ depending on the style of syntax. - '@' for a reference to the top word on the stack: - sp@, (sp) or (%sp) depending on the style of syntax. - '#' for an immediate operand prefix (# in MIT and Motorola syntax - but & in SGS syntax). - '!' for the cc register (used in an `and to cc' insn). - '$' for the letter `s' in an op code, but only on the 68040. - '&' for the letter `d' in an op code, but only on the 68040. - '/' for register prefix needed by longlong.h. - - 'b' for byte insn (no effect, on the Sun; this is for the ISI). - 'd' to force memory addressing to be absolute, not relative. - 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex) - 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather - than directly). Second part of 'y' below. - 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex), - or print pair of registers as rx:ry. - 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs - CONST_DOUBLE's as SunFPA constant RAM registers if - possible, so it should not be used except for the SunFPA. - - */ - -void -print_operand (file, op, letter) - FILE *file; /* file to write to */ - rtx op; /* operand to print */ - int letter; /* % or 0 */ -{ - int i; - - if (letter == '.') - { -#ifdef MOTOROLA - asm_fprintf (file, "."); -#endif - } - else if (letter == '#') - { - asm_fprintf (file, "%0I"); - } - else if (letter == '-') - { -#ifdef MOTOROLA - asm_fprintf (file, "-(%Rsp)"); -#else - asm_fprintf (file, "%Rsp@-"); -#endif - } - else if (letter == '+') - { -#ifdef MOTOROLA - asm_fprintf (file, "(%Rsp)+"); -#else - asm_fprintf (file, "%Rsp@+"); -#endif - } - else if (letter == '@') - { -#ifdef MOTOROLA - asm_fprintf (file, "(%Rsp)"); -#else - asm_fprintf (file, "%Rsp@"); -#endif - } - else if (letter == '!') - { - asm_fprintf (file, "%Rfpcr"); - } - else if (letter == '$') - { - if (TARGET_68040_ONLY) - { - fprintf (file, "s"); - } - } - else if (letter == '&') - { - if (TARGET_68040_ONLY) - { - fprintf (file, "d"); - } - } - else if (letter == '/') - { - asm_fprintf (file, "%R"); - } - else if (GET_CODE (op) == REG) - { - if (REGNO (op) < 16 - && (letter == 'y' || letter == 'x') - && GET_MODE (op) == DFmode) - { - fprintf (file, "%s:%s", reg_names[REGNO (op)], - reg_names[REGNO (op)+1]); - } - else - { - fprintf (file, "%s", reg_names[REGNO (op)]); - } - } - else if (GET_CODE (op) == MEM) - { - output_address (XEXP (op, 0)); - if (letter == 'd' && ! TARGET_68020 - && CONSTANT_ADDRESS_P (XEXP (op, 0)) - && !(GET_CODE (XEXP (op, 0)) == CONST_INT - && INTVAL (XEXP (op, 0)) < 0x8000 - && INTVAL (XEXP (op, 0)) >= -0x8000)) - { - fprintf (file, ":l"); - } - } -#ifdef SUPPORT_SUN_FPA - else if ((letter == 'y' || letter == 'w') - && GET_CODE (op) == CONST_DOUBLE - && (i = standard_sun_fpa_constant_p (op))) - { - fprintf (file, "%%%d", i & 0x1ff); - } -#endif - else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode) - { - REAL_VALUE_TYPE r; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_FLOAT_OPERAND (letter, file, r); - } - else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode) - { - REAL_VALUE_TYPE r; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r); - } - else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode) - { - REAL_VALUE_TYPE r; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - ASM_OUTPUT_DOUBLE_OPERAND (file, r); - } - else - { - asm_fprintf (file, "%0I"); output_addr_const (file, op); - } -} - - -/* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand that is a memory - reference whose address is ADDR. ADDR is an RTL expression. - - Note that this contains a kludge that knows that the only reason - we have an address (plus (label_ref...) (reg...)) when not generating - PIC code is in the insn before a tablejump, and we know that m68k.md - generates a label LInnn: on such an insn. - - It is possible for PIC to generate a (plus (label_ref...) (reg...)) - and we handle that just like we would a (plus (symbol_ref...) (reg...)). - - Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)" - fails to assemble. Luckily "Lnnn(pc,d0.l*2)" produces the results - we want. This difference can be accommodated by using an assembler - define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other - string, as necessary. This is accomplished via the ASM_OUTPUT_CASE_END - macro. See m68k/sgs.h for an example; for versions without the bug. - - They also do not like things like "pea 1.w", so we simple leave off - the .w on small constants. - - This routine is responsible for distinguishing between -fpic and -fPIC - style relocations in an address. When generating -fpic code the - offset is output in word mode (eg movel a5@(_foo:w), a0). When generating - -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */ - -void -print_operand_address (file, addr) - FILE *file; - rtx addr; -{ - register rtx reg1, reg2, breg, ireg; - rtx offset; - - switch (GET_CODE (addr)) - { - case REG: -#ifdef MOTOROLA - fprintf (file, "(%s)", reg_names[REGNO (addr)]); -#else - fprintf (file, "%s@", reg_names[REGNO (addr)]); -#endif - break; - case PRE_DEC: -#ifdef MOTOROLA - fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); -#else - fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]); -#endif - break; - case POST_INC: -#ifdef MOTOROLA - fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); -#else - fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]); -#endif - break; - case PLUS: - reg1 = reg2 = ireg = breg = offset = 0; - if (CONSTANT_ADDRESS_P (XEXP (addr, 0))) - { - offset = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))) - { - offset = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - if (GET_CODE (addr) != PLUS) - { - ; - } - else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND) - { - reg1 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND) - { - reg1 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else if (GET_CODE (XEXP (addr, 0)) == MULT) - { - reg1 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == MULT) - { - reg1 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else if (GET_CODE (XEXP (addr, 0)) == REG) - { - reg1 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == REG) - { - reg1 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT - || GET_CODE (addr) == SIGN_EXTEND) - { - if (reg1 == 0) - { - reg1 = addr; - } - else - { - reg2 = addr; - } - addr = 0; - } -#if 0 /* for OLD_INDEXING */ - else if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG) - { - reg2 = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - else if (GET_CODE (XEXP (addr, 1)) == REG) - { - reg2 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - } -#endif - if (offset != 0) - { - if (addr != 0) - { - abort (); - } - addr = offset; - } - if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND - || GET_CODE (reg1) == MULT)) - || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2)))) - { - breg = reg2; - ireg = reg1; - } - else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1))) - { - breg = reg1; - ireg = reg2; - } - if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF - && ! (flag_pic && ireg == pic_offset_table_rtx)) - { - int scale = 1; - if (GET_CODE (ireg) == MULT) - { - scale = INTVAL (XEXP (ireg, 1)); - ireg = XEXP (ireg, 0); - } - if (GET_CODE (ireg) == SIGN_EXTEND) - { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.w", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (XEXP (ireg, 0))]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.w", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (XEXP (ireg, 0))]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (XEXP (ireg, 0))]); -#endif - } - else - { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (ireg)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (ireg)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (ireg)]); -#endif - } - if (scale != 1) - { -#ifdef MOTOROLA - fprintf (file, "*%d", scale); -#else - fprintf (file, ":%d", scale); -#endif - } - putc (')', file); - break; - } - if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF - && ! (flag_pic && breg == pic_offset_table_rtx)) - { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (breg)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (breg)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (breg)]); -#endif - putc (')', file); - break; - } - if (ireg != 0 || breg != 0) - { - int scale = 1; - if (breg == 0) - { - abort (); - } - if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF) - { - abort (); - } -#ifdef MOTOROLA - if (addr != 0) - { - output_addr_const (file, addr); - if (flag_pic && (breg == pic_offset_table_rtx)) - fprintf (file, "@GOT"); - } - fprintf (file, "(%s", reg_names[REGNO (breg)]); - if (ireg != 0) - { - putc (',', file); - } -#else - fprintf (file, "%s@(", reg_names[REGNO (breg)]); - if (addr != 0) - { - output_addr_const (file, addr); - if ((flag_pic == 1) && (breg == pic_offset_table_rtx)) - fprintf (file, ":w"); - if ((flag_pic == 2) && (breg == pic_offset_table_rtx)) - fprintf (file, ":l"); - } - if (addr != 0 && ireg != 0) - { - putc (',', file); - } -#endif - if (ireg != 0 && GET_CODE (ireg) == MULT) - { - scale = INTVAL (XEXP (ireg, 1)); - ireg = XEXP (ireg, 0); - } - if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND) - { -#ifdef MOTOROLA - fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]); -#else - fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]); -#endif - } - else if (ireg != 0) - { -#ifdef MOTOROLA - fprintf (file, "%s.l", reg_names[REGNO (ireg)]); -#else - fprintf (file, "%s:l", reg_names[REGNO (ireg)]); -#endif - } - if (scale != 1) - { -#ifdef MOTOROLA - fprintf (file, "*%d", scale); -#else - fprintf (file, ":%d", scale); -#endif - } - putc (')', file); - break; - } - else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF - && ! (flag_pic && reg1 == pic_offset_table_rtx)) - { -#ifdef MOTOROLA -#ifdef SGS - asm_fprintf (file, "%LLD%d(%Rpc,%s.l)", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (reg1)]); -#else - asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l)", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (reg1)]); -#endif -#else - asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)", - CODE_LABEL_NUMBER (XEXP (addr, 0)), - CODE_LABEL_NUMBER (XEXP (addr, 0)), - reg_names[REGNO (reg1)]); -#endif - break; - } - /* FALL-THROUGH (is this really what we want? */ - default: - if (GET_CODE (addr) == CONST_INT - && INTVAL (addr) < 0x8000 - && INTVAL (addr) >= -0x8000) - { -#ifdef MOTOROLA -#ifdef SGS - /* Many SGS assemblers croak on size specifiers for constants. */ - fprintf (file, "%d", INTVAL (addr)); -#else - fprintf (file, "%d.w", INTVAL (addr)); -#endif -#else - fprintf (file, "%d:w", INTVAL (addr)); -#endif - } - else - { - output_addr_const (file, addr); - } - break; - } -} - -/* Check for cases where a clr insns can be omitted from code using - strict_low_part sets. For example, the second clrl here is not needed: - clrl d0; movw a0@+,d0; use d0; clrl d0; movw a0@+; use d0; ... - - MODE is the mode of this STRICT_LOW_PART set. FIRST_INSN is the clear - insn we are checking for redundancy. TARGET is the register set by the - clear insn. */ - -int -strict_low_part_peephole_ok (mode, first_insn, target) - enum machine_mode mode; - rtx first_insn; - rtx target; -{ - rtx p; - - p = prev_nonnote_insn (first_insn); - - while (p) - { - /* If it isn't an insn, then give up. */ - if (GET_CODE (p) != INSN) - return 0; - - if (reg_set_p (target, p)) - { - rtx set = single_set (p); - rtx dest; - - /* If it isn't an easy to recognize insn, then give up. */ - if (! set) - return 0; - - dest = SET_DEST (set); - - /* If this sets the entire target register to zero, then our - first_insn is redundant. */ - if (rtx_equal_p (dest, target) - && SET_SRC (set) == const0_rtx) - return 1; - else if (GET_CODE (dest) == STRICT_LOW_PART - && GET_CODE (XEXP (dest, 0)) == REG - && REGNO (XEXP (dest, 0)) == REGNO (target) - && (GET_MODE_SIZE (GET_MODE (XEXP (dest, 0))) - <= GET_MODE_SIZE (mode))) - /* This is a strict low part set which modifies less than - we are using, so it is safe. */ - ; - else - return 0; - } - - p = prev_nonnote_insn (p); - - } - - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/m68k/config.h b/gnu/usr.bin/gcc2/arch/m68k/config.h deleted file mode 100644 index 0bec2252327..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/config.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Configuration for GNU C-compiler for Motorola 68000 family. - Copyright (C) 1987 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: config.h,v 1.1.1.1 1995/10/18 08:39:19 deraadt Exp $ -*/ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -#define HOST_WORDS_BIG_ENDIAN - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If compiled with GNU C, use the built-in alloca */ -#ifdef __GNUC__ -/* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ -#define alloca(x) __builtin_alloca(x) -#endif diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-attr.h b/gnu/usr.bin/gcc2/arch/m68k/insn-attr.h deleted file mode 100644 index 5fe9a2f8001..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-attr.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Generated automatically by the program `genattr' -from the machine description file `md'. */ - -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif -#define HAVE_ATTR_alternative -#define get_attr_alternative(insn) which_alternative - -#define ATTR_FLAG_forward 0x1 -#define ATTR_FLAG_backward 0x2 -#define ATTR_FLAG_likely 0x4 -#define ATTR_FLAG_very_likely 0x8 -#define ATTR_FLAG_unlikely 0x10 -#define ATTR_FLAG_very_unlikely 0x20 diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-attrtab.c b/gnu/usr.bin/gcc2/arch/m68k/insn-attrtab.c deleted file mode 100644 index 0e86d1f4c35..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-attrtab.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Generated automatically by the program `genattrtab' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "regs.h" -#include "real.h" -#include "output.h" -#include "insn-attr.h" - -#define operands recog_operand - diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-codes.h b/gnu/usr.bin/gcc2/arch/m68k/insn-codes.h deleted file mode 100644 index 35b48afb561..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-codes.h +++ /dev/null @@ -1,184 +0,0 @@ -/* Generated automatically by the program `gencodes' -from the machine description file `md'. */ - -#ifndef MAX_INSN_CODE - -enum insn_code { - CODE_FOR_tstsi = 2, - CODE_FOR_tsthi = 3, - CODE_FOR_tstqi = 4, - CODE_FOR_tstsf = 5, - CODE_FOR_tstsf_fpa = 6, - CODE_FOR_tstdf = 8, - CODE_FOR_tstdf_fpa = 9, - CODE_FOR_cmpsi = 11, - CODE_FOR_cmphi = 12, - CODE_FOR_cmpqi = 13, - CODE_FOR_cmpdf = 14, - CODE_FOR_cmpdf_fpa = 15, - CODE_FOR_cmpsf = 17, - CODE_FOR_cmpsf_fpa = 18, - CODE_FOR_movsi = 28, - CODE_FOR_movhi = 30, - CODE_FOR_movstricthi = 31, - CODE_FOR_movqi = 32, - CODE_FOR_movstrictqi = 33, - CODE_FOR_movsf = 34, - CODE_FOR_movdf = 35, - CODE_FOR_movxf = 36, - CODE_FOR_movdi = 39, - CODE_FOR_pushasi = 40, - CODE_FOR_truncsiqi2 = 41, - CODE_FOR_trunchiqi2 = 42, - CODE_FOR_truncsihi2 = 43, - CODE_FOR_zero_extendhisi2 = 44, - CODE_FOR_zero_extendqihi2 = 45, - CODE_FOR_zero_extendqisi2 = 46, - CODE_FOR_extendhisi2 = 50, - CODE_FOR_extendqihi2 = 51, - CODE_FOR_extendqisi2 = 52, - CODE_FOR_extendsfdf2 = 53, - CODE_FOR_truncdfsf2 = 56, - CODE_FOR_floatsisf2 = 60, - CODE_FOR_floatsidf2 = 63, - CODE_FOR_floathisf2 = 66, - CODE_FOR_floathidf2 = 67, - CODE_FOR_floatqisf2 = 68, - CODE_FOR_floatqidf2 = 69, - CODE_FOR_fix_truncdfsi2 = 70, - CODE_FOR_fix_truncdfhi2 = 71, - CODE_FOR_fix_truncdfqi2 = 72, - CODE_FOR_ftruncdf2 = 73, - CODE_FOR_ftruncsf2 = 74, - CODE_FOR_fixsfqi2 = 75, - CODE_FOR_fixsfhi2 = 76, - CODE_FOR_fixsfsi2 = 77, - CODE_FOR_fixdfqi2 = 78, - CODE_FOR_fixdfhi2 = 79, - CODE_FOR_fixdfsi2 = 80, - CODE_FOR_addsi3 = 83, - CODE_FOR_addhi3 = 85, - CODE_FOR_addqi3 = 88, - CODE_FOR_adddf3 = 91, - CODE_FOR_addsf3 = 94, - CODE_FOR_subsi3 = 97, - CODE_FOR_subhi3 = 99, - CODE_FOR_subqi3 = 101, - CODE_FOR_subdf3 = 103, - CODE_FOR_subsf3 = 106, - CODE_FOR_mulhi3 = 109, - CODE_FOR_mulhisi3 = 110, - CODE_FOR_mulsi3 = 112, - CODE_FOR_umulhisi3 = 113, - CODE_FOR_umulsidi3 = 115, - CODE_FOR_mulsidi3 = 118, - CODE_FOR_muldf3 = 121, - CODE_FOR_mulsf3 = 124, - CODE_FOR_divhi3 = 127, - CODE_FOR_divhisi3 = 128, - CODE_FOR_udivhi3 = 130, - CODE_FOR_udivhisi3 = 131, - CODE_FOR_divdf3 = 133, - CODE_FOR_divsf3 = 136, - CODE_FOR_modhi3 = 139, - CODE_FOR_modhisi3 = 140, - CODE_FOR_umodhi3 = 142, - CODE_FOR_umodhisi3 = 143, - CODE_FOR_divmodsi4 = 145, - CODE_FOR_udivmodsi4 = 146, - CODE_FOR_andsi3 = 147, - CODE_FOR_andhi3 = 148, - CODE_FOR_andqi3 = 151, - CODE_FOR_iorsi3 = 154, - CODE_FOR_iorhi3 = 155, - CODE_FOR_iorqi3 = 158, - CODE_FOR_xorsi3 = 161, - CODE_FOR_xorhi3 = 162, - CODE_FOR_xorqi3 = 165, - CODE_FOR_negsi2 = 168, - CODE_FOR_neghi2 = 169, - CODE_FOR_negqi2 = 171, - CODE_FOR_negsf2 = 173, - CODE_FOR_negdf2 = 176, - CODE_FOR_sqrtdf2 = 179, - CODE_FOR_abssf2 = 180, - CODE_FOR_absdf2 = 183, - CODE_FOR_one_cmplsi2 = 186, - CODE_FOR_one_cmplhi2 = 187, - CODE_FOR_one_cmplqi2 = 189, - CODE_FOR_ashlsi3 = 193, - CODE_FOR_ashlhi3 = 194, - CODE_FOR_ashlqi3 = 196, - CODE_FOR_ashrsi3 = 200, - CODE_FOR_ashrhi3 = 201, - CODE_FOR_ashrqi3 = 203, - CODE_FOR_lshlsi3 = 207, - CODE_FOR_lshlhi3 = 208, - CODE_FOR_lshlqi3 = 210, - CODE_FOR_lshrsi3 = 214, - CODE_FOR_lshrhi3 = 215, - CODE_FOR_lshrqi3 = 217, - CODE_FOR_rotlsi3 = 219, - CODE_FOR_rotlhi3 = 220, - CODE_FOR_rotlqi3 = 222, - CODE_FOR_rotrsi3 = 224, - CODE_FOR_rotrhi3 = 225, - CODE_FOR_rotrqi3 = 227, - CODE_FOR_extv = 235, - CODE_FOR_extzv = 236, - CODE_FOR_insv = 240, - CODE_FOR_seq = 248, - CODE_FOR_sne = 249, - CODE_FOR_sgt = 250, - CODE_FOR_sgtu = 251, - CODE_FOR_slt = 252, - CODE_FOR_sltu = 253, - CODE_FOR_sge = 254, - CODE_FOR_sgeu = 255, - CODE_FOR_sle = 256, - CODE_FOR_sleu = 257, - CODE_FOR_beq = 258, - CODE_FOR_bne = 259, - CODE_FOR_bgt = 260, - CODE_FOR_bgtu = 261, - CODE_FOR_blt = 262, - CODE_FOR_bltu = 263, - CODE_FOR_bge = 264, - CODE_FOR_bgeu = 265, - CODE_FOR_ble = 266, - CODE_FOR_bleu = 267, - CODE_FOR_jump = 278, - CODE_FOR_tablejump = 279, - CODE_FOR_decrement_and_branch_until_zero = 285, - CODE_FOR_call = 286, - CODE_FOR_call_value = 289, - CODE_FOR_untyped_call = 292, - CODE_FOR_blockage = 293, - CODE_FOR_nop = 294, - CODE_FOR_probe = 295, - CODE_FOR_return = 296, - CODE_FOR_indirect_jump = 297, - CODE_FOR_tstxf = 318, - CODE_FOR_cmpxf = 319, - CODE_FOR_extendsfxf2 = 321, - CODE_FOR_extenddfxf2 = 322, - CODE_FOR_truncxfdf2 = 323, - CODE_FOR_truncxfsf2 = 324, - CODE_FOR_floatsixf2 = 325, - CODE_FOR_floathixf2 = 326, - CODE_FOR_floatqixf2 = 327, - CODE_FOR_ftruncxf2 = 328, - CODE_FOR_fixxfqi2 = 329, - CODE_FOR_fixxfhi2 = 330, - CODE_FOR_fixxfsi2 = 331, - CODE_FOR_addxf3 = 332, - CODE_FOR_subxf3 = 334, - CODE_FOR_mulxf3 = 336, - CODE_FOR_divxf3 = 338, - CODE_FOR_negxf2 = 340, - CODE_FOR_absxf2 = 341, - CODE_FOR_sqrtxf2 = 342, - CODE_FOR_nothing }; - -#define MAX_INSN_CODE ((int) CODE_FOR_nothing) -#endif /* MAX_INSN_CODE */ diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-config.h b/gnu/usr.bin/gcc2/arch/m68k/insn-config.h deleted file mode 100644 index 7dba8866f62..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-config.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Generated automatically by the program `genconfig' -from the machine description file `md'. */ - - -#define MAX_RECOG_OPERANDS 10 - -#define MAX_DUP_OPERANDS 3 -#ifndef MAX_INSNS_PER_SPLIT -#define MAX_INSNS_PER_SPLIT 1 -#endif -#define REGISTER_CONSTRAINTS -#define HAVE_cc0 diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-emit.c b/gnu/usr.bin/gcc2/arch/m68k/insn-emit.c deleted file mode 100644 index 6b2694f69d5..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-emit.c +++ /dev/null @@ -1,1897 +0,0 @@ -/* Generated automatically by the program `genemit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "expr.h" -#include "real.h" -#include "output.h" -#include "insn-config.h" - -#include "insn-flags.h" - -#include "insn-codes.h" - -extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS]; - -extern rtx recog_operand[]; -#define operands emit_operand - -#define FAIL goto _fail - -#define DONE goto _done - -rtx -gen_tstsi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tsthi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tstqi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tstsf (operand0) - rtx operand0; -{ - rtx operands[1]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ - if (TARGET_FPA) - { - emit_insn (gen_tstsf_fpa (operands[0])); - DONE; - } -} - operand0 = operands[0]; - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, operand0)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_tstsf_fpa (operand0) - rtx operand0; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, cc0_rtx, operand0), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_tstdf (operand0) - rtx operand0; -{ - rtx operands[1]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ - if (TARGET_FPA) - { - emit_insn (gen_tstsf_fpa (operands[0])); - DONE; - } -} - operand0 = operands[0]; - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, operand0)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_tstdf_fpa (operand0) - rtx operand0; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, cc0_rtx, operand0), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_cmpsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmphi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmpqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmpdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (TARGET_FPA) - { - emit_insn (gen_cmpdf_fpa (operands[0], operands[1])); - DONE; - } -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_cmpdf_fpa (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_cmpsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (TARGET_FPA) - { - emit_insn (gen_cmpsf_fpa (operands[0], operands[1])); - DONE; - } -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_cmpsf_fpa (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_movsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (flag_pic && symbolic_operand (operands[1], SImode)) - { - /* The source is an address which requires PIC relocation. - Call legitimize_pic_address with the source, mode, and a relocation - register (a new pseudo, or the final destination if reload_in_progress - is set). Then fall through normally */ - extern rtx legitimize_pic_address(); - rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); - operands[1] = legitimize_pic_address (operands[1], SImode, temp); - } -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movhi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movstricthi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand0), operand1); -} - -rtx -gen_movqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movstrictqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand0), operand1); -} - -rtx -gen_movsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movxf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (CONSTANT_P (operands[1])) - { - operands[1] = force_const_mem (XFmode, operands[1]); - if (! memory_address_p (XFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], XFmode, - XEXP (operands[1], 0)); - } -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movdi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_pushasi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_truncsiqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, QImode, operand1)); -} - -rtx -gen_trunchiqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, QImode, operand1)); -} - -rtx -gen_truncsihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, operand1)); -} - -rtx -gen_zero_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operand2; - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, const0_rtx)); - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand2), operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_zero_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operand2; - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, const0_rtx)); - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand2), operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_zero_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operand2; - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, const0_rtx)); - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand2), operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1)); -} - -rtx -gen_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, HImode, operand1)); -} - -rtx -gen_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1)); -} - -rtx -gen_extendsfdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, DFmode, operand1)); -} - -rtx -gen_truncdfsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, SFmode, operand1)); -} - -rtx -gen_floatsisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floatsidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_floathisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floathidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_floatqisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floatqidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_fix_truncdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, DFmode, operand1))), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_fix_truncdfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, gen_rtx (FIX, DFmode, operand1))), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_fix_truncdfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, gen_rtx (FIX, DFmode, operand1))), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_ftruncdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, DFmode, operand1)); -} - -rtx -gen_ftruncsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SFmode, operand1)); -} - -rtx -gen_fixsfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, operand1)); -} - -rtx -gen_fixsfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, operand1)); -} - -rtx -gen_fixsfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, operand1)); -} - -rtx -gen_fixdfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, operand1)); -} - -rtx -gen_fixdfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, operand1)); -} - -rtx -gen_fixdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, operand1)); -} - -rtx -gen_addsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, operand1, operand2)); -} - -rtx -gen_addhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, HImode, operand1, operand2)); -} - -rtx -gen_addqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, QImode, operand1, operand2)); -} - -rtx -gen_adddf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, DFmode, operand1, operand2)); -} - -rtx -gen_addsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SFmode, operand1, operand2)); -} - -rtx -gen_subsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SImode, operand1, operand2)); -} - -rtx -gen_subhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, HImode, operand1, operand2)); -} - -rtx -gen_subqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, QImode, operand1, operand2)); -} - -rtx -gen_subdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, DFmode, operand1, operand2)); -} - -rtx -gen_subsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SFmode, operand1, operand2)); -} - -rtx -gen_mulhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, HImode, operand1, operand2)); -} - -rtx -gen_mulhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SImode, gen_rtx (SIGN_EXTEND, SImode, operand1), gen_rtx (SIGN_EXTEND, SImode, operand2))); -} - -rtx -gen_mulsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SImode, operand1, operand2)); -} - -rtx -gen_umulhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SImode, gen_rtx (ZERO_EXTEND, SImode, operand1), gen_rtx (ZERO_EXTEND, SImode, operand2))); -} - -rtx -gen_umulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, operand0, 1), gen_rtx (MULT, SImode, operand1, operand2)), - gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, operand0, 0), gen_rtx (TRUNCATE, SImode, gen_rtx (LSHIFTRT, DImode, gen_rtx (MULT, DImode, gen_rtx (ZERO_EXTEND, DImode, operand1), gen_rtx (ZERO_EXTEND, DImode, operand2)), GEN_INT (32)))))); -} - -rtx -gen_mulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, operand0, 1), gen_rtx (MULT, SImode, operand1, operand2)), - gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, operand0, 0), gen_rtx (TRUNCATE, SImode, gen_rtx (ASHIFT, DImode, gen_rtx (MULT, DImode, gen_rtx (SIGN_EXTEND, DImode, operand1), gen_rtx (SIGN_EXTEND, DImode, operand2)), GEN_INT (32)))))); -} - -rtx -gen_muldf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DFmode, operand1, operand2)); -} - -rtx -gen_mulsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SFmode, operand1, operand2)); -} - -rtx -gen_divhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, HImode, operand1, operand2)); -} - -rtx -gen_divhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, gen_rtx (DIV, SImode, operand1, gen_rtx (SIGN_EXTEND, SImode, operand2)))); -} - -rtx -gen_udivhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, HImode, operand1, operand2)); -} - -rtx -gen_udivhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, gen_rtx (UDIV, SImode, operand1, gen_rtx (ZERO_EXTEND, SImode, operand2)))); -} - -rtx -gen_divdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, DFmode, operand1, operand2)); -} - -rtx -gen_divsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SFmode, operand1, operand2)); -} - -rtx -gen_modhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MOD, HImode, operand1, operand2)); -} - -rtx -gen_modhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, gen_rtx (MOD, SImode, operand1, gen_rtx (SIGN_EXTEND, SImode, operand2)))); -} - -rtx -gen_umodhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UMOD, HImode, operand1, operand2)); -} - -rtx -gen_umodhisi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, gen_rtx (UMOD, SImode, operand1, gen_rtx (ZERO_EXTEND, SImode, operand2)))); -} - -rtx -gen_divmodsi4 (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SImode, operand1, operand2)), - gen_rtx (SET, VOIDmode, operand3, gen_rtx (MOD, SImode, operand1, operand2)))); -} - -rtx -gen_udivmodsi4 (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, SImode, operand1, operand2)), - gen_rtx (SET, VOIDmode, operand3, gen_rtx (UMOD, SImode, operand1, operand2)))); -} - -rtx -gen_andsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, SImode, operand1, operand2)); -} - -rtx -gen_andhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, HImode, operand1, operand2)); -} - -rtx -gen_andqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, QImode, operand1, operand2)); -} - -rtx -gen_iorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, SImode, operand1, operand2)); -} - -rtx -gen_iorhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, HImode, operand1, operand2)); -} - -rtx -gen_iorqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, QImode, operand1, operand2)); -} - -rtx -gen_xorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, SImode, operand1, operand2)); -} - -rtx -gen_xorhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, HImode, operand1, operand2)); -} - -rtx -gen_xorqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, QImode, operand1, operand2)); -} - -rtx -gen_negsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SImode, operand1)); -} - -rtx -gen_neghi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, HImode, operand1)); -} - -rtx -gen_negqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, QImode, operand1)); -} - -rtx -gen_negsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SFmode, operand1)); -} - -rtx -gen_negdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, DFmode, operand1)); -} - -rtx -gen_sqrtdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SQRT, DFmode, operand1)); -} - -rtx -gen_abssf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, SFmode, operand1)); -} - -rtx -gen_absdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, DFmode, operand1)); -} - -rtx -gen_one_cmplsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, SImode, operand1)); -} - -rtx -gen_one_cmplhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, HImode, operand1)); -} - -rtx -gen_one_cmplqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, QImode, operand1)); -} - -rtx -gen_ashlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, SImode, operand1, operand2)); -} - -rtx -gen_ashlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, HImode, operand1, operand2)); -} - -rtx -gen_ashlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, QImode, operand1, operand2)); -} - -rtx -gen_ashrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, SImode, operand1, operand2)); -} - -rtx -gen_ashrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, HImode, operand1, operand2)); -} - -rtx -gen_ashrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, QImode, operand1, operand2)); -} - -rtx -gen_lshlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, SImode, operand1, operand2)); -} - -rtx -gen_lshlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, HImode, operand1, operand2)); -} - -rtx -gen_lshlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, QImode, operand1, operand2)); -} - -rtx -gen_lshrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, SImode, operand1, operand2)); -} - -rtx -gen_lshrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, HImode, operand1, operand2)); -} - -rtx -gen_lshrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, QImode, operand1, operand2)); -} - -rtx -gen_rotlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, SImode, operand1, operand2)); -} - -rtx -gen_rotlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, HImode, operand1, operand2)); -} - -rtx -gen_rotlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, QImode, operand1, operand2)); -} - -rtx -gen_rotrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, SImode, operand1, operand2)); -} - -rtx -gen_rotrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, HImode, operand1, operand2)); -} - -rtx -gen_rotrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, QImode, operand1, operand2)); -} - -rtx -gen_extv (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTRACT, SImode, operand1, operand2, operand3)); -} - -rtx -gen_extzv (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTRACT, SImode, operand1, operand2, operand3)); -} - -rtx -gen_insv (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (ZERO_EXTRACT, SImode, operand0, operand1, operand2), operand3); -} - -rtx -gen_seq (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (EQ, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sne (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NE, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GT, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgtu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GTU, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_slt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LT, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sltu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LTU, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sge (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GE, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgeu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GEU, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sle (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LE, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sleu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LEU, QImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_beq (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (EQ, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bne (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (NE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GT, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgtu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GTU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_blt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LT, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bltu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LTU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bge (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgeu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GEU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_ble (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bleu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LEU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, operand0)); -} - -rtx -gen_tablejump (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ -#ifdef CASE_VECTOR_PC_RELATIVE - operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]); -#endif -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, operand0), - gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, operand1))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_decrement_and_branch_until_zero (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GE, VOIDmode, gen_rtx (PLUS, SImode, operand0, constm1_rtx), const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand1), pc_rtx)), - gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, operand0, constm1_rtx)))); -} - -rtx -gen_call (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_call_insn (gen_rtx (CALL, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_call_value (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_call_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (CALL, VOIDmode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_untyped_call (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (CALL, VOIDmode, operand0, const0_rtx), - operand1, - operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_blockage () -{ - return gen_rtx (UNSPEC_VOLATILE, VOIDmode, gen_rtvec (1, - const0_rtx), 0); -} - -rtx -gen_nop () -{ - return const0_rtx; -} - -rtx -gen_probe () -{ - return gen_rtx (REG, SImode, 15); -} - -rtx -gen_return () -{ - return gen_rtx (RETURN, VOIDmode); -} - -rtx -gen_indirect_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, operand0); -} - -rtx -gen_tstxf (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_cmpxf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (CONSTANT_P (operands[0])) - operands[0] = force_const_mem (XFmode, operands[0]); - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extendsfxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, XFmode, operand1)); -} - -rtx -gen_extenddfxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, XFmode, operand1)); -} - -rtx -gen_truncxfdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, DFmode, operand1)); -} - -rtx -gen_truncxfsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, SFmode, operand1)); -} - -rtx -gen_floatsixf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, XFmode, operand1)); -} - -rtx -gen_floathixf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, XFmode, operand1)); -} - -rtx -gen_floatqixf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, XFmode, operand1)); -} - -rtx -gen_ftruncxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, XFmode, operand1)); -} - -rtx -gen_fixxfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, operand1)); -} - -rtx -gen_fixxfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, operand1)); -} - -rtx -gen_fixxfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, operand1)); -} - -rtx -gen_addxf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, XFmode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_subxf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, XFmode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_mulxf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, XFmode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_divxf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, XFmode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_negxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, XFmode, operand1)); -} - -rtx -gen_absxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, XFmode, operand1)); -} - -rtx -gen_sqrtxf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SQRT, XFmode, operand1)); -} - - - -void -add_clobbers (pattern, insn_code_number) - rtx pattern; - int insn_code_number; -{ - int i; - - switch (insn_code_number) - { - case 72: - case 71: - case 70: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)); - XVECEXP (pattern, 0, 2) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)); - break; - - case 18: - case 15: - case 9: - case 6: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)); - break; - - default: - abort (); - } -} diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-extract.c b/gnu/usr.bin/gcc2/arch/m68k/insn-extract.c deleted file mode 100644 index 82338e52e32..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-extract.c +++ /dev/null @@ -1,558 +0,0 @@ -/* Generated automatically by the program `genextract' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" - -static rtx junk; -extern rtx recog_operand[]; -extern rtx *recog_operand_loc[]; -extern rtx *recog_dup_loc[]; -extern char recog_dup_num[]; -extern -#ifdef __GNUC__ -__volatile__ -#endif -void fatal_insn_not_found (); - -void -insn_extract (insn) - rtx insn; -{ - register rtx *ro = recog_operand; - register rtx **ro_loc = recog_operand_loc; - rtx pat = PATTERN (insn); - switch (INSN_CODE (insn)) - { - case -1: - fatal_insn_not_found (insn); - - case 305: - case 304: - case 303: - case 302: - case 301: - case 300: - case 299: -#if __GNUC__ > 1 && !defined (bcopy) -#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#endif - bcopy (&XVECEXP (pat, 0, 0), ro, - sizeof (rtx) * XVECLEN (pat, 0)); - break; - - case 317: - case 315: - case 309: - case 308: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (XEXP (pat, 1), 1), 1)); - break; - - case 316: - case 314: - case 313: - case 312: - case 311: - case 310: - case 307: - case 306: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 296: - case 295: - case 294: - case 293: - break; - - case 285: - case 284: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0); - recog_dup_num[0] = 0; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[1] = 0; - break; - - case 283: - case 282: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0); - recog_dup_num[0] = 0; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[1] = 0; - break; - - case 281: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0)); - break; - - case 280: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0)); - break; - - case 278: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 277: - case 276: - case 275: - case 274: - case 273: - case 272: - case 271: - case 270: - case 269: - case 268: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 2), 0)); - break; - - case 267: - case 266: - case 265: - case 264: - case 263: - case 262: - case 261: - case 260: - case 259: - case 258: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 247: - case 246: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 2)); - break; - - case 244: - case 243: - case 239: - case 238: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 0), 2)); - break; - - case 237: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 0), 2)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (pat, 1), 1)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 0), 0); - recog_dup_num[0] = 0; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1); - recog_dup_num[1] = 1; - recog_dup_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 0), 2); - recog_dup_num[2] = 2; - break; - - case 242: - case 241: - case 236: - case 235: - case 234: - case 233: - case 232: - case 231: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (pat, 1), 2)); - break; - - case 245: - case 240: - case 230: - case 229: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 0), 2)); - ro[3] = *(ro_loc[3] = &XEXP (pat, 1)); - break; - - case 190: - case 188: - case 172: - case 170: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - recog_dup_loc[0] = &XEXP (XEXP (pat, 1), 0); - recog_dup_num[0] = 0; - break; - - case 146: - case 145: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 1), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1); - recog_dup_num[1] = 2; - break; - - case 144: - case 141: - case 132: - case 129: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - break; - - case 143: - case 140: - case 131: - case 128: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 0), 1), 0)); - break; - - case 120: - case 117: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 1), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0), 0), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0), 1); - recog_dup_num[1] = 2; - break; - - case 119: - case 116: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 1), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0), 0), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0), 1), 0); - recog_dup_num[1] = 2; - break; - - case 114: - case 111: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 113: - case 110: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 167: - case 164: - case 160: - case 157: - case 153: - case 150: - case 90: - case 87: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - recog_dup_loc[0] = &XEXP (XEXP (pat, 1), 1); - recog_dup_num[0] = 0; - break; - - case 228: - case 226: - case 223: - case 221: - case 218: - case 216: - case 211: - case 209: - case 204: - case 202: - case 197: - case 195: - case 166: - case 163: - case 159: - case 156: - case 152: - case 149: - case 102: - case 100: - case 89: - case 86: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - recog_dup_loc[0] = &XEXP (XEXP (pat, 1), 0); - recog_dup_num[0] = 0; - break; - - case 98: - case 84: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 339: - case 337: - case 335: - case 333: - case 291: - case 290: - case 227: - case 225: - case 224: - case 222: - case 220: - case 219: - case 217: - case 215: - case 214: - case 213: - case 212: - case 210: - case 208: - case 207: - case 206: - case 205: - case 203: - case 201: - case 200: - case 199: - case 198: - case 196: - case 194: - case 193: - case 192: - case 191: - case 165: - case 162: - case 161: - case 158: - case 155: - case 154: - case 151: - case 148: - case 147: - case 142: - case 139: - case 138: - case 137: - case 135: - case 134: - case 130: - case 127: - case 126: - case 125: - case 123: - case 122: - case 112: - case 109: - case 108: - case 107: - case 105: - case 104: - case 101: - case 99: - case 97: - case 96: - case 95: - case 93: - case 92: - case 88: - case 85: - case 83: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 82: - case 81: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - break; - - case 72: - case 71: - case 70: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 2), 0)); - break; - - case 342: - case 341: - case 340: - case 331: - case 330: - case 329: - case 328: - case 327: - case 326: - case 325: - case 324: - case 323: - case 322: - case 321: - case 189: - case 187: - case 186: - case 185: - case 184: - case 182: - case 181: - case 179: - case 178: - case 177: - case 175: - case 174: - case 171: - case 169: - case 168: - case 80: - case 79: - case 78: - case 77: - case 76: - case 75: - case 74: - case 73: - case 69: - case 68: - case 67: - case 66: - case 65: - case 64: - case 62: - case 61: - case 59: - case 58: - case 57: - case 55: - case 54: - case 52: - case 51: - case 50: - case 49: - case 48: - case 47: - case 43: - case 42: - case 41: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 33: - case 31: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (pat, 1)); - break; - - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 27: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - break; - - case 25: - case 24: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 2)); - break; - - case 23: - case 22: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 2), 1), 0)); - break; - - case 21: - case 20: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 2), 1)); - break; - - case 18: - case 15: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 320: - case 19: - case 16: - case 13: - case 12: - case 11: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 9: - case 6: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 318: - case 297: - case 10: - case 7: - case 4: - case 3: - case 2: - ro[0] = *(ro_loc[0] = &XEXP (pat, 1)); - break; - - case 298: - case 288: - case 287: - case 40: - case 39: - case 38: - case 37: - case 35: - case 34: - case 32: - case 30: - case 29: - case 26: - case 1: - case 0: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (pat, 1)); - break; - - default: - abort (); - } -} diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-flags.h b/gnu/usr.bin/gcc2/arch/m68k/insn-flags.h deleted file mode 100644 index 13cb48ec061..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-flags.h +++ /dev/null @@ -1,537 +0,0 @@ -/* Generated automatically by the program `genflags' -from the machine description file `md'. */ - -#define HAVE_tstsi 1 -#define HAVE_tsthi 1 -#define HAVE_tstqi 1 -#define HAVE_tstsf (TARGET_68881 || TARGET_FPA) -#define HAVE_tstsf_fpa (TARGET_FPA) -#define HAVE_tstdf (TARGET_68881 || TARGET_FPA) -#define HAVE_tstdf_fpa (TARGET_FPA) -#define HAVE_cmpsi 1 -#define HAVE_cmphi 1 -#define HAVE_cmpqi 1 -#define HAVE_cmpdf (TARGET_68881 || TARGET_FPA) -#define HAVE_cmpdf_fpa (TARGET_FPA) -#define HAVE_cmpsf (TARGET_68881 || TARGET_FPA) -#define HAVE_cmpsf_fpa (TARGET_FPA) -#define HAVE_movsi 1 -#define HAVE_movhi 1 -#define HAVE_movstricthi 1 -#define HAVE_movqi 1 -#define HAVE_movstrictqi 1 -#define HAVE_movsf 1 -#define HAVE_movdf 1 -#define HAVE_movxf 1 -#define HAVE_movdi 1 -#define HAVE_pushasi 1 -#define HAVE_truncsiqi2 1 -#define HAVE_trunchiqi2 1 -#define HAVE_truncsihi2 1 -#define HAVE_zero_extendhisi2 1 -#define HAVE_zero_extendqihi2 1 -#define HAVE_zero_extendqisi2 1 -#define HAVE_extendhisi2 1 -#define HAVE_extendqihi2 1 -#define HAVE_extendqisi2 (TARGET_68020) -#define HAVE_extendsfdf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_truncdfsf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_floatsisf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_floatsidf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_floathisf2 (TARGET_68881) -#define HAVE_floathidf2 (TARGET_68881) -#define HAVE_floatqisf2 (TARGET_68881) -#define HAVE_floatqidf2 (TARGET_68881) -#define HAVE_fix_truncdfsi2 (TARGET_68040) -#define HAVE_fix_truncdfhi2 (TARGET_68040) -#define HAVE_fix_truncdfqi2 (TARGET_68040) -#define HAVE_ftruncdf2 (TARGET_68881 && !TARGET_68040) -#define HAVE_ftruncsf2 (TARGET_68881 && !TARGET_68040) -#define HAVE_fixsfqi2 (TARGET_68881) -#define HAVE_fixsfhi2 (TARGET_68881) -#define HAVE_fixsfsi2 (TARGET_68881) -#define HAVE_fixdfqi2 (TARGET_68881) -#define HAVE_fixdfhi2 (TARGET_68881) -#define HAVE_fixdfsi2 (TARGET_68881) -#define HAVE_addsi3 1 -#define HAVE_addhi3 1 -#define HAVE_addqi3 1 -#define HAVE_adddf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_addsf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_subsi3 1 -#define HAVE_subhi3 1 -#define HAVE_subqi3 1 -#define HAVE_subdf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_subsf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_mulhi3 1 -#define HAVE_mulhisi3 1 -#define HAVE_mulsi3 (TARGET_68020) -#define HAVE_umulhisi3 1 -#define HAVE_umulsidi3 (TARGET_68020) -#define HAVE_mulsidi3 (TARGET_68020) -#define HAVE_muldf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_mulsf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_divhi3 1 -#define HAVE_divhisi3 1 -#define HAVE_udivhi3 1 -#define HAVE_udivhisi3 1 -#define HAVE_divdf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_divsf3 (TARGET_68881 || TARGET_FPA) -#define HAVE_modhi3 1 -#define HAVE_modhisi3 1 -#define HAVE_umodhi3 1 -#define HAVE_umodhisi3 1 -#define HAVE_divmodsi4 (TARGET_68020) -#define HAVE_udivmodsi4 (TARGET_68020) -#define HAVE_andsi3 1 -#define HAVE_andhi3 1 -#define HAVE_andqi3 1 -#define HAVE_iorsi3 1 -#define HAVE_iorhi3 1 -#define HAVE_iorqi3 1 -#define HAVE_xorsi3 1 -#define HAVE_xorhi3 1 -#define HAVE_xorqi3 1 -#define HAVE_negsi2 1 -#define HAVE_neghi2 1 -#define HAVE_negqi2 1 -#define HAVE_negsf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_negdf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_sqrtdf2 (TARGET_68881) -#define HAVE_abssf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_absdf2 (TARGET_68881 || TARGET_FPA) -#define HAVE_one_cmplsi2 1 -#define HAVE_one_cmplhi2 1 -#define HAVE_one_cmplqi2 1 -#define HAVE_ashlsi3 1 -#define HAVE_ashlhi3 1 -#define HAVE_ashlqi3 1 -#define HAVE_ashrsi3 1 -#define HAVE_ashrhi3 1 -#define HAVE_ashrqi3 1 -#define HAVE_lshlsi3 1 -#define HAVE_lshlhi3 1 -#define HAVE_lshlqi3 1 -#define HAVE_lshrsi3 1 -#define HAVE_lshrhi3 1 -#define HAVE_lshrqi3 1 -#define HAVE_rotlsi3 1 -#define HAVE_rotlhi3 1 -#define HAVE_rotlqi3 1 -#define HAVE_rotrsi3 1 -#define HAVE_rotrhi3 1 -#define HAVE_rotrqi3 1 -#define HAVE_extv (TARGET_68020 && TARGET_BITFIELD) -#define HAVE_extzv (TARGET_68020 && TARGET_BITFIELD) -#define HAVE_insv (TARGET_68020 && TARGET_BITFIELD) -#define HAVE_seq 1 -#define HAVE_sne 1 -#define HAVE_sgt 1 -#define HAVE_sgtu 1 -#define HAVE_slt 1 -#define HAVE_sltu 1 -#define HAVE_sge 1 -#define HAVE_sgeu 1 -#define HAVE_sle 1 -#define HAVE_sleu 1 -#define HAVE_beq 1 -#define HAVE_bne 1 -#define HAVE_bgt 1 -#define HAVE_bgtu 1 -#define HAVE_blt 1 -#define HAVE_bltu 1 -#define HAVE_bge 1 -#define HAVE_bgeu 1 -#define HAVE_ble 1 -#define HAVE_bleu 1 -#define HAVE_jump 1 -#define HAVE_tablejump 1 -#define HAVE_decrement_and_branch_until_zero (find_reg_note (insn, REG_NONNEG, 0)) -#define HAVE_call 1 -#define HAVE_call_value 1 -#define HAVE_untyped_call (NEEDS_UNTYPED_CALL) -#define HAVE_blockage 1 -#define HAVE_nop 1 -#define HAVE_probe (NEED_PROBE) -#define HAVE_return (USE_RETURN_INSN) -#define HAVE_indirect_jump 1 -#define HAVE_tstxf (TARGET_68881) -#define HAVE_cmpxf (TARGET_68881) -#define HAVE_extendsfxf2 (TARGET_68881) -#define HAVE_extenddfxf2 (TARGET_68881) -#define HAVE_truncxfdf2 (TARGET_68881) -#define HAVE_truncxfsf2 (TARGET_68881) -#define HAVE_floatsixf2 (TARGET_68881) -#define HAVE_floathixf2 (TARGET_68881) -#define HAVE_floatqixf2 (TARGET_68881) -#define HAVE_ftruncxf2 (TARGET_68881) -#define HAVE_fixxfqi2 (TARGET_68881) -#define HAVE_fixxfhi2 (TARGET_68881) -#define HAVE_fixxfsi2 (TARGET_68881) -#define HAVE_addxf3 (TARGET_68881) -#define HAVE_subxf3 (TARGET_68881) -#define HAVE_mulxf3 (TARGET_68881) -#define HAVE_divxf3 (TARGET_68881) -#define HAVE_negxf2 (TARGET_68881) -#define HAVE_absxf2 (TARGET_68881) -#define HAVE_sqrtxf2 (TARGET_68881) - -#ifndef NO_MD_PROTOTYPES -extern rtx gen_tstsi PROTO((rtx)); -extern rtx gen_tsthi PROTO((rtx)); -extern rtx gen_tstqi PROTO((rtx)); -extern rtx gen_tstsf PROTO((rtx)); -extern rtx gen_tstsf_fpa PROTO((rtx)); -extern rtx gen_tstdf PROTO((rtx)); -extern rtx gen_tstdf_fpa PROTO((rtx)); -extern rtx gen_cmpsi PROTO((rtx, rtx)); -extern rtx gen_cmphi PROTO((rtx, rtx)); -extern rtx gen_cmpqi PROTO((rtx, rtx)); -extern rtx gen_cmpdf PROTO((rtx, rtx)); -extern rtx gen_cmpdf_fpa PROTO((rtx, rtx)); -extern rtx gen_cmpsf PROTO((rtx, rtx)); -extern rtx gen_cmpsf_fpa PROTO((rtx, rtx)); -extern rtx gen_movsi PROTO((rtx, rtx)); -extern rtx gen_movhi PROTO((rtx, rtx)); -extern rtx gen_movstricthi PROTO((rtx, rtx)); -extern rtx gen_movqi PROTO((rtx, rtx)); -extern rtx gen_movstrictqi PROTO((rtx, rtx)); -extern rtx gen_movsf PROTO((rtx, rtx)); -extern rtx gen_movdf PROTO((rtx, rtx)); -extern rtx gen_movxf PROTO((rtx, rtx)); -extern rtx gen_movdi PROTO((rtx, rtx)); -extern rtx gen_pushasi PROTO((rtx, rtx)); -extern rtx gen_truncsiqi2 PROTO((rtx, rtx)); -extern rtx gen_trunchiqi2 PROTO((rtx, rtx)); -extern rtx gen_truncsihi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_extendsfdf2 PROTO((rtx, rtx)); -extern rtx gen_truncdfsf2 PROTO((rtx, rtx)); -extern rtx gen_floatsisf2 PROTO((rtx, rtx)); -extern rtx gen_floatsidf2 PROTO((rtx, rtx)); -extern rtx gen_floathisf2 PROTO((rtx, rtx)); -extern rtx gen_floathidf2 PROTO((rtx, rtx)); -extern rtx gen_floatqisf2 PROTO((rtx, rtx)); -extern rtx gen_floatqidf2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfsi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfhi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfqi2 PROTO((rtx, rtx)); -extern rtx gen_ftruncdf2 PROTO((rtx, rtx)); -extern rtx gen_ftruncsf2 PROTO((rtx, rtx)); -extern rtx gen_fixsfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixsfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixsfsi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfsi2 PROTO((rtx, rtx)); -extern rtx gen_addsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_adddf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umulhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_muldf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_modhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_modhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umodhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umodhisi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divmodsi4 PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_udivmodsi4 PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_andsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_negsi2 PROTO((rtx, rtx)); -extern rtx gen_neghi2 PROTO((rtx, rtx)); -extern rtx gen_negqi2 PROTO((rtx, rtx)); -extern rtx gen_negsf2 PROTO((rtx, rtx)); -extern rtx gen_negdf2 PROTO((rtx, rtx)); -extern rtx gen_sqrtdf2 PROTO((rtx, rtx)); -extern rtx gen_abssf2 PROTO((rtx, rtx)); -extern rtx gen_absdf2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplsi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplhi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplqi2 PROTO((rtx, rtx)); -extern rtx gen_ashlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_extv PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_extzv PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_insv PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_seq PROTO((rtx)); -extern rtx gen_sne PROTO((rtx)); -extern rtx gen_sgt PROTO((rtx)); -extern rtx gen_sgtu PROTO((rtx)); -extern rtx gen_slt PROTO((rtx)); -extern rtx gen_sltu PROTO((rtx)); -extern rtx gen_sge PROTO((rtx)); -extern rtx gen_sgeu PROTO((rtx)); -extern rtx gen_sle PROTO((rtx)); -extern rtx gen_sleu PROTO((rtx)); -extern rtx gen_beq PROTO((rtx)); -extern rtx gen_bne PROTO((rtx)); -extern rtx gen_bgt PROTO((rtx)); -extern rtx gen_bgtu PROTO((rtx)); -extern rtx gen_blt PROTO((rtx)); -extern rtx gen_bltu PROTO((rtx)); -extern rtx gen_bge PROTO((rtx)); -extern rtx gen_bgeu PROTO((rtx)); -extern rtx gen_ble PROTO((rtx)); -extern rtx gen_bleu PROTO((rtx)); -extern rtx gen_jump PROTO((rtx)); -extern rtx gen_tablejump PROTO((rtx, rtx)); -extern rtx gen_decrement_and_branch_until_zero PROTO((rtx, rtx)); -extern rtx gen_untyped_call PROTO((rtx, rtx, rtx)); -extern rtx gen_blockage PROTO((void)); -extern rtx gen_nop PROTO((void)); -extern rtx gen_probe PROTO((void)); -extern rtx gen_return PROTO((void)); -extern rtx gen_indirect_jump PROTO((rtx)); -extern rtx gen_tstxf PROTO((rtx)); -extern rtx gen_cmpxf PROTO((rtx, rtx)); -extern rtx gen_extendsfxf2 PROTO((rtx, rtx)); -extern rtx gen_extenddfxf2 PROTO((rtx, rtx)); -extern rtx gen_truncxfdf2 PROTO((rtx, rtx)); -extern rtx gen_truncxfsf2 PROTO((rtx, rtx)); -extern rtx gen_floatsixf2 PROTO((rtx, rtx)); -extern rtx gen_floathixf2 PROTO((rtx, rtx)); -extern rtx gen_floatqixf2 PROTO((rtx, rtx)); -extern rtx gen_ftruncxf2 PROTO((rtx, rtx)); -extern rtx gen_fixxfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixxfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixxfsi2 PROTO((rtx, rtx)); -extern rtx gen_addxf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subxf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulxf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divxf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_negxf2 PROTO((rtx, rtx)); -extern rtx gen_absxf2 PROTO((rtx, rtx)); -extern rtx gen_sqrtxf2 PROTO((rtx, rtx)); - -#ifdef MD_CALL_PROTOTYPES -extern rtx gen_call PROTO((rtx, rtx)); -extern rtx gen_call_value PROTO((rtx, rtx, rtx)); - -#else /* !MD_CALL_PROTOTYPES */ -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* !MD_CALL_PROTOTYPES */ - -#else /* NO_MD_PROTOTYPES */ -extern rtx gen_tstsi (); -extern rtx gen_tsthi (); -extern rtx gen_tstqi (); -extern rtx gen_tstsf (); -extern rtx gen_tstsf_fpa (); -extern rtx gen_tstdf (); -extern rtx gen_tstdf_fpa (); -extern rtx gen_cmpsi (); -extern rtx gen_cmphi (); -extern rtx gen_cmpqi (); -extern rtx gen_cmpdf (); -extern rtx gen_cmpdf_fpa (); -extern rtx gen_cmpsf (); -extern rtx gen_cmpsf_fpa (); -extern rtx gen_movsi (); -extern rtx gen_movhi (); -extern rtx gen_movstricthi (); -extern rtx gen_movqi (); -extern rtx gen_movstrictqi (); -extern rtx gen_movsf (); -extern rtx gen_movdf (); -extern rtx gen_movxf (); -extern rtx gen_movdi (); -extern rtx gen_pushasi (); -extern rtx gen_truncsiqi2 (); -extern rtx gen_trunchiqi2 (); -extern rtx gen_truncsihi2 (); -extern rtx gen_zero_extendhisi2 (); -extern rtx gen_zero_extendqihi2 (); -extern rtx gen_zero_extendqisi2 (); -extern rtx gen_extendhisi2 (); -extern rtx gen_extendqihi2 (); -extern rtx gen_extendqisi2 (); -extern rtx gen_extendsfdf2 (); -extern rtx gen_truncdfsf2 (); -extern rtx gen_floatsisf2 (); -extern rtx gen_floatsidf2 (); -extern rtx gen_floathisf2 (); -extern rtx gen_floathidf2 (); -extern rtx gen_floatqisf2 (); -extern rtx gen_floatqidf2 (); -extern rtx gen_fix_truncdfsi2 (); -extern rtx gen_fix_truncdfhi2 (); -extern rtx gen_fix_truncdfqi2 (); -extern rtx gen_ftruncdf2 (); -extern rtx gen_ftruncsf2 (); -extern rtx gen_fixsfqi2 (); -extern rtx gen_fixsfhi2 (); -extern rtx gen_fixsfsi2 (); -extern rtx gen_fixdfqi2 (); -extern rtx gen_fixdfhi2 (); -extern rtx gen_fixdfsi2 (); -extern rtx gen_addsi3 (); -extern rtx gen_addhi3 (); -extern rtx gen_addqi3 (); -extern rtx gen_adddf3 (); -extern rtx gen_addsf3 (); -extern rtx gen_subsi3 (); -extern rtx gen_subhi3 (); -extern rtx gen_subqi3 (); -extern rtx gen_subdf3 (); -extern rtx gen_subsf3 (); -extern rtx gen_mulhi3 (); -extern rtx gen_mulhisi3 (); -extern rtx gen_mulsi3 (); -extern rtx gen_umulhisi3 (); -extern rtx gen_umulsidi3 (); -extern rtx gen_mulsidi3 (); -extern rtx gen_muldf3 (); -extern rtx gen_mulsf3 (); -extern rtx gen_divhi3 (); -extern rtx gen_divhisi3 (); -extern rtx gen_udivhi3 (); -extern rtx gen_udivhisi3 (); -extern rtx gen_divdf3 (); -extern rtx gen_divsf3 (); -extern rtx gen_modhi3 (); -extern rtx gen_modhisi3 (); -extern rtx gen_umodhi3 (); -extern rtx gen_umodhisi3 (); -extern rtx gen_divmodsi4 (); -extern rtx gen_udivmodsi4 (); -extern rtx gen_andsi3 (); -extern rtx gen_andhi3 (); -extern rtx gen_andqi3 (); -extern rtx gen_iorsi3 (); -extern rtx gen_iorhi3 (); -extern rtx gen_iorqi3 (); -extern rtx gen_xorsi3 (); -extern rtx gen_xorhi3 (); -extern rtx gen_xorqi3 (); -extern rtx gen_negsi2 (); -extern rtx gen_neghi2 (); -extern rtx gen_negqi2 (); -extern rtx gen_negsf2 (); -extern rtx gen_negdf2 (); -extern rtx gen_sqrtdf2 (); -extern rtx gen_abssf2 (); -extern rtx gen_absdf2 (); -extern rtx gen_one_cmplsi2 (); -extern rtx gen_one_cmplhi2 (); -extern rtx gen_one_cmplqi2 (); -extern rtx gen_ashlsi3 (); -extern rtx gen_ashlhi3 (); -extern rtx gen_ashlqi3 (); -extern rtx gen_ashrsi3 (); -extern rtx gen_ashrhi3 (); -extern rtx gen_ashrqi3 (); -extern rtx gen_lshlsi3 (); -extern rtx gen_lshlhi3 (); -extern rtx gen_lshlqi3 (); -extern rtx gen_lshrsi3 (); -extern rtx gen_lshrhi3 (); -extern rtx gen_lshrqi3 (); -extern rtx gen_rotlsi3 (); -extern rtx gen_rotlhi3 (); -extern rtx gen_rotlqi3 (); -extern rtx gen_rotrsi3 (); -extern rtx gen_rotrhi3 (); -extern rtx gen_rotrqi3 (); -extern rtx gen_extv (); -extern rtx gen_extzv (); -extern rtx gen_insv (); -extern rtx gen_seq (); -extern rtx gen_sne (); -extern rtx gen_sgt (); -extern rtx gen_sgtu (); -extern rtx gen_slt (); -extern rtx gen_sltu (); -extern rtx gen_sge (); -extern rtx gen_sgeu (); -extern rtx gen_sle (); -extern rtx gen_sleu (); -extern rtx gen_beq (); -extern rtx gen_bne (); -extern rtx gen_bgt (); -extern rtx gen_bgtu (); -extern rtx gen_blt (); -extern rtx gen_bltu (); -extern rtx gen_bge (); -extern rtx gen_bgeu (); -extern rtx gen_ble (); -extern rtx gen_bleu (); -extern rtx gen_jump (); -extern rtx gen_tablejump (); -extern rtx gen_decrement_and_branch_until_zero (); -extern rtx gen_untyped_call (); -extern rtx gen_blockage (); -extern rtx gen_nop (); -extern rtx gen_probe (); -extern rtx gen_return (); -extern rtx gen_indirect_jump (); -extern rtx gen_tstxf (); -extern rtx gen_cmpxf (); -extern rtx gen_extendsfxf2 (); -extern rtx gen_extenddfxf2 (); -extern rtx gen_truncxfdf2 (); -extern rtx gen_truncxfsf2 (); -extern rtx gen_floatsixf2 (); -extern rtx gen_floathixf2 (); -extern rtx gen_floatqixf2 (); -extern rtx gen_ftruncxf2 (); -extern rtx gen_fixxfqi2 (); -extern rtx gen_fixxfhi2 (); -extern rtx gen_fixxfsi2 (); -extern rtx gen_addxf3 (); -extern rtx gen_subxf3 (); -extern rtx gen_mulxf3 (); -extern rtx gen_divxf3 (); -extern rtx gen_negxf2 (); -extern rtx gen_absxf2 (); -extern rtx gen_sqrtxf2 (); -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* NO_MD_PROTOTYPES */ diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-opinit.c b/gnu/usr.bin/gcc2/arch/m68k/insn-opinit.c deleted file mode 100644 index 83f29384a2a..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-opinit.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Generated automatically by the program `genopinit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "flags.h" -#include "insn-flags.h" -#include "insn-codes.h" -#include "insn-config.h" -#include "recog.h" -#include "expr.h" -#include "reload.h" - -void -init_all_optabs () -{ - tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi; - tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi; - tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi; - if (HAVE_tstsf) - tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf; - if (HAVE_tstdf) - tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf; - cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi; - cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi; - cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi; - if (HAVE_cmpdf) - cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf; - if (HAVE_cmpsf) - cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf; - mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi; - mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi; - movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi; - mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi; - movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi; - mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf; - mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf; - mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf; - mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi; - extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2; - extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2; - extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2; - extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2; - extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2; - if (HAVE_extendqisi2) - extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2; - if (HAVE_extendsfdf2) - extendtab[(int) DFmode][(int) SFmode][0] = CODE_FOR_extendsfdf2; - if (HAVE_floatsisf2) - floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2; - if (HAVE_floatsidf2) - floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2; - if (HAVE_floathisf2) - floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2; - if (HAVE_floathidf2) - floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2; - if (HAVE_floatqisf2) - floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2; - if (HAVE_floatqidf2) - floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2; - if (HAVE_fix_truncdfsi2) - fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2; - if (HAVE_fix_truncdfhi2) - fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2; - if (HAVE_fix_truncdfqi2) - fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2; - if (HAVE_ftruncdf2) - ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2; - if (HAVE_ftruncsf2) - ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2; - if (HAVE_fixsfqi2) - fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2; - if (HAVE_fixsfhi2) - fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2; - if (HAVE_fixsfsi2) - fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2; - if (HAVE_fixdfqi2) - fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2; - if (HAVE_fixdfhi2) - fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2; - if (HAVE_fixdfsi2) - fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2; - add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3; - add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3; - add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3; - if (HAVE_adddf3) - add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3; - if (HAVE_addsf3) - add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3; - sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3; - sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3; - sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3; - if (HAVE_subdf3) - sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3; - if (HAVE_subsf3) - sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3; - smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3; - smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3; - if (HAVE_mulsi3) - smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3; - umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3; - if (HAVE_umulsidi3) - umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3; - if (HAVE_mulsidi3) - smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3; - if (HAVE_muldf3) - smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3; - if (HAVE_mulsf3) - smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3; - sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3; - udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3; - if (HAVE_divdf3) - flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3; - if (HAVE_divsf3) - flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3; - smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3; - umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3; - if (HAVE_divmodsi4) - sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4; - if (HAVE_udivmodsi4) - udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4; - and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3; - and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3; - and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3; - ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3; - ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3; - ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3; - xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3; - xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3; - xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3; - neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2; - neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2; - neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2; - if (HAVE_negsf2) - neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2; - if (HAVE_negdf2) - neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2; - if (HAVE_sqrtdf2) - sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2; - if (HAVE_abssf2) - abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2; - if (HAVE_absdf2) - abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2; - one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2; - one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2; - one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2; - ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3; - ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3; - ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3; - ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3; - ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3; - ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3; - lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3; - lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3; - lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3; - lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3; - lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3; - lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3; - rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3; - rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3; - rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3; - rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3; - rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3; - rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3; - setcc_gen_code[(int) EQ] = CODE_FOR_seq; - setcc_gen_code[(int) NE] = CODE_FOR_sne; - setcc_gen_code[(int) GT] = CODE_FOR_sgt; - setcc_gen_code[(int) GTU] = CODE_FOR_sgtu; - setcc_gen_code[(int) LT] = CODE_FOR_slt; - setcc_gen_code[(int) LTU] = CODE_FOR_sltu; - setcc_gen_code[(int) GE] = CODE_FOR_sge; - setcc_gen_code[(int) GEU] = CODE_FOR_sgeu; - setcc_gen_code[(int) LE] = CODE_FOR_sle; - setcc_gen_code[(int) LEU] = CODE_FOR_sleu; - bcc_gen_fctn[(int) EQ] = gen_beq; - bcc_gen_fctn[(int) NE] = gen_bne; - bcc_gen_fctn[(int) GT] = gen_bgt; - bcc_gen_fctn[(int) GTU] = gen_bgtu; - bcc_gen_fctn[(int) LT] = gen_blt; - bcc_gen_fctn[(int) LTU] = gen_bltu; - bcc_gen_fctn[(int) GE] = gen_bge; - bcc_gen_fctn[(int) GEU] = gen_bgeu; - bcc_gen_fctn[(int) LE] = gen_ble; - bcc_gen_fctn[(int) LEU] = gen_bleu; - if (HAVE_tstxf) - tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf; - if (HAVE_cmpxf) - cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf; - if (HAVE_extendsfxf2) - extendtab[(int) XFmode][(int) SFmode][0] = CODE_FOR_extendsfxf2; - if (HAVE_extenddfxf2) - extendtab[(int) XFmode][(int) DFmode][0] = CODE_FOR_extenddfxf2; - if (HAVE_floatsixf2) - floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2; - if (HAVE_floathixf2) - floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2; - if (HAVE_floatqixf2) - floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2; - if (HAVE_ftruncxf2) - ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2; - if (HAVE_fixxfqi2) - fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2; - if (HAVE_fixxfhi2) - fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2; - if (HAVE_fixxfsi2) - fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2; - if (HAVE_addxf3) - add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3; - if (HAVE_subxf3) - sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3; - if (HAVE_mulxf3) - smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3; - if (HAVE_divxf3) - flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3; - if (HAVE_negxf2) - neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2; - if (HAVE_absxf2) - abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2; - if (HAVE_sqrtxf2) - sqrt_optab->handlers[(int) XFmode].insn_code = CODE_FOR_sqrtxf2; -} diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-output.c b/gnu/usr.bin/gcc2/arch/m68k/insn-output.c deleted file mode 100644 index 84070236fff..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-output.c +++ /dev/null @@ -1,7826 +0,0 @@ -/* Generated automatically by the program `genoutput' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" - -#include "conditions.h" -#include "insn-flags.h" -#include "insn-attr.h" - -#include "insn-codes.h" - -#include "recog.h" - -#include -#include "output.h" - -static char * -output_0 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "fmove%.d %f1,%0"; - if (FPA_REG_P (operands[1])) - return "fpmove%.d %1, %x0"; - return output_move_double (operands); -} -} - -static char * -output_1 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return output_move_double (operands); -} -} - -static char * -output_2 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef ISI_OV - /* ISI's assembler fails to handle tstl a0. */ - if (! ADDRESS_REG_P (operands[0])) -#else - if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) -#endif - return "tst%.l %0"; - /* If you think that the 68020 does not support tstl a0, - reread page B-167 of the 68020 manual more carefully. */ - /* On an address reg, cmpw may replace cmpl. */ -#ifdef SGS_CMP_ORDER - return "cmp%.w %0,%#0"; -#else - return "cmp%.w %#0,%0"; -#endif -} -} - -static char * -output_7 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return "ftst%.x %0"; - return "ftst%.s %0"; -} -} - -static char * -output_10 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return "ftst%.x %0"; - return "ftst%.d %0"; -} -} - -static char * -output_11 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return "cmpm%.l %1,%0"; - if (REG_P (operands[1]) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return "cmp%.l %d1,%d0"; -#else - return "cmp%.l %d0,%d1"; -#endif - } -#ifdef SGS_CMP_ORDER - return "cmp%.l %d0,%d1"; -#else - return "cmp%.l %d1,%d0"; -#endif -} -} - -static char * -output_12 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return "cmpm%.w %1,%0"; - if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return "cmp%.w %d1,%d0"; -#else - return "cmp%.w %d0,%d1"; -#endif - } -#ifdef SGS_CMP_ORDER - return "cmp%.w %d0,%d1"; -#else - return "cmp%.w %d1,%d0"; -#endif -} -} - -static char * -output_13 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return "cmpm%.b %1,%0"; - if (REG_P (operands[1]) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return "cmp%.b %d1,%d0"; -#else - return "cmp%.b %d0,%d1"; -#endif - } -#ifdef SGS_CMP_ORDER - return "cmp%.b %d0,%d1"; -#else - return "cmp%.b %d1,%d0"; -#endif -} -} - -static char * -output_16 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return "fcmp%.x %0,%1"; - else - return "fcmp%.d %0,%f1"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.d %1,%f0"; -#else - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return "fcmp%.x %1,%0"; - else - return "fcmp%.d %f1,%0"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.d %f0,%1"; -#endif -} -} - -static char * -output_19 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fcmp%.x %0,%1"; - else - return "fcmp%.s %0,%f1"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.s %1,%f0"; -#else - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fcmp%.x %1,%0"; - else - return "fcmp%.s %f1,%0"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.s %f0,%1"; -#endif -} -} - -static char * -output_20 (operands, insn) - rtx *operands; - rtx insn; -{ - { return output_btst (operands, operands[1], operands[0], insn, 7); } -} - -static char * -output_21 (operands, insn) - rtx *operands; - rtx insn; -{ - { return output_btst (operands, operands[1], operands[0], insn, 31); } -} - -static char * -output_22 (operands, insn) - rtx *operands; - rtx insn; -{ - { return output_btst (operands, operands[1], operands[0], insn, 7); } -} - -static char * -output_23 (operands, insn) - rtx *operands; - rtx insn; -{ - { return output_btst (operands, operands[1], operands[0], insn, 31); } -} - -static char * -output_24 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1])); - return output_btst (operands, operands[1], operands[0], insn, 7); -} -} - -static char * -output_25 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == MEM) - { - operands[0] = adj_offsettable_operand (operands[0], - INTVAL (operands[1]) / 8); - operands[1] = gen_rtx (CONST_INT, VOIDmode, - 7 - INTVAL (operands[1]) % 8); - return output_btst (operands, operands[1], operands[0], insn, 7); - } - operands[1] = gen_rtx (CONST_INT, VOIDmode, - 31 - INTVAL (operands[1])); - return output_btst (operands, operands[1], operands[0], insn, 31); -} -} - -static char * -output_26 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[1] == const0_rtx) - return "clr%.l %0"; - return "pea %a1"; -} -} - -static char * -output_27 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (ADDRESS_REG_P (operands[0])) - return "sub%.l %0,%0"; - /* moveq is faster on the 68000. */ - if (DATA_REG_P (operands[0]) && !TARGET_68020) -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %#0,%0"; -#else - return "moveq %#0,%0"; -#endif - return "clr%.l %0"; -} -} - -static char * -output_29 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (which_alternative == 3) - return "fpmove%.l %x1,fpa0\n\tfpmove%.l fpa0,%x0"; - if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0])) - return "fpmove%.l %x1,%x0"; - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return "clr%.l %0"; - else if (DATA_REG_P (operands[0]) - && INTVAL (operands[1]) < 128 - && INTVAL (operands[1]) >= -128) - { -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %1,%0"; -#else - return "moveq %1,%0"; -#endif - } -#ifndef NO_ADDSUB_Q - else if (DATA_REG_P (operands[0]) - /* Do this with a moveq #N-8, dreg; addq #8,dreg */ - && INTVAL (operands[1]) < 136 - && INTVAL (operands[1]) >= 128) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %1,%0\n\taddq%.w %#8,%0"; -#else - return "moveq %1,%0\n\taddq%.w %#8,%0"; -#endif - } - else if (DATA_REG_P (operands[0]) - /* Do this with a moveq #N+8, dreg; subq #8,dreg */ - && INTVAL (operands[1]) < -128 - && INTVAL (operands[1]) >= -136) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 8); -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %1,%0;subq%.w %#8,%0"; -#else - return "moveq %1,%0;subq%.w %#8,%0"; -#endif - } -#endif - else if (DATA_REG_P (operands[0]) - /* If N is in the right range and is even, then use - moveq #N/2, dreg; addl dreg,dreg */ - && INTVAL (operands[1]) > 127 - && INTVAL (operands[1]) <= 254 - && INTVAL (operands[1]) % 2 == 0) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 2); -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %1,%0\n\tadd%.w %0,%0"; -#else - return "moveq %1,%0\n\tadd%.w %0,%0"; -#endif - } - else if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return "move%.w %1,%0"; - else if (push_operand (operands[0], SImode) - && INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return "pea %a1"; - } - else if ((GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST) - && push_operand (operands[0], SImode)) - return "pea %a1"; - else if ((GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST) - && ADDRESS_REG_P (operands[0])) - return "lea %a1,%0"; - return "move%.l %1,%0"; -} -} - -static char * -output_30 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return "clr%.w %0"; - else if (DATA_REG_P (operands[0]) - && INTVAL (operands[1]) < 128 - && INTVAL (operands[1]) >= -128) - { -#if defined(MOTOROLA) && !defined(CRDS) - return "moveq%.l %1,%0"; -#else - return "moveq %1,%0"; -#endif - } - else if (INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return "move%.w %1,%0"; - } - else if (CONSTANT_P (operands[1])) - return "move%.l %1,%0"; -#ifndef SGS_NO_LI - /* Recognize the insn before a tablejump, one that refers - to a table of offsets. Such an insn will need to refer - to a label on the insn. So output one. Use the label-number - of the table of offsets to generate this label. */ - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF) - && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS - && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS) - { - rtx labelref; - if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF) - labelref = XEXP (XEXP (operands[1], 0), 0); - else - labelref = XEXP (XEXP (operands[1], 0), 1); -#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES) -#ifdef SGS - asm_fprintf (asm_out_file, "\tset %LLI%d,.+2\n", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#else /* not SGS */ - asm_fprintf (asm_out_file, "\t.set %LLI%d,.+2\n", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#endif /* not SGS */ -#else /* SGS_SWITCH_TABLES or not MOTOROLA */ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#ifdef SGS_SWITCH_TABLES - /* Set flag saying we need to define the symbol - LD%n (with value L%n-LI%n) at the end of the switch table. */ - switch_table_difference_label_flag = 1; -#endif /* SGS_SWITCH_TABLES */ -#endif /* SGS_SWITCH_TABLES or not MOTOROLA */ - } -#endif /* SGS_NO_LI */ - return "move%.w %1,%0"; -} -} - -static char * -output_31 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return "clr%.w %0"; - } - return "move%.w %1,%0"; -} -} - -static char * -output_32 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx xoperands[4]; - - /* This is probably useless, since it loses for pushing a struct - of several bytes a byte at a time. */ - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC - && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) - { - xoperands[1] = operands[1]; - xoperands[2] - = gen_rtx (MEM, QImode, - gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); - /* Just pushing a byte puts it in the high byte of the halfword. */ - /* We must put it in the low-order, high-numbered byte. */ - output_asm_insn ("move%.b %1,%-\n\tmove%.b %@,%2", xoperands); - return ""; - } - - /* Moving a byte into an address register is not possible. */ - /* Use d0 as an intermediate, but don't clobber its contents. */ - if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) - { - /* ??? For 2.5, don't allow this choice and use secondary reloads - instead. - - See if the address register is used in the address. If it - is, we have to generate a more complex sequence than those below. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], NULL_RTX)) - { - /* See if the stack pointer is used in the address. If it isn't, - we can push d0 or d1 (the insn can't use both of them) on - the stack, perform our move into d0/d1, copy the byte from d0/1, - and pop d0/1. */ - if (! reg_mentioned_p (stack_pointer_rtx, operands[1])) - { - if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) - return "move%.l %/d0,%-\n\tmove%.b %1,%/d0\n\tmove%.l %/d0,%0\n\tmove%.l %+,%/d0"; - else - return "move%.l %/d1,%-\n\tmove%.b %1,%/d1\n\tmove%.l %/d1,%0\n\tmove%.l %+,%/d1"; - } - else - { - /* Otherwise, we know that d0 cannot be used in the address - (since sp and one address register is). Assume that sp is - being used as a base register and replace the address - register that is our operand[0] with d0. */ - rtx reg_map[FIRST_PSEUDO_REGISTER]; - int i; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_map[i] = 0; - - reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0); - operands[1] = copy_rtx (operands[1]); - replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0); - return "exg %/d0,%0\n\tmove%.b %1,%/d0\n\texg %/d0,%0"; - } - } - - /* If the address of operand 1 uses d0, choose d1 as intermediate. */ - if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) - return "exg %/d1,%0\n\tmove%.b %1,%/d1\n\texg %/d1,%0"; - /* Otherwise d0 is usable. - (An effective address on the 68k can't use two d-regs.) */ - else - return "exg %/d0,%0\n\tmove%.b %1,%/d0\n\texg %/d0,%0"; - } - - /* Likewise for moving from an address reg. */ - if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) - { - /* ??? For 2.5, don't allow this choice and use secondary reloads - instead. - - See if the address register is used in the address. If it - is, we have to generate a more complex sequence than those below. */ - if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1, - operands[0], NULL_RTX)) - { - /* See if the stack pointer is used in the address. If it isn't, - we can push d0 or d1 (the insn can't use both of them) on - the stack, copy the byte to d0/1, perform our move from d0/d1, - and pop d0/1. */ - if (! reg_mentioned_p (stack_pointer_rtx, operands[0])) - { - if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) - return "move%.l %/d0,%-\n\tmove%.l %1,%/d0\n\tmove%.b %/d0,%0\n\tmove%.l %+,%/d0"; - else - return "move%.l %/d1,%-\n\tmove%.l %1,%/d1\n\tmove%.b %/d1,%0\n\tmove%.l %+,%/d1"; - } - else - { - /* Otherwise, we know that d0 cannot be used in the address - (since sp and one address register is). Assume that sp is - being used as a base register and replace the address - register that is our operand[1] with d0. */ - rtx reg_map[FIRST_PSEUDO_REGISTER]; - int i; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_map[i] = 0; - - reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0); - operands[0] = copy_rtx (operands[0]); - replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0); - return "exg %/d0,%1\n\tmove%.b %/d0,%0\n\texg %/d0,%1"; - } - } - - if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) - return "exg %/d1,%1\n\tmove%.b %/d1,%0\n\texg %/d1,%1"; - else - return "exg %/d0,%1\n\tmove%.b %/d0,%0\n\texg %/d0,%1"; - } - - /* clr and st insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - if (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - if (operands[1] == const0_rtx) - return "clr%.b %0"; - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) == -1) - { - CC_STATUS_INIT; - return "st %0"; - } - } - if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) - return "move%.l %1,%0"; - if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) - return "move%.w %1,%0"; - return "move%.b %1,%0"; -} -} - -static char * -output_33 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[1] == const0_rtx - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) - return "clr%.b %0"; - return "move%.b %1,%0"; -} -} - -static char * -output_34 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (which_alternative >= 4) - return "fpmove%.s %1,fpa0\n\tfpmove%.s fpa0,%0"; - if (FPA_REG_P (operands[0])) - { - if (FPA_REG_P (operands[1])) - return "fpmove%.s %x1,%x0"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - else if (FP_REG_P (operands[1])) - return "fmove%.s %1,sp@-\n\tfpmove%.d sp@+, %0"; - return "fpmove%.s %x1,%x0"; - } - if (FPA_REG_P (operands[1])) - { - if (FP_REG_P (operands[0])) - return "fpmove%.s %x1,sp@-\n\tfmove%.s sp@+,%0"; - else - return "fpmove%.s %x1,%x0"; - } - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "f%$move%.x %1,%0"; - else if (ADDRESS_REG_P (operands[1])) - return "move%.l %1,%-\n\tf%$move%.s %+,%0"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - return "f%$move%.s %f1,%0"; - } - if (FP_REG_P (operands[1])) - { - if (ADDRESS_REG_P (operands[0])) - return "fmove%.s %1,%-\n\tmove%.l %+,%0"; - return "fmove%.s %f1,%0"; - } - return "move%.l %1,%0"; -} -} - -static char * -output_35 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (which_alternative == 6) - return "fpmove%.d %x1,fpa0\n\tfpmove%.d fpa0,%x0"; - if (FPA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - if (FP_REG_P (operands[1])) - return "fmove%.d %1,sp@-\n\tfpmove%.d sp@+,%x0"; - return "fpmove%.d %x1,%x0"; - } - else if (FPA_REG_P (operands[1])) - { - if (FP_REG_P(operands[0])) - return "fpmove%.d %x1,sp@-\n\tfmoved sp@+,%0"; - else - return "fpmove%.d %x1,%x0"; - } - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "f%&move%.x %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%-", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "f%&move%.d %+,%0"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - return "f%&move%.d %f1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn ("fmove%.d %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - else - return "fmove%.d %f1,%0"; - } - return output_move_double (operands); -} - -} - -static char * -output_37 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fmove%.x %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - output_asm_insn ("move%.l %1,%-", xoperands); - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%-", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "fmove%.x %+,%0"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return "fmove%.x %1,%0"; - return "fmove%.x %f1,%0"; - } - if (REG_P (operands[0])) - { - output_asm_insn ("fmove%.x %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - output_asm_insn ("move%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - return "fmove%.x %f1,%0"; -} - -} - -static char * -output_38 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fmove%.x %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - output_asm_insn ("move%.l %1,%-", xoperands); - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%-", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "fmove%.x %+,%0"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return "fmove%.x %1,%0"; - return "fmove%.x %f1,%0"; - } - if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn ("fmove%.x %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - output_asm_insn ("move%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - else - return "fmove%.x %f1,%0"; - } - return output_move_double (operands); -} - -} - -static char * -output_39 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (which_alternative == 8) - return "fpmove%.d %x1,fpa0\n\tfpmove%.d fpa0,%x0"; - if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) - return "fpmove%.d %x1,%x0"; - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fmove%.x %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%-", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "fmove%.d %+,%0"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - return "fmove%.d %f1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn ("fmove%.d %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - else - return "fmove%.d %f1,%0"; - } - return output_move_double (operands); -} - -} - -static char * -output_41 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return "move%.l %1,%0"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 3); - return "move%.b %1,%0"; -} -} - -static char * -output_42 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == REG - && (GET_CODE (operands[1]) == MEM - || GET_CODE (operands[1]) == CONST_INT)) - { - /* Must clear condition codes, since the move.w bases them on - the entire 16 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return "move%.w %1,%0"; - } - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return "move%.l %1,%0"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 1); - return "move%.b %1,%0"; -} -} - -static char * -output_43 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return "move%.l %1,%0"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 2); - return "move%.w %1,%0"; -} -} - -static char * -output_47 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return "and%.l %#0xFFFF,%0"; - if (reg_mentioned_p (operands[0], operands[1])) - return "move%.w %1,%0\n\tand%.l %#0xFFFF,%0"; - return "clr%.l %0\n\tmove%.w %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - return "move%.w %1,%0\n\tclr%.w %0"; - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.w %0\n\tmove%.w %1,%0"; - else - { - output_asm_insn ("clr%.w %0", operands); - operands[0] = adj_offsettable_operand (operands[0], 2); - return "move%.w %1,%0"; - } -} -} - -static char * -output_48 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return "and%.w %#0xFF,%0"; - if (reg_mentioned_p (operands[0], operands[1])) - return "move%.b %1,%0\n\tand%.w %#0xFF,%0"; - return "clr%.w %0\n\tmove%.b %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - if (REGNO (XEXP (XEXP (operands[0], 0), 0)) - == STACK_POINTER_REGNUM) - { - output_asm_insn ("clr%.w %-", operands); - operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), - plus_constant (stack_pointer_rtx, 1)); - return "move%.b %1,%0"; - } - else - return "move%.b %1,%0\n\tclr%.b %0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.b %0\n\tmove%.b %1,%0"; - else - { - output_asm_insn ("clr%.b %0", operands); - operands[0] = adj_offsettable_operand (operands[0], 1); - return "move%.b %1,%0"; - } -} -} - -static char * -output_49 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return "and%.l %#0xFF,%0"; - if (reg_mentioned_p (operands[0], operands[1])) - return "move%.b %1,%0\n\tand%.l %#0xFF,%0"; - return "clr%.l %0\n\tmove%.b %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); -#ifdef MOTOROLA -#ifdef SGS - return "clr%.l -(%0)\n\tmove%.b %1,3(%0)"; -#else - return "clr%.l -(%0)\n\tmove%.b %1,(3,%0)"; -#endif -#else - return "clrl %0@-\n\tmoveb %1,%0@(3)"; -#endif - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); -#ifdef MOTOROLA -#ifdef SGS - return "clr%.l (%0)+\n\tmove%.b %1,-1(%0)"; -#else - return "clr%.l (%0)+\n\tmove%.b %1,(-1,%0)"; -#endif -#else - return "clrl %0@+\n\tmoveb %1,%0@(-1)"; -#endif - } - else - { - output_asm_insn ("clr%.l %0", operands); - operands[0] = adj_offsettable_operand (operands[0], 3); - return "move%.b %1,%0"; - } -} -} - -static char * -output_50 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (ADDRESS_REG_P (operands[0])) - return "move%.w %1,%0"; - return "ext%.l %0"; -} -} - -static char * -output_55 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return ""; - } - return "f%&move%.x %1,%0"; - } - if (FP_REG_P (operands[0])) - return "f%&move%.s %f1,%0"; - if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - output_asm_insn ("fmove%.d %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - return "fmove%.d %f1,%0"; -} -} - -static char * -output_58 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "f%$move%.x %1,%0"; - return "f%$move%.d %f1,%0"; -} -} - -static char * -output_70 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "fmovem%.l %!,%2\n\tmoveq %#16,%3\n\tor%.l %2,%3\n\tand%.w %#-33,%3\n\tfmovem%.l %3,%!\n\tfmove%.l %1,%0\n\tfmovem%.l %2,%!"; -} -} - -static char * -output_71 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "fmovem%.l %!,%2\n\tmoveq %#16,%3\n\tor%.l %2,%3\n\tand%.w %#-33,%3\n\tfmovem%.l %3,%!\n\tfmove%.w %1,%0\n\tfmovem%.l %2,%!"; -} -} - -static char * -output_72 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "fmovem%.l %!,%2\n\tmoveq %#16,%3\n\tor%.l %2,%3\n\tand%.w %#-33,%3\n\tfmovem%.l %3,%!\n\tfmove%.b %1,%0\n\tfmovem%.l %2,%!"; -} -} - -static char * -output_73 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "fintrz%.x %f1,%0"; - return "fintrz%.d %f1,%0"; -} -} - -static char * -output_74 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "fintrz%.x %f1,%0"; - return "fintrz%.s %f1,%0"; -} -} - -static char * -output_83 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (! operands_match_p (operands[0], operands[1])) - { - if (!ADDRESS_REG_P (operands[1])) - { - rtx tmp = operands[1]; - - operands[1] = operands[2]; - operands[2] = tmp; - } - - /* These insns can result from reloads to access - stack slots over 64k from the frame pointer. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000) - return "move%.l %2,%0\n\tadd%.l %1,%0"; -#ifdef SGS - if (GET_CODE (operands[2]) == REG) - return "lea 0(%1,%2.l),%0"; - else - return "lea %c2(%1),%0"; -#else /* not SGS */ -#ifdef MOTOROLA - if (GET_CODE (operands[2]) == REG) - return "lea (%1,%2.l),%0"; - else - return "lea (%c2,%1),%0"; -#else /* not MOTOROLA (MIT syntax) */ - if (GET_CODE (operands[2]) == REG) - return "lea %1@(0,%2:l),%0"; - else - return "lea %1@(%c2),%0"; -#endif /* not MOTOROLA */ -#endif /* not SGS */ - } - if (GET_CODE (operands[2]) == CONST_INT) - { -#ifndef NO_ADDSUB_Q - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return (ADDRESS_REG_P (operands[0]) - ? "addq%.w %2,%0" - : "addq%.l %2,%0"); - if (INTVAL (operands[2]) < 0 - && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2])); - return (ADDRESS_REG_P (operands[0]) - ? "subq%.w %2,%0" - : "subq%.l %2,%0"); - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw.*/ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return "addq%.w %#8,%0\n\taddq%.w %2,%0"; - } - if (INTVAL (operands[2]) < -8 - && INTVAL (operands[2]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2]) - 8); - return "subq%.w %#8,%0\n\tsubq%.w %2,%0"; - } -#endif - if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[2]) >= -0x8000 - && INTVAL (operands[2]) < 0x8000) - return "add%.w %2,%0"; - } - return "add%.l %2,%0"; -} -} - -static char * -output_85 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[2]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[2]) >= 32768) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) - 65536); - - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return "addq%.w %2,%0"; - if (INTVAL (operands[2]) < 0 - && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2])); - return "subq%.w %2,%0"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return "addq%.w %#8,%0\n\taddq%.w %2,%0"; - } - if (INTVAL (operands[2]) < -8 - && INTVAL (operands[2]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2]) - 8); - return "subq%.w %#8,%0\n\tsubq%.w %2,%0"; - } - } -#endif - return "add%.w %2,%0"; -} -} - -static char * -output_86 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[1]) >= 32768) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 65536); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return "addq%.w %1,%0"; - if (INTVAL (operands[1]) < 0 - && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1])); - return "subq%.w %1,%0"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[1]) > 8 - && INTVAL (operands[1]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); - return "addq%.w %#8,%0\n\taddq%.w %1,%0"; - } - if (INTVAL (operands[1]) < -8 - && INTVAL (operands[1]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1]) - 8); - return "subq%.w %#8,%0\n\tsubq%.w %1,%0"; - } - } -#endif - return "add%.w %1,%0"; -} -} - -static char * -output_87 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[1]) >= 32768) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 65536); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return "addq%.w %1,%0"; - if (INTVAL (operands[1]) < 0 - && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1])); - return "subq%.w %1,%0"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[1]) > 8 - && INTVAL (operands[1]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); - return "addq%.w %#8,%0\n\taddq%.w %1,%0"; - } - if (INTVAL (operands[1]) < -8 - && INTVAL (operands[1]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1]) - 8); - return "subq%.w %#8,%0\n\tsubq%.w %1,%0"; - } - } -#endif - return "add%.w %1,%0"; -} -} - -static char * -output_88 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 128) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) - 256); - - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return "addq%.b %2,%0"; - if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); - return "subq%.b %2,%0"; - } - } -#endif - return "add%.b %2,%0"; -} -} - -static char * -output_89 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 128) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 256); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return "addq%.b %1,%0"; - if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); - return "subq%.b %1,%0"; - } - } -#endif - return "add%.b %1,%0"; -} -} - -static char * -output_90 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 128) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 256); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return "addq%.b %1,%0"; - if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); - return "subq%.b %1,%0"; - } - } -#endif - return "add%.b %1,%0"; -} -} - -static char * -output_92 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[1])) - return "fpadd%.d %y2,%0"; - if (rtx_equal_p (operands[0], operands[2])) - return "fpadd%.d %y1,%0"; - if (which_alternative == 0) - return "fpadd3%.d %w2,%w1,%0"; - return "fpadd3%.d %x2,%x1,%0"; -} -} - -static char * -output_93 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "f%&add%.x %2,%0"; - return "f%&add%.d %f2,%0"; -} -} - -static char * -output_95 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[1])) - return "fpadd%.s %w2,%0"; - if (rtx_equal_p (operands[0], operands[2])) - return "fpadd%.s %w1,%0"; - if (which_alternative == 0) - return "fpadd3%.s %w2,%w1,%0"; - return "fpadd3%.s %2,%1,%0"; -} -} - -static char * -output_96 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return "f%$add%.x %2,%0"; - return "f%$add%.s %f2,%0"; -} -} - -static char * -output_97 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (! operands_match_p (operands[0], operands[1])) - { - if (operands_match_p (operands[0], operands[2])) - { -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return "subq%.l %1,%0\n\tneg%.l %0"; - } -#endif - return "sub%.l %1,%0\n\tneg%.l %0"; - } - /* This case is matched by J, but negating -0x8000 - in an lea would give an invalid displacement. - So do this specially. */ - if (INTVAL (operands[2]) == -0x8000) - return "move%.l %1,%0\n\tsub%.l %2,%0"; -#ifdef SGS - return "lea %n2(%1),%0"; -#else -#ifdef MOTOROLA - return "lea (%n2,%1),%0"; -#else /* not MOTOROLA (MIT syntax) */ - return "lea %1@(%n2),%0"; -#endif /* not MOTOROLA */ -#endif /* not SGS */ - } - if (GET_CODE (operands[2]) == CONST_INT) - { -#ifndef NO_ADDSUB_Q - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return "subq%.l %2,%0"; - /* Using two subqw for 8 < N <= 16 being subtracted from an - address register is faster on all but 68000 */ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return "subq%.w %#8,%0\n\tsubq%.w %2,%0"; - } -#endif - if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[2]) >= -0x8000 - && INTVAL (operands[2]) < 0x8000) - return "sub%.w %2,%0"; - } - return "sub%.l %2,%0"; -} -} - -static char * -output_104 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[2])) - return "fprsub%.d %y1,%0"; - if (rtx_equal_p (operands[0], operands[1])) - return "fpsub%.d %y2,%0"; - if (which_alternative == 0) - return "fpsub3%.d %w2,%w1,%0"; - return "fpsub3%.d %x2,%x1,%0"; -} -} - -static char * -output_105 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "f%&sub%.x %2,%0"; - return "f%&sub%.d %f2,%0"; -} -} - -static char * -output_107 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[2])) - return "fprsub%.s %w1,%0"; - if (rtx_equal_p (operands[0], operands[1])) - return "fpsub%.s %w2,%0"; - if (which_alternative == 0) - return "fpsub3%.s %w2,%w1,%0"; - return "fpsub3%.s %2,%1,%0"; -} -} - -static char * -output_108 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return "f%$sub%.x %2,%0"; - return "f%$sub%.s %f2,%0"; -} -} - -static char * -output_109 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if defined(MOTOROLA) && !defined(CRDS) - return "muls%.w %2,%0"; -#else - return "muls %2,%0"; -#endif -} -} - -static char * -output_110 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if defined(MOTOROLA) && !defined(CRDS) - return "muls%.w %2,%0"; -#else - return "muls %2,%0"; -#endif -} -} - -static char * -output_111 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if defined(MOTOROLA) && !defined(CRDS) - return "muls%.w %2,%0"; -#else - return "muls %2,%0"; -#endif -} -} - -static char * -output_113 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if defined(MOTOROLA) && !defined(CRDS) - return "mulu%.w %2,%0"; -#else - return "mulu %2,%0"; -#endif -} -} - -static char * -output_114 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if defined(MOTOROLA) && !defined(CRDS) - return "mulu%.w %2,%0"; -#else - return "mulu %2,%0"; -#endif -} -} - -static char * -output_122 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[1], operands[2])) - return "fpsqr%.d %y1,%0"; - if (rtx_equal_p (operands[0], operands[1])) - return "fpmul%.d %y2,%0"; - if (rtx_equal_p (operands[0], operands[2])) - return "fpmul%.d %y1,%0"; - if (which_alternative == 0) - return "fpmul3%.d %w2,%w1,%0"; - return "fpmul3%.d %x2,%x1,%0"; -} -} - -static char * -output_123 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_DOUBLE - && floating_exact_log2 (operands[2]) && !TARGET_68040) - { - int i = floating_exact_log2 (operands[2]); - operands[2] = gen_rtx (CONST_INT, VOIDmode, i); - return "fscale%.l %2,%0"; - } - if (REG_P (operands[2])) - return "f%&mul%.x %2,%0"; - return "f%&mul%.d %f2,%0"; -} -} - -static char * -output_125 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[1], operands[2])) - return "fpsqr%.s %w1,%0"; - if (rtx_equal_p (operands[0], operands[1])) - return "fpmul%.s %w2,%0"; - if (rtx_equal_p (operands[0], operands[2])) - return "fpmul%.s %w1,%0"; - if (which_alternative == 0) - return "fpmul3%.s %w2,%w1,%0"; - return "fpmul3%.s %2,%1,%0"; -} -} - -static char * -output_126 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef FSGLMUL_USE_S - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? "fsmul%.s %2,%0" - : "fsglmul%.s %2,%0"); -#else - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? "fsmul%.x %2,%0" - : "fsglmul%.x %2,%0"); -#endif - return (TARGET_68040_ONLY - ? "fsmul%.s %f2,%0" - : "fsglmul%.s %f2,%0"); -} -} - -static char * -output_127 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "ext%.l %0\n\tdivs%.w %2,%0"; -#else - return "extl %0\n\tdivs %2,%0"; -#endif -} -} - -static char * -output_128 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "divs%.w %2,%0"; -#else - return "divs %2,%0"; -#endif -} -} - -static char * -output_129 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "divs%.w %2,%0"; -#else - return "divs %2,%0"; -#endif -} -} - -static char * -output_130 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "and%.l %#0xFFFF,%0\n\tdivu%.w %2,%0"; -#else - return "andl %#0xFFFF,%0\n\tdivu %2,%0"; -#endif -} -} - -static char * -output_131 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "divu%.w %2,%0"; -#else - return "divu %2,%0"; -#endif -} -} - -static char * -output_132 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - return "divu%.w %2,%0"; -#else - return "divu %2,%0"; -#endif -} -} - -static char * -output_134 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[2])) - return "fprdiv%.d %y1,%0"; - if (rtx_equal_p (operands[0], operands[1])) - return "fpdiv%.d %y2,%0"; - if (which_alternative == 0) - return "fpdiv3%.d %w2,%w1,%0"; - return "fpdiv3%.d %x2,%x1,%x0"; -} -} - -static char * -output_135 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "f%&div%.x %2,%0"; - return "f%&div%.d %f2,%0"; -} -} - -static char * -output_137 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (rtx_equal_p (operands[0], operands[1])) - return "fpdiv%.s %w2,%0"; - if (rtx_equal_p (operands[0], operands[2])) - return "fprdiv%.s %w1,%0"; - if (which_alternative == 0) - return "fpdiv3%.s %w2,%w1,%0"; - return "fpdiv3%.s %2,%1,%0"; -} -} - -static char * -output_138 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef FSGLDIV_USE_S - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? "fsdiv%.s %2,%0" - : "fsgldiv%.s %2,%0"); -#else - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? "fsdiv%.x %2,%0" - : "fsgldiv%.x %2,%0"); -#endif - return (TARGET_68040_ONLY - ? "fsdiv%.s %f2,%0" - : "fsgldiv%.s %f2,%0"); -} -} - -static char * -output_139 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "ext%.l %0\n\tdivs%.w %2,%0\n\tswap %0"; -#else - return "extl %0\n\tdivs %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_140 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "divs%.w %2,%0\n\tswap %0"; -#else - return "divs %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_141 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "divs%.w %2,%0\n\tswap %0"; -#else - return "divs %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_142 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "and%.l %#0xFFFF,%0\n\tdivu%.w %2,%0\n\tswap %0"; -#else - return "andl %#0xFFFF,%0\n\tdivu %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_143 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "divu%.w %2,%0\n\tswap %0"; -#else - return "divu %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_144 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return "divu%.w %2,%0\n\tswap %0"; -#else - return "divu %2,%0\n\tswap %0"; -#endif -} -} - -static char * -output_145 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return "divs%.l %2,%0"; - else - return "divsl%.l %2,%3:%0"; -} -} - -static char * -output_146 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return "divu%.l %2,%0"; - else - return "divul%.l %2,%3:%0"; -} -} - -static char * -output_147 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - int logval; - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xffff) == 0xffffffff - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - if (operands[2] == const0_rtx) - return "clr%.w %0"; - return "and%.w %2,%0"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - /* This does not set condition codes in a standard way. */ - CC_STATUS_INIT; - return "bclr %1,%0"; - } - return "and%.l %2,%0"; -} -} - -static char * -output_154 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - register int logval; - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return "or%.w %2,%0"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - CC_STATUS_INIT; - return "bset %1,%0"; - } - return "or%.l %2,%0"; -} -} - -static char * -output_161 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) - { - if (! DATA_REG_P (operands[0])) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return "eor%.w %2,%0"; - } - return "eor%.l %2,%0"; -} -} - -static char * -output_175 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); - return "bchg %1,%0"; - } - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "f%$neg%.x %1,%0"; - return "f%$neg%.s %f1,%0"; -} -} - -static char * -output_178 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); - return "bchg %1,%0"; - } - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "f%&neg%.x %1,%0"; - return "f%&neg%.d %f1,%0"; -} -} - -static char * -output_179 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "fsqrt%.x %1,%0"; - else - return "fsqrt%.d %1,%0"; -} -} - -static char * -output_182 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "f%$abs%.x %1,%0"; - return "f%$abs%.s %f1,%0"; -} -} - -static char * -output_185 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "f%&abs%.x %1,%0"; - return "f%&abs%.d %f1,%0"; -} -} - -static char * -output_191 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "swap %0\n\tclr%.w %0"; -} -} - -static char * -output_192 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return "asl%.w %2,%0\n\tswap %0\n\tclr%.w %0"; -} -} - -static char * -output_193 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[2] == const1_rtx) - return "add%.l %0,%0"; - return "asl%.l %2,%0"; -} -} - -static char * -output_199 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return "swap %0\n\tasr%.w %2,%0\n\text%.l %0"; -} -} - -static char * -output_200 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "asr%.l %2,%0"; -} -} - -static char * -output_205 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "swap %0\n\tclr%.w %0"; -} -} - -static char * -output_206 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return "lsl%.w %2,%0\n\tswap %0\n\tclr%.w %0"; -} -} - -static char * -output_207 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[2] == const1_rtx) - return "add%.l %0,%0"; - return "lsl%.l %2,%0"; -} -} - -static char * -output_212 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "clr%.w %0\n\tswap %0"; -} -} - -static char * -output_213 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* I think lsr%.w sets the CC properly. */ - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return "clr%.w %0\n\tswap %0\n\tlsr%.w %2,%0"; -} -} - -static char * -output_214 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "lsr%.l %2,%0"; -} -} - -static char * -output_229 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[0] - = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); - - return "move%.l %3,%0"; -} -} - -static char * -output_230 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[0])) - { - if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) - return "bfins %3,%0{%b2:%b1}"; - } - else - operands[0] - = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); - - if (GET_CODE (operands[3]) == MEM) - operands[3] = adj_offsettable_operand (operands[3], - (32 - INTVAL (operands[1])) / 8); - if (INTVAL (operands[1]) == 8) - return "move%.b %3,%0"; - return "move%.w %3,%0"; -} -} - -static char * -output_231 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - return "move%.l %1,%0"; -} -} - -static char * -output_232 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags |= CC_NOT_NEGATIVE; - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return "bfextu %1{%b3:%b2},%0"; - } - else - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - output_asm_insn ("clr%.l %0", operands); - if (GET_CODE (operands[0]) == MEM) - operands[0] = adj_offsettable_operand (operands[0], - (32 - INTVAL (operands[1])) / 8); - if (INTVAL (operands[2]) == 8) - return "move%.b %1,%0"; - return "move%.w %1,%0"; -} -} - -static char * -output_233 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - return "move%.l %1,%0"; -} -} - -static char * -output_234 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return "bfexts %1{%b3:%b2},%0"; - } - else - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - if (INTVAL (operands[2]) == 8) - return "move%.b %1,%0\n\textb%.l %0"; - return "move%.w %1,%0\n\text%.l %0"; -} -} - -static char * -output_236 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags |= CC_NOT_NEGATIVE; - return "bfextu %1{%b3:%b2},%0"; -} -} - -static char * -output_237 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "bfchg %0{%b2:%b1}"; -} -} - -static char * -output_238 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "bfclr %0{%b2:%b1}"; -} -} - -static char * -output_239 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "bfset %0{%b2:%b1}"; -} -} - -static char * -output_242 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags |= CC_NOT_NEGATIVE; - return "bfextu %1{%b3:%b2},%0"; -} -} - -static char * -output_243 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "bfclr %0{%b2:%b1}"; -} -} - -static char * -output_244 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - return "bfset %0{%b2:%b1}"; -} -} - -static char * -output_245 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#if 0 - /* These special cases are now recognized by a specific pattern. */ - if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) - return "move%.w %3,%0"; - if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) - return "move%.b %3,%0"; -#endif - return "bfins %3,%0{%b2:%b1}"; -} -} - -static char * -output_246 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, - gen_rtx (CONST_INT, VOIDmode, - width - INTVAL (operands[2])), - operands[0], - insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return "bftst %0{%b2:%b1}"; -} -} - -static char * -output_247 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, - gen_rtx (CONST_INT, VOIDmode, - width - INTVAL (operands[2])), - operands[0], - insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return "bftst %0{%b2:%b1}"; -} -} - -static char * -output_248 (operands, insn) - rtx *operands; - rtx insn; -{ - - cc_status = cc_prev_status; - OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0"); - -} - -static char * -output_249 (operands, insn) - rtx *operands; - rtx insn; -{ - - cc_status = cc_prev_status; - OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0"); - -} - -static char * -output_250 (operands, insn) - rtx *operands; - rtx insn; -{ - - cc_status = cc_prev_status; - OUTPUT_JUMP ("sgt %0", "fsgt %0", 0); - -} - -static char * -output_251 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - return "shi %0"; -} - -static char * -output_252 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0"); -} - -static char * -output_253 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - return "scs %0"; -} - -static char * -output_254 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0"); -} - -static char * -output_255 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - return "scc %0"; -} - -static char * -output_256 (operands, insn) - rtx *operands; - rtx insn; -{ - - cc_status = cc_prev_status; - OUTPUT_JUMP ("sle %0", "fsle %0", 0); - -} - -static char * -output_257 (operands, insn) - rtx *operands; - rtx insn; -{ - cc_status = cc_prev_status; - return "sls %0"; -} - -static char * -output_258 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0"); -#else - OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); -#endif -} -} - -static char * -output_259 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0"); -#else - OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); -#endif -} -} - -static char * -output_260 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jbgt %l0", "fbgt %l0", 0); -#else - OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0); -#endif - -} - -static char * -output_261 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbhi %l0"; -#else - return "jhi %l0"; -#endif - -} - -static char * -output_262 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jblt %l0", "fblt %l0", "jbmi %l0"); -#else - OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0"); -#endif - -} - -static char * -output_263 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbcs %l0"; -#else - return "jcs %l0"; -#endif - -} - -static char * -output_264 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jbge %l0", "fbge %l0", "jbpl %l0"); -#else - OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0"); -#endif - -} - -static char * -output_265 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbcc %l0"; -#else - return "jcc %l0"; -#endif - -} - -static char * -output_266 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jble %l0", "fble %l0", 0); -#else - OUTPUT_JUMP ("jle %l0", "fjle %l0", 0); -#endif - -} - -static char * -output_267 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbls %l0"; -#else - return "jls %l0"; -#endif - -} - -static char * -output_268 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0"); -#else - OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); -#endif -} -} - -static char * -output_269 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifdef MOTOROLA - OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0"); -#else - OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); -#endif -} -} - -static char * -output_270 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jble %l0", "fbngt %l0", 0); -#else - OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0); -#endif - -} - -static char * -output_271 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbls %l0"; -#else - return "jls %l0"; -#endif - -} - -static char * -output_272 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jbge %l0", "fbnlt %l0", "jbpl %l0"); -#else - OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0"); -#endif - -} - -static char * -output_273 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbcc %l0"; -#else - return "jcc %l0"; -#endif - -} - -static char * -output_274 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jblt %l0", "fbnge %l0", "jbmi %l0"); -#else - OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0"); -#endif - -} - -static char * -output_275 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbcs %l0"; -#else - return "jcs %l0"; -#endif - -} - -static char * -output_276 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - OUTPUT_JUMP ("jbgt %l0", "fbnle %l0", 0); -#else - OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0); -#endif - -} - -static char * -output_277 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbhi %l0"; -#else - return "jhi %l0"; -#endif - -} - -static char * -output_278 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jbra %l0"; -#else - return "jra %l0"; -#endif - -} - -static char * -output_280 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jmp (%0)"; -#else - return "jmp %0@"; -#endif - -} - -static char * -output_281 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef ASM_RETURN_CASE_JUMP - ASM_RETURN_CASE_JUMP; -#else -#ifdef SGS -#ifdef ASM_OUTPUT_CASE_LABEL - return "jmp 6(%%pc,%0.w)"; -#else -#ifdef CRDS - return "jmp 2(pc,%0.w)"; -#else - return "jmp 2(%%pc,%0.w)"; -#endif /* end !CRDS */ -#endif -#else /* not SGS */ -#ifdef MOTOROLA - return "jmp (2,pc,%0.w)"; -#else - return "jmp pc@(2,%0:w)"; -#endif -#endif -#endif - -} - -static char * -output_282 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1"; - if (GET_CODE (operands[0]) == MEM) - { -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - return "sub%.w %#1,%0\n\tjbcc %l1"; -#else - return "subq%.w %#1,%0\n\tjbcc %l1"; -#endif -#else /* not MOTOROLA */ - return "subqw %#1,%0\n\tjcc %l1"; -#endif - } -#ifdef MOTOROLA -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return "sub%.w %#1,%0\n\tcmp%.w %0,%#-1\n\tjbne %l1"; -#else - return "subq%.w %#1,%0\n\tcmp%.w %0,%#-1\n\tjbne %l1"; -#endif -#else /* not SGS_CMP_ORDER */ - return "subq%.w %#1,%0\n\tcmp%.w %#-1,%0\n\tjbne %l1"; -#endif -#else /* not MOTOROLA */ - return "subqw %#1,%0\n\tcmpw %#-1,%0\n\tjne %l1"; -#endif -} -} - -static char * -output_283 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsub%.l %#1,%0\n\tjbcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "sub%.l %#1,%0\n\tjbcc %l1"; -#else - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsubq%.l %#1,%0\n\tjbcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "subq%.l %#1,%0\n\tjbcc %l1"; -#endif /* NO_ADDSUB_Q */ -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return "sub.l %#1,%0\n\tcmp.l %0,%#-1\n\tjbne %l1"; -#else - return "subq.l %#1,%0\n\tcmp.l %0,%#-1\n\tjbne %l1"; -#endif -#else /* not SGS_CMP_ORDER */ - return "subq.l %#1,%0\n\tcmp.l %#-1,%0\n\tjbne %l1"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsubql %#1,%0\n\tjcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "subql %#1,%0\n\tjcc %l1"; - return "subql %#1,%0\n\tcmpl %#-1,%0\n\tjne %l1"; -#endif /* not MOTOROLA */ -} -} - -static char * -output_284 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1"; - if (GET_CODE (operands[0]) == MEM) - return "sub%.w %#1,%0\n\tjbcc %l1"; -#else - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1"; - if (GET_CODE (operands[0]) == MEM) - return "subq%.w %#1,%0\n\tjbcc %l1"; -#endif -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return "sub.w %#1,%0\n\tcmp.w %0,%#-1\n\tjbne %l1"; -#else - return "subq.w %#1,%0\n\tcmp.w %0,%#-1\n\tjbne %l1"; -#endif -#else /* not SGS_CMP_ORDER */ - return "subq.w %#1,%0\n\tcmp.w %#-1,%0\n\tjbne %l1"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1"; - if (GET_CODE (operands[0]) == MEM) - return "subqw %#1,%0\n\tjcc %l1"; - return "subqw %#1,%0\n\tcmpw %#-1,%0\n\tjne %l1"; -#endif /* not MOTOROLA */ -} -} - -static char * -output_285 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsub%.l %#1,%0\n\tjbcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "sub%.l %#1,%0\n\tjbcc %l1"; -#else - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsubq%.l %#1,%0\n\tjbcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "subq%.l %#1,%0\n\tjbcc %l1"; -#endif -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return "sub.l %#1,%0\n\tcmp.l %0,%#-1\n\tjbne %l1"; -#else - return "subq.l %#1,%0\n\tcmp.l %0,%#-1\n\tjbne %l1"; -#endif -#else /* not SGS_CMP_ORDER */ - return "subq.l %#1,%0\n\tcmp.l %#-1,%0\n\tjbne %l1"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return "dbra %0,%l1\n\tclr%.w %0\n\tsubql %#1,%0\n\tjcc %l1"; - if (GET_CODE (operands[0]) == MEM) - return "subql %#1,%0\n\tjcc %l1"; - return "subql %#1,%0\n\tcmpl %#-1,%0\n\tjne %l1"; -#endif /* not MOTOROLA */ -} -} - -static char * -output_287 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jsr %0"; -#else - return "jbsr %0"; -#endif - -} - -static char * -output_288 (operands, insn) - rtx *operands; - rtx insn; -{ - - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) -#ifdef MOTOROLA - return "bsr %0@PLTPC"; -#else - return "jbsr %0,a1"; -#endif - return "jsr %0"; - -} - -static char * -output_290 (operands, insn) - rtx *operands; - rtx insn; -{ - -#ifdef MOTOROLA - return "jsr %1"; -#else - return "jbsr %1"; -#endif - -} - -static char * -output_291 (operands, insn) - rtx *operands; - rtx insn; -{ - - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) -#ifdef MOTOROLA - return "bsr %1@PLTPC"; -#else - return "jbsr %1,a1"; -#endif - return "jsr %1"; - -} - -static char * -output_295 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx, - gen_rtx (CONST_INT, VOIDmode, NEED_PROBE)); - return "tstl %a0"; -} -} - -static char * -output_296 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_pops_args == 0) - return "rts"; - operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args); - return "rtd %0"; -} -} - -static char * -output_299 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%@", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "fmove%.d %+,%0"; -} - -} - -static char * -output_300 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); -#ifndef NO_ADDSUB_Q - if (INTVAL (xoperands[1]) <= 8) - output_asm_insn ("addq%.w %1,%0", xoperands); - else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) - { - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (xoperands[1]) - 8); - output_asm_insn ("addq%.w %#8,%0\n\taddq%.w %1,%0", xoperands); - } - else -#endif - if (INTVAL (xoperands[1]) <= 0x7FFF) - output_asm_insn ("add%.w %1,%0", xoperands); - else - output_asm_insn ("add%.l %1,%0", xoperands); - } - if (FP_REG_P (operands[2])) - return "fmove%.s %2,%@"; - return "move%.l %2,%@"; -} -} - -static char * -output_301 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); -#ifndef NO_ADDSUB_Q - if (INTVAL (xoperands[1]) <= 8) - output_asm_insn ("addq%.w %1,%0", xoperands); - else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) - { - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (xoperands[1]) - 8); - output_asm_insn ("addq%.w %#8,%0\n\taddq%.w %1,%0", xoperands); - } - else -#endif - if (INTVAL (xoperands[1]) <= 0x7FFF) - output_asm_insn ("add%.w %1,%0", xoperands); - else - output_asm_insn ("add%.l %1,%0", xoperands); - } - if (operands[2] == const0_rtx) - return "clr%.l %@"; - return "move%.l %2,%@"; -} -} - -static char * -output_302 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx xoperands[4]; - - if (GET_CODE (operands[1]) == REG) - return "move%.l %1,%-"; - - xoperands[1] = operands[1]; - xoperands[2] - = gen_rtx (MEM, QImode, - gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, - gen_rtx (CONST_INT, VOIDmode, 3))); - xoperands[3] = stack_pointer_rtx; - output_asm_insn ("subq%.w %#4,%3\n\tmove%.b %1,%2", xoperands); - return ""; -} -} - -static char * -output_303 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return "clr%.w %0"; - } - return "move%.w %1,%0"; -} -} - -static char * -output_304 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - output_dbcc_and_branch (operands); - return ""; -} -} - -static char * -output_305 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - CC_STATUS_INIT; - output_dbcc_and_branch (operands); - return ""; -} -} - -static char * -output_306 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_306[] = { - "fpma%.d %1,%w2,%w3,%0", - "fpma%.d %x1,%x2,%x3,%0", - "fpma%.d %x1,%x2,%x3,%0", - }; - return strings_306[which_alternative]; -} - -static char * -output_307 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_307[] = { - "fpma%.s %1,%w2,%w3,%0", - "fpma%.s %1,%2,%3,%0", - "fpma%.s %1,%2,%3,%0", - }; - return strings_307[which_alternative]; -} - -static char * -output_308 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_308[] = { - "fpms%.d %3,%w2,%w1,%0", - "fpms%.d %x3,%2,%x1,%0", - "fpms%.d %x3,%2,%x1,%0", - }; - return strings_308[which_alternative]; -} - -static char * -output_309 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_309[] = { - "fpms%.s %3,%w2,%w1,%0", - "fpms%.s %3,%2,%1,%0", - "fpms%.s %3,%2,%1,%0", - }; - return strings_309[which_alternative]; -} - -static char * -output_310 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_310[] = { - "fpmr%.d %2,%w1,%w3,%0", - "fpmr%.d %x2,%1,%x3,%0", - "fpmr%.d %x2,%1,%x3,%0", - }; - return strings_310[which_alternative]; -} - -static char * -output_311 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_311[] = { - "fpmr%.s %2,%w1,%w3,%0", - "fpmr%.s %x2,%1,%x3,%0", - "fpmr%.s %x2,%1,%x3,%0", - }; - return strings_311[which_alternative]; -} - -static char * -output_312 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_312[] = { - "fpam%.d %2,%w1,%w3,%0", - "fpam%.d %x2,%1,%x3,%0", - "fpam%.d %x2,%1,%x3,%0", - }; - return strings_312[which_alternative]; -} - -static char * -output_313 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_313[] = { - "fpam%.s %2,%w1,%w3,%0", - "fpam%.s %x2,%1,%x3,%0", - "fpam%.s %x2,%1,%x3,%0", - }; - return strings_313[which_alternative]; -} - -static char * -output_314 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_314[] = { - "fpsm%.d %2,%w1,%w3,%0", - "fpsm%.d %x2,%1,%x3,%0", - "fpsm%.d %x2,%1,%x3,%0", - }; - return strings_314[which_alternative]; -} - -static char * -output_315 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_315[] = { - "fpsm%.d %3,%w2,%w1,%0", - "fpsm%.d %x3,%2,%x1,%0", - "fpsm%.d %x3,%2,%x1,%0", - }; - return strings_315[which_alternative]; -} - -static char * -output_316 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_316[] = { - "fpsm%.s %2,%w1,%w3,%0", - "fpsm%.s %x2,%1,%x3,%0", - "fpsm%.s %x2,%1,%x3,%0", - }; - return strings_316[which_alternative]; -} - -static char * -output_317 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_317[] = { - "fpsm%.s %3,%w2,%w1,%0", - "fpsm%.s %x3,%2,%x1,%0", - "fpsm%.s %x3,%2,%x1,%0", - }; - return strings_317[which_alternative]; -} - -static char * -output_318 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; - return "ftst%.x %0"; -} -} - -static char * -output_320 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return "fcmp%.x %0,%1"; - else - return "fcmp%.x %0,%f1"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.x %1,%f0"; -#else - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return "fcmp%.x %1,%0"; - else - return "fcmp%.x %f1,%0"; - } - cc_status.flags |= CC_REVERSED; - return "fcmp%.x %f0,%1"; -#endif -} -} - -static char * -output_321 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return ""; - } - return "f%$move%.x %1,%0"; - } - if (FP_REG_P (operands[0])) - return "f%$move%.s %f1,%0"; - return "fmove%.x %f1,%0"; -} -} - -static char * -output_322 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return ""; - } - return "fmove%.x %1,%0"; - } - if (FP_REG_P (operands[0])) - return "f%&move%.d %f1,%0"; - return "fmove%.x %f1,%0"; -} -} - -static char * -output_323 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[0])) - { - output_asm_insn ("fmove%.d %f1,%-\n\tmove%.l %+,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "move%.l %+,%0"; - } - return "fmove%.d %f1,%0"; -} -} - -static char * -output_328 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[1])) - return "fintrz%.x %f1,%0"; - return "fintrz%.x %f1,%0"; -} -} - -static char * -output_333 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "fadd%.x %2,%0"; - return "fadd%.x %f2,%0"; -} -} - -static char * -output_335 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "fsub%.x %2,%0"; - return "fsub%.x %f2,%0"; -} -} - -static char * -output_337 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "fmul%.x %2,%0"; - return "fmul%.x %f2,%0"; -} -} - -static char * -output_339 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[2])) - return "fdiv%.x %2,%0"; - return "fdiv%.x %f2,%0"; -} -} - -static char * -output_340 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "fneg%.x %1,%0"; - return "fneg%.x %f1,%0"; -} -} - -static char * -output_341 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return "fabs%.x %1,%0"; - return "fabs%.x %f1,%0"; -} -} - -static char * -output_342 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "fsqrt%.x %1,%0"; -} -} - -char * const insn_template[] = - { - 0, - 0, - 0, - "tst%.w %0", - "tst%.b %0", - 0, - "fptst%.s %x0\n\tfpmove fpastatus,%1\n\tmovw %1,cc", - 0, - 0, - "fptst%.d %x0\n\tfpmove fpastatus,%1\n\tmovw %1,cc", - 0, - 0, - 0, - 0, - 0, - "fpcmp%.d %y1,%0\n\tfpmove fpastatus,%2\n\tmovw %2,cc", - 0, - 0, - "fpcmp%.s %w1,%x0\n\tfpmove fpastatus,%2\n\tmovw %2,cc", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "pea %a1", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "ext%.w %0", - "extb%.l %0", - 0, - "fpstod %w1,%0", - 0, - 0, - "fpdtos %y1,%0", - 0, - "fmove%.s %f1,%0", - 0, - "fpltos %1,%0", - "f%$move%.l %1,%0", - 0, - "fpltod %1,%0", - "f%&move%.l %1,%0", - "f%$move%.w %1,%0", - "fmove%.w %1,%0", - "fmove%.b %1,%0", - "f%&move%.b %1,%0", - 0, - 0, - 0, - 0, - 0, - "fmove%.b %1,%0", - "fmove%.w %1,%0", - "fmove%.l %1,%0", - "fmove%.b %1,%0", - "fmove%.w %1,%0", - "fmove%.l %1,%0", - "fpstol %w1,%0", - "fpdtol %y1,%0", - 0, - "add%.w %2,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "sub%.w %2,%0", - "sub%.w %2,%0", - "sub%.w %1,%0", - "sub%.b %2,%0", - "sub%.b %1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "muls%.l %2,%0", - 0, - 0, - 0, - "mulu%.l %2,%3:%0", - "mulu%.l %2,%3:%0", - 0, - "muls%.l %2,%3:%0", - "muls%.l %2,%3:%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "and%.w %2,%0", - "and%.w %1,%0", - "and%.w %1,%0", - "and%.b %2,%0", - "and%.b %1,%0", - "and%.b %1,%0", - 0, - "or%.w %2,%0", - "or%.w %1,%0", - "or%.w %1,%0", - "or%.b %2,%0", - "or%.b %1,%0", - "or%.b %1,%0", - 0, - "eor%.w %2,%0", - "eor%.w %1,%0", - "eor%.w %1,%0", - "eor%.b %2,%0", - "eor%.b %1,%0", - "eor%.b %1,%0", - "neg%.l %0", - "neg%.w %0", - "neg%.w %0", - "neg%.b %0", - "neg%.b %0", - 0, - "fpneg%.s %w1,%0", - 0, - 0, - "fpneg%.d %y1, %0", - 0, - 0, - 0, - "fpabs%.s %y1,%0", - 0, - 0, - "fpabs%.d %y1,%0", - 0, - "not%.l %0", - "not%.w %0", - "not%.w %0", - "not%.b %0", - "not%.b %0", - 0, - 0, - 0, - "asl%.w %2,%0", - "asl%.w %1,%0", - "asl%.b %2,%0", - "asl%.b %1,%0", - "swap %0\n\text%.l %0", - 0, - 0, - "asr%.w %2,%0", - "asr%.w %1,%0", - "asr%.b %2,%0", - "asr%.b %1,%0", - 0, - 0, - 0, - "lsl%.w %2,%0", - "lsl%.w %1,%0", - "lsl%.b %2,%0", - "lsl%.b %1,%0", - 0, - 0, - 0, - "lsr%.w %2,%0", - "lsr%.w %1,%0", - "lsr%.b %2,%0", - "lsr%.b %1,%0", - "rol%.l %2,%0", - "rol%.w %2,%0", - "rol%.w %1,%0", - "rol%.b %2,%0", - "rol%.b %1,%0", - "ror%.l %2,%0", - "ror%.w %2,%0", - "ror%.w %1,%0", - "ror%.b %2,%0", - "ror%.b %1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - "bfexts %1{%b3:%b2},%0", - 0, - 0, - 0, - 0, - "bfins %3,%0{%b2:%b1}", - "bfexts %1{%b3:%b2},%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "", - "nop", - 0, - 0, - "jmp %a0", - "lea %a1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "fmove%.s %f1,%0", - "fmove%.l %1,%0", - "fmove%.w %1,%0", - "fmove%.b %1,%0", - 0, - "fmove%.b %1,%0", - "fmove%.w %1,%0", - "fmove%.l %1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *(*const insn_outfun[])() = - { - output_0, - output_1, - output_2, - 0, - 0, - 0, - 0, - output_7, - 0, - 0, - output_10, - output_11, - output_12, - output_13, - 0, - 0, - output_16, - 0, - 0, - output_19, - output_20, - output_21, - output_22, - output_23, - output_24, - output_25, - output_26, - output_27, - 0, - output_29, - output_30, - output_31, - output_32, - output_33, - output_34, - output_35, - 0, - output_37, - output_38, - output_39, - 0, - output_41, - output_42, - output_43, - 0, - 0, - 0, - output_47, - output_48, - output_49, - output_50, - 0, - 0, - 0, - 0, - output_55, - 0, - 0, - output_58, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_70, - output_71, - output_72, - output_73, - output_74, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_83, - 0, - output_85, - output_86, - output_87, - output_88, - output_89, - output_90, - 0, - output_92, - output_93, - 0, - output_95, - output_96, - output_97, - 0, - 0, - 0, - 0, - 0, - 0, - output_104, - output_105, - 0, - output_107, - output_108, - output_109, - output_110, - output_111, - 0, - output_113, - output_114, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_122, - output_123, - 0, - output_125, - output_126, - output_127, - output_128, - output_129, - output_130, - output_131, - output_132, - 0, - output_134, - output_135, - 0, - output_137, - output_138, - output_139, - output_140, - output_141, - output_142, - output_143, - output_144, - output_145, - output_146, - output_147, - 0, - 0, - 0, - 0, - 0, - 0, - output_154, - 0, - 0, - 0, - 0, - 0, - 0, - output_161, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_175, - 0, - 0, - output_178, - output_179, - 0, - 0, - output_182, - 0, - 0, - output_185, - 0, - 0, - 0, - 0, - 0, - output_191, - output_192, - output_193, - 0, - 0, - 0, - 0, - 0, - output_199, - output_200, - 0, - 0, - 0, - 0, - output_205, - output_206, - output_207, - 0, - 0, - 0, - 0, - output_212, - output_213, - output_214, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_229, - output_230, - output_231, - output_232, - output_233, - output_234, - 0, - output_236, - output_237, - output_238, - output_239, - 0, - 0, - output_242, - output_243, - output_244, - output_245, - output_246, - output_247, - output_248, - output_249, - output_250, - output_251, - output_252, - output_253, - output_254, - output_255, - output_256, - output_257, - output_258, - output_259, - output_260, - output_261, - output_262, - output_263, - output_264, - output_265, - output_266, - output_267, - output_268, - output_269, - output_270, - output_271, - output_272, - output_273, - output_274, - output_275, - output_276, - output_277, - output_278, - 0, - output_280, - output_281, - output_282, - output_283, - output_284, - output_285, - 0, - output_287, - output_288, - 0, - output_290, - output_291, - 0, - 0, - 0, - output_295, - output_296, - 0, - 0, - output_299, - output_300, - output_301, - output_302, - output_303, - output_304, - output_305, - output_306, - output_307, - output_308, - output_309, - output_310, - output_311, - output_312, - output_313, - output_314, - output_315, - output_316, - output_317, - output_318, - 0, - output_320, - output_321, - output_322, - output_323, - 0, - 0, - 0, - 0, - output_328, - 0, - 0, - 0, - 0, - output_333, - 0, - output_335, - 0, - output_337, - 0, - output_339, - output_340, - output_341, - output_342, - }; - -rtx (*const insn_gen_function[]) () = - { - 0, - 0, - gen_tstsi, - gen_tsthi, - gen_tstqi, - gen_tstsf, - gen_tstsf_fpa, - 0, - gen_tstdf, - gen_tstdf_fpa, - 0, - gen_cmpsi, - gen_cmphi, - gen_cmpqi, - gen_cmpdf, - gen_cmpdf_fpa, - 0, - gen_cmpsf, - gen_cmpsf_fpa, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_movsi, - 0, - gen_movhi, - gen_movstricthi, - gen_movqi, - gen_movstrictqi, - gen_movsf, - gen_movdf, - gen_movxf, - 0, - 0, - gen_movdi, - gen_pushasi, - gen_truncsiqi2, - gen_trunchiqi2, - gen_truncsihi2, - gen_zero_extendhisi2, - gen_zero_extendqihi2, - gen_zero_extendqisi2, - 0, - 0, - 0, - gen_extendhisi2, - gen_extendqihi2, - gen_extendqisi2, - gen_extendsfdf2, - 0, - 0, - gen_truncdfsf2, - 0, - 0, - 0, - gen_floatsisf2, - 0, - 0, - gen_floatsidf2, - 0, - 0, - gen_floathisf2, - gen_floathidf2, - gen_floatqisf2, - gen_floatqidf2, - gen_fix_truncdfsi2, - gen_fix_truncdfhi2, - gen_fix_truncdfqi2, - gen_ftruncdf2, - gen_ftruncsf2, - gen_fixsfqi2, - gen_fixsfhi2, - gen_fixsfsi2, - gen_fixdfqi2, - gen_fixdfhi2, - gen_fixdfsi2, - 0, - 0, - gen_addsi3, - 0, - gen_addhi3, - 0, - 0, - gen_addqi3, - 0, - 0, - gen_adddf3, - 0, - 0, - gen_addsf3, - 0, - 0, - gen_subsi3, - 0, - gen_subhi3, - 0, - gen_subqi3, - 0, - gen_subdf3, - 0, - 0, - gen_subsf3, - 0, - 0, - gen_mulhi3, - gen_mulhisi3, - 0, - gen_mulsi3, - gen_umulhisi3, - 0, - gen_umulsidi3, - 0, - 0, - gen_mulsidi3, - 0, - 0, - gen_muldf3, - 0, - 0, - gen_mulsf3, - 0, - 0, - gen_divhi3, - gen_divhisi3, - 0, - gen_udivhi3, - gen_udivhisi3, - 0, - gen_divdf3, - 0, - 0, - gen_divsf3, - 0, - 0, - gen_modhi3, - gen_modhisi3, - 0, - gen_umodhi3, - gen_umodhisi3, - 0, - gen_divmodsi4, - gen_udivmodsi4, - gen_andsi3, - gen_andhi3, - 0, - 0, - gen_andqi3, - 0, - 0, - gen_iorsi3, - gen_iorhi3, - 0, - 0, - gen_iorqi3, - 0, - 0, - gen_xorsi3, - gen_xorhi3, - 0, - 0, - gen_xorqi3, - 0, - 0, - gen_negsi2, - gen_neghi2, - 0, - gen_negqi2, - 0, - gen_negsf2, - 0, - 0, - gen_negdf2, - 0, - 0, - gen_sqrtdf2, - gen_abssf2, - 0, - 0, - gen_absdf2, - 0, - 0, - gen_one_cmplsi2, - gen_one_cmplhi2, - 0, - gen_one_cmplqi2, - 0, - 0, - 0, - gen_ashlsi3, - gen_ashlhi3, - 0, - gen_ashlqi3, - 0, - 0, - 0, - gen_ashrsi3, - gen_ashrhi3, - 0, - gen_ashrqi3, - 0, - 0, - 0, - gen_lshlsi3, - gen_lshlhi3, - 0, - gen_lshlqi3, - 0, - 0, - 0, - gen_lshrsi3, - gen_lshrhi3, - 0, - gen_lshrqi3, - 0, - gen_rotlsi3, - gen_rotlhi3, - 0, - gen_rotlqi3, - 0, - gen_rotrsi3, - gen_rotrhi3, - 0, - gen_rotrqi3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_extv, - gen_extzv, - 0, - 0, - 0, - gen_insv, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_seq, - gen_sne, - gen_sgt, - gen_sgtu, - gen_slt, - gen_sltu, - gen_sge, - gen_sgeu, - gen_sle, - gen_sleu, - gen_beq, - gen_bne, - gen_bgt, - gen_bgtu, - gen_blt, - gen_bltu, - gen_bge, - gen_bgeu, - gen_ble, - gen_bleu, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_jump, - gen_tablejump, - 0, - 0, - 0, - 0, - 0, - gen_decrement_and_branch_until_zero, - gen_call, - 0, - 0, - gen_call_value, - 0, - 0, - gen_untyped_call, - gen_blockage, - gen_nop, - gen_probe, - gen_return, - gen_indirect_jump, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_tstxf, - gen_cmpxf, - 0, - gen_extendsfxf2, - gen_extenddfxf2, - gen_truncxfdf2, - gen_truncxfsf2, - gen_floatsixf2, - gen_floathixf2, - gen_floatqixf2, - gen_ftruncxf2, - gen_fixxfqi2, - gen_fixxfhi2, - gen_fixxfsi2, - gen_addxf3, - 0, - gen_subxf3, - 0, - gen_mulxf3, - 0, - gen_divxf3, - 0, - gen_negxf2, - gen_absxf2, - gen_sqrtxf2, - }; - -char *insn_name[] = - { - "tstsi-1", - "tstsi-0", - "tstsi", - "tsthi", - "tstqi", - "tstsf", - "tstsf_fpa", - "tstsf_fpa+1", - "tstdf", - "tstdf_fpa", - "tstdf_fpa+1", - "cmpsi", - "cmphi", - "cmpqi", - "cmpdf", - "cmpdf_fpa", - "cmpdf_fpa+1", - "cmpsf", - "cmpsf_fpa", - "cmpsf_fpa+1", - "cmpsf_fpa+2", - "cmpsf_fpa+3", - "cmpsf_fpa+4", - "cmpsf_fpa+5", - "movsi-4", - "movsi-3", - "movsi-2", - "movsi-1", - "movsi", - "movsi+1", - "movhi", - "movstricthi", - "movqi", - "movstrictqi", - "movsf", - "movdf", - "movxf", - "movxf+1", - "movdi-1", - "movdi", - "pushasi", - "truncsiqi2", - "trunchiqi2", - "truncsihi2", - "zero_extendhisi2", - "zero_extendqihi2", - "zero_extendqisi2", - "zero_extendqisi2+1", - "zero_extendqisi2+2", - "extendhisi2-1", - "extendhisi2", - "extendqihi2", - "extendqisi2", - "extendsfdf2", - "extendsfdf2+1", - "truncdfsf2-1", - "truncdfsf2", - "truncdfsf2+1", - "truncdfsf2+2", - "floatsisf2-1", - "floatsisf2", - "floatsisf2+1", - "floatsidf2-1", - "floatsidf2", - "floatsidf2+1", - "floathisf2-1", - "floathisf2", - "floathidf2", - "floatqisf2", - "floatqidf2", - "fix_truncdfsi2", - "fix_truncdfhi2", - "fix_truncdfqi2", - "ftruncdf2", - "ftruncsf2", - "fixsfqi2", - "fixsfhi2", - "fixsfsi2", - "fixdfqi2", - "fixdfhi2", - "fixdfsi2", - "fixdfsi2+1", - "addsi3-1", - "addsi3", - "addsi3+1", - "addhi3", - "addhi3+1", - "addqi3-1", - "addqi3", - "addqi3+1", - "adddf3-1", - "adddf3", - "adddf3+1", - "addsf3-1", - "addsf3", - "addsf3+1", - "subsi3-1", - "subsi3", - "subsi3+1", - "subhi3", - "subhi3+1", - "subqi3", - "subqi3+1", - "subdf3", - "subdf3+1", - "subsf3-1", - "subsf3", - "subsf3+1", - "mulhi3-1", - "mulhi3", - "mulhisi3", - "mulhisi3+1", - "mulsi3", - "umulhisi3", - "umulhisi3+1", - "umulsidi3", - "umulsidi3+1", - "mulsidi3-1", - "mulsidi3", - "mulsidi3+1", - "muldf3-1", - "muldf3", - "muldf3+1", - "mulsf3-1", - "mulsf3", - "mulsf3+1", - "divhi3-1", - "divhi3", - "divhisi3", - "divhisi3+1", - "udivhi3", - "udivhisi3", - "udivhisi3+1", - "divdf3", - "divdf3+1", - "divsf3-1", - "divsf3", - "divsf3+1", - "modhi3-1", - "modhi3", - "modhisi3", - "modhisi3+1", - "umodhi3", - "umodhisi3", - "umodhisi3+1", - "divmodsi4", - "udivmodsi4", - "andsi3", - "andhi3", - "andhi3+1", - "andqi3-1", - "andqi3", - "andqi3+1", - "iorsi3-1", - "iorsi3", - "iorhi3", - "iorhi3+1", - "iorqi3-1", - "iorqi3", - "iorqi3+1", - "xorsi3-1", - "xorsi3", - "xorhi3", - "xorhi3+1", - "xorqi3-1", - "xorqi3", - "xorqi3+1", - "negsi2-1", - "negsi2", - "neghi2", - "neghi2+1", - "negqi2", - "negqi2+1", - "negsf2", - "negsf2+1", - "negdf2-1", - "negdf2", - "negdf2+1", - "sqrtdf2-1", - "sqrtdf2", - "abssf2", - "abssf2+1", - "absdf2-1", - "absdf2", - "absdf2+1", - "one_cmplsi2-1", - "one_cmplsi2", - "one_cmplhi2", - "one_cmplhi2+1", - "one_cmplqi2", - "one_cmplqi2+1", - "one_cmplqi2+2", - "ashlsi3-1", - "ashlsi3", - "ashlhi3", - "ashlhi3+1", - "ashlqi3", - "ashlqi3+1", - "ashlqi3+2", - "ashrsi3-1", - "ashrsi3", - "ashrhi3", - "ashrhi3+1", - "ashrqi3", - "ashrqi3+1", - "ashrqi3+2", - "lshlsi3-1", - "lshlsi3", - "lshlhi3", - "lshlhi3+1", - "lshlqi3", - "lshlqi3+1", - "lshlqi3+2", - "lshrsi3-1", - "lshrsi3", - "lshrhi3", - "lshrhi3+1", - "lshrqi3", - "lshrqi3+1", - "rotlsi3", - "rotlhi3", - "rotlhi3+1", - "rotlqi3", - "rotlqi3+1", - "rotrsi3", - "rotrhi3", - "rotrhi3+1", - "rotrqi3", - "rotrqi3+1", - "rotrqi3+2", - "rotrqi3+3", - "rotrqi3+4", - "extv-3", - "extv-2", - "extv-1", - "extv", - "extzv", - "extzv+1", - "extzv+2", - "insv-1", - "insv", - "insv+1", - "insv+2", - "insv+3", - "insv+4", - "seq-3", - "seq-2", - "seq-1", - "seq", - "sne", - "sgt", - "sgtu", - "slt", - "sltu", - "sge", - "sgeu", - "sle", - "sleu", - "beq", - "bne", - "bgt", - "bgtu", - "blt", - "bltu", - "bge", - "bgeu", - "ble", - "bleu", - "bleu+1", - "bleu+2", - "bleu+3", - "bleu+4", - "bleu+5", - "jump-5", - "jump-4", - "jump-3", - "jump-2", - "jump-1", - "jump", - "tablejump", - "tablejump+1", - "tablejump+2", - "tablejump+3", - "decrement_and_branch_until_zero-2", - "decrement_and_branch_until_zero-1", - "decrement_and_branch_until_zero", - "call", - "call+1", - "call_value-1", - "call_value", - "call_value+1", - "untyped_call-1", - "untyped_call", - "blockage", - "nop", - "probe", - "return", - "indirect_jump", - "indirect_jump+1", - "indirect_jump+2", - "indirect_jump+3", - "indirect_jump+4", - "indirect_jump+5", - "indirect_jump+6", - "indirect_jump+7", - "indirect_jump+8", - "indirect_jump+9", - "indirect_jump+10", - "tstxf-10", - "tstxf-9", - "tstxf-8", - "tstxf-7", - "tstxf-6", - "tstxf-5", - "tstxf-4", - "tstxf-3", - "tstxf-2", - "tstxf-1", - "tstxf", - "cmpxf", - "cmpxf+1", - "extendsfxf2", - "extenddfxf2", - "truncxfdf2", - "truncxfsf2", - "floatsixf2", - "floathixf2", - "floatqixf2", - "ftruncxf2", - "fixxfqi2", - "fixxfhi2", - "fixxfsi2", - "addxf3", - "addxf3+1", - "subxf3", - "subxf3+1", - "mulxf3", - "mulxf3+1", - "divxf3", - "divxf3+1", - "negxf2", - "absxf2", - "sqrtxf2", - }; -char **insn_name_ptr = insn_name; - -const int insn_n_operands[] = - { - 2, - 2, - 1, - 1, - 1, - 1, - 2, - 1, - 1, - 2, - 1, - 2, - 2, - 2, - 2, - 3, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 4, - 4, - 4, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 2, - 2, - 3, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 3, - 4, - 4, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 3, - 3, - 2, - 2, - 3, - 2, - 2, - 3, - 3, - 2, - 2, - 3, - 2, - 2, - 3, - 3, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 1, - 2, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 2, - 1, - 3, - 3, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 2, - 3, - 2, - 3, - 3, - 2, - 3, - 2, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 3, - 3, - 4, - 4, - 4, - 3, - 3, - 4, - 3, - 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 0, - 0, - 0, - 0, - 1, - 2, - 2, - 3, - 3, - 2, - 2, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 2, - 2, - }; - -const int insn_n_dups[] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3, - 2, - 2, - 3, - 2, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 2, - 0, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 2, - 2, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] = - { - { "=m", "ro<>fyE", }, - { "=m", "ro<>Fy", }, - { "rm", }, - { "dm", }, - { "dm", }, - { "", }, - { "xmdF", "=d", }, - { "fdm", }, - { "", }, - { "xrmF", "=d", }, - { "fm", }, - { "rKs,mr,>", "mr,Ksr,>", }, - { "rnm,d,n,m", "d,rnm,m,n", }, - { "dn,md,>", "dm,nd,>", }, - { "", "", }, - { "x,y", "xH,rmF", "=d,d", }, - { "f,mG", "fmG,f", }, - { "", "", }, - { "x,y", "xH,rmF", "=d,d", }, - { "f,mdG", "fmdG,f", }, - { "do", "di", }, - { "d", "di", }, - { "do", "d", }, - { "d", "d", }, - { "md", "i", }, - { "do", "i", }, - { "=m", "J", }, - { "=g", }, - { "", "", }, - { "=g,da,y,!*x*r*m", "daymKs,i,g,*x*r*m", }, - { "=g", "g", }, - { "+dm", "rmn", }, - { "=d,*a,m,m,?*a", "dmi*a,d*a,dmi,?*a,m", }, - { "+dm", "dmn", }, - { "=rmf,x,y,rm,!x,!rm", "rmfF,xH,rmF,y,rm,x", }, - { "=rm,&rf,&rof<>,y,rm,x,!x,!rm", "rf,m,rofE<>,rmE,y,xH,rm,x", }, - { "", "", }, - { "=f,m,f,!r,!f", "m,f,f,f,r", }, - { "=rm,&rf,&rof<>", "rf,m,rof<>", }, - { "=rm,&r,&ro<>,y,rm,!*x,!rm", "rF,m,roi<>F,rmiF,y,rmF,*x", }, - { "=m", "p", }, - { "=dm,d", "doJ,i", }, - { "=dm,d", "doJ,i", }, - { "=dm,d", "roJ,i", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "=do<>,d<", "r,m", }, - { "=do<>,d", "d,m", }, - { "=do<>,d", "d,m", }, - { "=*d,a", "0,rm", }, - { "=d", "0", }, - { "=d", "0", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=*fdm,f", "f,dmF", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=f", "fmG", }, - { "=dm", "f", }, - { "", "", }, - { "=y,x", "rmi,x", }, - { "=f", "dmi", }, - { "", "", }, - { "=y,x", "rmi,x", }, - { "=f", "dmi", }, - { "=f", "dmn", }, - { "=f", "dmn", }, - { "=f", "dmn", }, - { "=f", "dmn", }, - { "=dm", "f", "=d", "=d", }, - { "=dm", "f", "=d", "=d", }, - { "=dm", "f", "=d", "=d", }, - { "=f", "fFm", }, - { "=f", "dfFm", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=x,y", "xH,rmF", }, - { "=x,y", "xH,rmF", }, - { "=m,?a,?a,r", "%0,a,rJK,0", "dIKLs,rJK,a,mrIKLs", }, - { "=a", "0", "rm", }, - { "=m,r", "%0,0", "dn,rmn", }, - { "+m,d", "dn,rmn", }, - { "+m,d", "dn,rmn", }, - { "=m,d", "%0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "", "", "", }, - { "=x,y", "%xH,y", "xH,dmF", }, - { "=f", "%0", "fmG", }, - { "", "", "", }, - { "=x,y", "%xH,y", "xH,rmF", }, - { "=f", "%0", "fdmF", }, - { "=m,r,!a,?d", "0,0,a,mrIKs", "dIKs,mrIKs,J,0", }, - { "=a", "0", "rm", }, - { "=m,r", "0,0", "dn,rmn", }, - { "+m,d", "dn,rmn", }, - { "=m,d", "0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "", "", "", }, - { "=x,y,y", "xH,y,dmF", "xH,dmF,0", }, - { "=f", "0", "fmG", }, - { "", "", "", }, - { "=x,y,y", "xH,y,rmF", "xH,rmF,0", }, - { "=f", "0", "fdmF", }, - { "=d", "%0", "dmn", }, - { "=d", "%0", "dm", }, - { "=d", "%0", "n", }, - { "=d", "%0", "dmsK", }, - { "=d", "%0", "dm", }, - { "=d", "%0", "n", }, - { "", "", "", }, - { "=d", "%0", "dm", "=d", }, - { "=d", "%0", "n", "=d", }, - { "", "", "", }, - { "=d", "%0", "dm", "=d", }, - { "=d", "%0", "n", "=d", }, - { "", "", "", }, - { "=x,y", "%xH,y", "xH,rmF", }, - { "=f", "%0", "fmG", }, - { "", "", "", }, - { "=x,y", "%xH,y", "xH,rmF", }, - { "=f", "%0", "fdmF", }, - { "=d", "0", "dmn", }, - { "=d", "0", "dm", }, - { "=d", "0", "n", }, - { "=d", "0", "dmn", }, - { "=d", "0", "dm", }, - { "=d", "0", "n", }, - { "", "", "", }, - { "=x,y,y", "xH,y,rmF", "xH,rmF,0", }, - { "=f", "0", "fmG", }, - { "", "", "", }, - { "=x,y,y", "xH,y,rmF", "xH,rmF,0", }, - { "=f", "0", "fdmF", }, - { "=d", "0", "dmn", }, - { "=d", "0", "dm", }, - { "=d", "0", "n", }, - { "=d", "0", "dmn", }, - { "=d", "0", "dm", }, - { "=d", "0", "n", }, - { "=d", "0", "dmsK", "=d", }, - { "=d", "0", "dmsK", "=d", }, - { "=m,d", "%0,0", "dKs,dmKs", }, - { "=m,d", "%0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "=m,d", "%0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "=m,d", "%0,0", "dKs,dmKs", }, - { "=m,d", "%0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "=m,d", "%0,0", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "+m,d", "dn,dmn", }, - { "=do,m", "%0,0", "di,dKs", }, - { "=dm", "%0", "dn", }, - { "+dm", "dn", }, - { "+dm", "dn", }, - { "=dm", "%0", "dn", }, - { "+dm", "dn", }, - { "+dm", "dn", }, - { "=dm", "0", }, - { "=dm", "0", }, - { "+dm", }, - { "=dm", "0", }, - { "+dm", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=f,d", "fdmF,0", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=f,d", "fmF,0", }, - { "=f", "fm", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=f", "fdmF", }, - { "", "", }, - { "=x,y", "xH,rmF", }, - { "=f", "fmF", }, - { "=dm", "0", }, - { "=dm", "0", }, - { "+dm", }, - { "=dm", "0", }, - { "+dm", }, - { "=d", "0", "i", }, - { "=d", "0", "i", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "i", }, - { "=d", "0", "i", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "i", }, - { "=d", "0", "i", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "i", }, - { "=d", "0", "i", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "=d", "0", "dI", }, - { "+d", "dI", }, - { "+o", "i", "i", "rmi", }, - { "+do", "i", "i", "d", }, - { "=rm", "o", "i", "i", }, - { "=&d", "do", "i", "i", }, - { "=rm", "o", "i", "i", }, - { "=d", "do", "i", "i", }, - { "=d,d", "o,d", "di,di", "di,di", }, - { "=d,d", "o,d", "di,di", "di,di", }, - { "+o,d", "di,di", "di,di", "i,i", }, - { "+o,d", "di,di", "di,di", }, - { "+o,d", "di,di", "di,di", }, - { "+o,d", "di,di", "di,di", "d,d", }, - { "=d", "d", "di", "di", }, - { "=d", "d", "di", "di", }, - { "+d", "di", "di", }, - { "+d", "di", "di", }, - { "+d", "di", "di", "d", }, - { "o", "di", "di", }, - { "d", "di", "di", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { "=d", }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { "", }, - { "a", }, - { "r", }, - { "+g", }, - { "+g", }, - { "+g", }, - { "+g", }, - { "", "", }, - { "o", "g", }, - { "o", "g", }, - { "", "", "", }, - { "=rf", "o", "g", }, - { "=rf", "o", "g", }, - { "", "", "", }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { "p", }, - { "=a", "p", }, - { "=f", "ad", }, - { "n", "=m", "rmfF", }, - { "n", "=m", "g", }, - { "", "dami", }, - { "=d", "rmn", }, - { "+d", "", "", "", }, - { "+d", "", "", "", }, - { "=x,y,y", "%x,dmF,y", "xH,y,y", "xH,y,dmF", }, - { "=x,y,y", "%x,ydmF,y", "xH,y,ydmF", "xH,ydmF,ydmF", }, - { "=x,y,y", "xH,rmF,y", "%xH,y,y", "x,y,rmF", }, - { "=x,y,y", "xH,rmF,yrmF", "%xH,rmF,y", "x,y,yrmF", }, - { "=x,y,y", "%xH,y,y", "x,y,rmF", "xH,rmF,y", }, - { "=x,y,y", "%xH,rmF,y", "x,y,yrmF", "xH,rmF,yrmF", }, - { "=x,y,y", "%xH,y,y", "x,y,rmF", "xH,rmF,y", }, - { "=x,y,y", "%xH,rmF,y", "x,y,yrmF", "xH,rmF,yrmF", }, - { "=x,y,y", "xH,y,y", "x,y,rmF", "xH,rmF,y", }, - { "=x,y,y", "xH,rmF,y", "xH,y,y", "x,y,rmF", }, - { "=x,y,y", "xH,rmF,y", "x,y,yrmF", "xH,rmF,yrmF", }, - { "=x,y,y", "xH,rmF,yrmF", "xH,rmF,y", "x,y,yrmF", }, - { "fm", }, - { "f,mG", "fmG,f", }, - { "f,mG", "fmG,f", }, - { "=fm,f", "f,m", }, - { "=fm,f", "f,m", }, - { "=m,!r", "f,f", }, - { "=dm", "f", }, - { "=f", "dmi", }, - { "=f", "dmn", }, - { "=f", "dmn", }, - { "=f", "fFm", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "=dm", "f", }, - { "", "", "", }, - { "=f", "%0", "fmG", }, - { "", "", "", }, - { "=f", "0", "fmG", }, - { "", "", "", }, - { "=f", "%0", "fmG", }, - { "", "", "", }, - { "=f", "0", "fmG", }, - { "=f", "fmF", }, - { "=f", "fmF", }, - { "=f", "fm", }, - }; - -const enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] = - { - { DFmode, DFmode, }, - { DImode, DImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SFmode, }, - { SFmode, SImode, }, - { SFmode, }, - { DFmode, }, - { DFmode, SImode, }, - { DFmode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, SImode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, SImode, }, - { SFmode, SFmode, }, - { QImode, SImode, }, - { SImode, SImode, }, - { QImode, SImode, }, - { SImode, SImode, }, - { QImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { XFmode, XFmode, }, - { XFmode, XFmode, }, - { XFmode, XFmode, }, - { DImode, DImode, }, - { SImode, SImode, }, - { QImode, SImode, }, - { QImode, HImode, }, - { HImode, SImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { DFmode, SFmode, }, - { DFmode, SFmode, }, - { DFmode, SFmode, }, - { SFmode, DFmode, }, - { SFmode, DFmode, }, - { SFmode, DFmode, }, - { SFmode, DFmode, }, - { SFmode, SImode, }, - { SFmode, SImode, }, - { SFmode, SImode, }, - { DFmode, SImode, }, - { DFmode, SImode, }, - { DFmode, SImode, }, - { SFmode, HImode, }, - { DFmode, HImode, }, - { SFmode, QImode, }, - { DFmode, QImode, }, - { SImode, DFmode, SImode, SImode, }, - { HImode, DFmode, SImode, SImode, }, - { QImode, DFmode, SImode, SImode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { QImode, SFmode, }, - { HImode, SFmode, }, - { SImode, SFmode, }, - { QImode, DFmode, }, - { HImode, DFmode, }, - { SImode, DFmode, }, - { SImode, SFmode, }, - { SImode, DFmode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, HImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, HImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { HImode, HImode, HImode, }, - { SImode, HImode, HImode, }, - { SImode, HImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, HImode, HImode, }, - { SImode, HImode, SImode, }, - { DImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { HImode, HImode, HImode, }, - { HImode, SImode, HImode, }, - { HImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, SImode, HImode, }, - { HImode, SImode, SImode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, }, - { HImode, HImode, HImode, }, - { HImode, SImode, HImode, }, - { HImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, SImode, HImode, }, - { HImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { HImode, }, - { QImode, QImode, }, - { QImode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { HImode, }, - { QImode, QImode, }, - { QImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, }, - { QImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, QImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, QImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, QImode, SImode, SImode, }, - { SImode, QImode, SImode, SImode, }, - { QImode, SImode, SImode, VOIDmode, }, - { QImode, SImode, SImode, }, - { QImode, SImode, SImode, }, - { QImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { QImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { QImode, }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode, }, - { SImode, }, - { HImode, }, - { HImode, }, - { SImode, }, - { HImode, }, - { SImode, }, - { QImode, SImode, }, - { QImode, SImode, }, - { QImode, SImode, }, - { VOIDmode, QImode, SImode, }, - { VOIDmode, QImode, SImode, }, - { VOIDmode, QImode, SImode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { SImode, }, - { SImode, QImode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { DFmode, DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { SFmode, SFmode, SFmode, SFmode, }, - { XFmode, }, - { XFmode, XFmode, }, - { XFmode, XFmode, }, - { XFmode, SFmode, }, - { XFmode, DFmode, }, - { DFmode, XFmode, }, - { SFmode, XFmode, }, - { XFmode, SImode, }, - { XFmode, HImode, }, - { XFmode, QImode, }, - { XFmode, XFmode, }, - { QImode, XFmode, }, - { HImode, XFmode, }, - { SImode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, XFmode, }, - { XFmode, XFmode, }, - { XFmode, XFmode, }, - { XFmode, DFmode, }, - }; - -const char insn_operand_strict_low[][MAX_RECOG_OPERANDS] = - { - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 1, 0, }, - { 0, 0, }, - { 1, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 1, 0, }, - { 0, 0, }, - { 0, 0, }, - { 1, }, - { 0, 0, }, - { 1, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 1, }, - { 0, 0, }, - { 1, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, }, - { 1, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - }; - -extern int push_operand (); -extern int general_operand (); -extern int nonimmediate_operand (); -extern int scratch_operand (); -extern int address_operand (); -extern int register_operand (); -extern int const_int_operand (); -extern int not_sp_operand (); -extern int immediate_operand (); -extern int memory_operand (); - -int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() = - { - { push_operand, general_operand, }, - { push_operand, general_operand, }, - { nonimmediate_operand, }, - { nonimmediate_operand, }, - { nonimmediate_operand, }, - { general_operand, }, - { general_operand, scratch_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, scratch_operand, }, - { general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, scratch_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, scratch_operand, }, - { general_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { push_operand, general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, nonimmediate_operand, }, - { nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, }, - { push_operand, address_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, general_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, register_operand, scratch_operand, scratch_operand, }, - { general_operand, register_operand, scratch_operand, scratch_operand, }, - { general_operand, register_operand, scratch_operand, scratch_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, const_int_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, const_int_operand, }, - { register_operand, register_operand, nonimmediate_operand, }, - { register_operand, register_operand, nonimmediate_operand, register_operand, }, - { register_operand, register_operand, const_int_operand, register_operand, }, - { register_operand, register_operand, nonimmediate_operand, }, - { register_operand, register_operand, nonimmediate_operand, register_operand, }, - { register_operand, register_operand, const_int_operand, register_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, const_int_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, const_int_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, const_int_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, nonimmediate_operand, }, - { general_operand, general_operand, const_int_operand, }, - { general_operand, general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, general_operand, }, - { not_sp_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { register_operand, register_operand, general_operand, }, - { register_operand, general_operand, }, - { nonimmediate_operand, immediate_operand, immediate_operand, general_operand, }, - { nonimmediate_operand, immediate_operand, immediate_operand, general_operand, }, - { general_operand, nonimmediate_operand, immediate_operand, immediate_operand, }, - { general_operand, nonimmediate_operand, immediate_operand, immediate_operand, }, - { general_operand, nonimmediate_operand, immediate_operand, immediate_operand, }, - { general_operand, nonimmediate_operand, immediate_operand, immediate_operand, }, - { general_operand, nonimmediate_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, immediate_operand, }, - { nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, general_operand, }, - { memory_operand, general_operand, general_operand, }, - { nonimmediate_operand, general_operand, general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0, }, - { register_operand, }, - { register_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { memory_operand, general_operand, }, - { memory_operand, general_operand, }, - { memory_operand, general_operand, }, - { 0, memory_operand, general_operand, }, - { 0, memory_operand, general_operand, }, - { 0, memory_operand, general_operand, }, - { 0, 0, 0, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { address_operand, }, - { general_operand, address_operand, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { register_operand, general_operand, general_operand, general_operand, }, - { nonimmediate_operand, }, - { general_operand, general_operand, }, - { nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - }; - -const int insn_n_alternatives[] = - { - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 3, - 4, - 3, - 0, - 2, - 2, - 0, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 4, - 1, - 1, - 5, - 1, - 6, - 8, - 0, - 5, - 3, - 7, - 1, - 2, - 2, - 2, - 0, - 0, - 0, - 2, - 2, - 2, - 2, - 1, - 1, - 0, - 2, - 2, - 0, - 2, - 1, - 1, - 0, - 2, - 1, - 0, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 4, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 0, - 2, - 1, - 0, - 2, - 1, - 4, - 1, - 2, - 2, - 2, - 2, - 0, - 3, - 1, - 0, - 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 2, - 1, - 0, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 3, - 1, - 0, - 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 2, - 2, - 0, - 2, - 2, - 1, - 0, - 2, - 1, - 0, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 1, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 1, - 1, - 1, - }; diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-peep.c b/gnu/usr.bin/gcc2/arch/m68k/insn-peep.c deleted file mode 100644 index ac2cb51fdd8..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-peep.c +++ /dev/null @@ -1,410 +0,0 @@ -/* Generated automatically by the program `genpeep' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "output.h" -#include "real.h" - -extern rtx peep_operand[]; - -#define operands peep_operand - -rtx -peephole (ins1) - rtx ins1; -{ - rtx insn, x, pat; - int i; - - if (NEXT_INSN (ins1) - && GET_CODE (NEXT_INSN (ins1)) == BARRIER) - return 0; - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L299; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L299; - if (GET_MODE (x) != SImode) goto L299; - if (XINT (x, 0) != 15) goto L299; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L299; - if (GET_MODE (x) != SImode) goto L299; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L299; - if (GET_MODE (x) != SImode) goto L299; - if (XINT (x, 0) != 15) goto L299; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L299; - if (XWINT (x, 0) != 4) goto L299; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L299; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L299; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L299; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, DFmode)) goto L299; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, DFmode)) goto L299; - if (! (FP_REG_P (operands[0]) && ! FP_REG_P (operands[1]))) goto L299; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 299; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L299: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L300; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L300; - if (GET_MODE (x) != SImode) goto L300; - if (XINT (x, 0) != 15) goto L300; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L300; - if (GET_MODE (x) != SImode) goto L300; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L300; - if (GET_MODE (x) != SImode) goto L300; - if (XINT (x, 0) != 15) goto L300; - x = XEXP (XEXP (pat, 1), 1); - operands[0] = x; - if (! immediate_operand (x, SImode)) goto L300; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L300; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L300; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L300; - x = XEXP (pat, 0); - operands[1] = x; - if (! push_operand (x, SFmode)) goto L300; - x = XEXP (pat, 1); - operands[2] = x; - if (! general_operand (x, SFmode)) goto L300; - if (! (GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2]))) goto L300; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 300; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L300: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L301; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L301; - if (GET_MODE (x) != SImode) goto L301; - if (XINT (x, 0) != 15) goto L301; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L301; - if (GET_MODE (x) != SImode) goto L301; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L301; - if (GET_MODE (x) != SImode) goto L301; - if (XINT (x, 0) != 15) goto L301; - x = XEXP (XEXP (pat, 1), 1); - operands[0] = x; - if (! immediate_operand (x, SImode)) goto L301; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L301; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L301; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L301; - x = XEXP (pat, 0); - operands[1] = x; - if (! push_operand (x, SImode)) goto L301; - x = XEXP (pat, 1); - operands[2] = x; - if (! general_operand (x, SImode)) goto L301; - if (! (GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2]))) goto L301; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 301; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L301: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L302; - x = XEXP (pat, 0); - if (GET_CODE (x) != MEM) goto L302; - if (GET_MODE (x) != QImode) goto L302; - x = XEXP (XEXP (pat, 0), 0); - if (GET_CODE (x) != PRE_DEC) goto L302; - if (GET_MODE (x) != SImode) goto L302; - x = XEXP (XEXP (XEXP (pat, 0), 0), 0); - if (GET_CODE (x) != REG) goto L302; - if (GET_MODE (x) != SImode) goto L302; - if (XINT (x, 0) != 15) goto L302; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, QImode)) goto L302; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L302; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L302; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L302; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L302; - if (GET_MODE (x) != SImode) goto L302; - if (XINT (x, 0) != 15) goto L302; - x = XEXP (pat, 1); - if (GET_CODE (x) != MINUS) goto L302; - if (GET_MODE (x) != SImode) goto L302; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L302; - if (GET_MODE (x) != SImode) goto L302; - if (XINT (x, 0) != 15) goto L302; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L302; - if (XWINT (x, 0) != 2) goto L302; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L302; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 302; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L302: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L303; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L303; - x = XEXP (pat, 1); - if (GET_CODE (x) != CONST_INT) goto L303; - if (XWINT (x, 0) != 0) goto L303; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L303; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L303; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L303; - x = XEXP (pat, 0); - if (GET_CODE (x) != STRICT_LOW_PART) goto L303; - x = XEXP (XEXP (pat, 0), 0); - if (GET_CODE (x) != SUBREG) goto L303; - if (GET_MODE (x) != HImode) goto L303; - x = XEXP (XEXP (XEXP (pat, 0), 0), 0); - if (!rtx_equal_p (operands[0], x)) goto L303; - x = XEXP (XEXP (pat, 0), 0); - if (XINT (x, 1) != 0) goto L303; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, HImode)) goto L303; - if (! (strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0]))) goto L303; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 303; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L303: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L304; - x = XEXP (pat, 0); - if (GET_CODE (x) != PC) goto L304; - x = XEXP (pat, 1); - if (GET_CODE (x) != IF_THEN_ELSE) goto L304; - x = XEXP (XEXP (pat, 1), 0); - operands[3] = x; - if (! valid_dbcc_comparison_p (x, VOIDmode)) goto L304; - x = XEXP (XEXP (XEXP (pat, 1), 0), 0); - if (GET_CODE (x) != CC0) goto L304; - x = XEXP (XEXP (XEXP (pat, 1), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L304; - if (XWINT (x, 0) != 0) goto L304; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != LABEL_REF) goto L304; - x = XEXP (XEXP (XEXP (pat, 1), 1), 0); - operands[2] = x; - x = XEXP (XEXP (pat, 1), 2); - if (GET_CODE (x) != PC) goto L304; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L304; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L304; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != PARALLEL) goto L304; - if (XVECLEN (x, 0) != 2) goto L304; - x = XVECEXP (pat, 0, 0); - if (GET_CODE (x) != SET) goto L304; - x = XEXP (XVECEXP (pat, 0, 0), 0); - if (GET_CODE (x) != PC) goto L304; - x = XEXP (XVECEXP (pat, 0, 0), 1); - if (GET_CODE (x) != IF_THEN_ELSE) goto L304; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0); - if (GET_CODE (x) != GE) goto L304; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0); - if (GET_CODE (x) != PLUS) goto L304; - if (GET_MODE (x) != HImode) goto L304; - x = XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 0); - operands[0] = x; - if (! register_operand (x, HImode)) goto L304; - x = XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L304; - if (XWINT (x, 0) != -1) goto L304; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L304; - if (XWINT (x, 0) != 0) goto L304; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1); - if (GET_CODE (x) != LABEL_REF) goto L304; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0); - operands[1] = x; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 2); - if (GET_CODE (x) != PC) goto L304; - x = XVECEXP (pat, 0, 1); - if (GET_CODE (x) != SET) goto L304; - x = XEXP (XVECEXP (pat, 0, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L304; - x = XEXP (XVECEXP (pat, 0, 1), 1); - if (GET_CODE (x) != PLUS) goto L304; - if (GET_MODE (x) != HImode) goto L304; - x = XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L304; - x = XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1); - if (GET_CODE (x) != CONST_INT) goto L304; - if (XWINT (x, 0) != -1) goto L304; - if (! (DATA_REG_P (operands[0]))) goto L304; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 304; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L304: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L305; - x = XEXP (pat, 0); - if (GET_CODE (x) != PC) goto L305; - x = XEXP (pat, 1); - if (GET_CODE (x) != IF_THEN_ELSE) goto L305; - x = XEXP (XEXP (pat, 1), 0); - operands[3] = x; - if (! valid_dbcc_comparison_p (x, VOIDmode)) goto L305; - x = XEXP (XEXP (XEXP (pat, 1), 0), 0); - if (GET_CODE (x) != CC0) goto L305; - x = XEXP (XEXP (XEXP (pat, 1), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L305; - if (XWINT (x, 0) != 0) goto L305; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != LABEL_REF) goto L305; - x = XEXP (XEXP (XEXP (pat, 1), 1), 0); - operands[2] = x; - x = XEXP (XEXP (pat, 1), 2); - if (GET_CODE (x) != PC) goto L305; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L305; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L305; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != PARALLEL) goto L305; - if (XVECLEN (x, 0) != 2) goto L305; - x = XVECEXP (pat, 0, 0); - if (GET_CODE (x) != SET) goto L305; - x = XEXP (XVECEXP (pat, 0, 0), 0); - if (GET_CODE (x) != PC) goto L305; - x = XEXP (XVECEXP (pat, 0, 0), 1); - if (GET_CODE (x) != IF_THEN_ELSE) goto L305; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0); - if (GET_CODE (x) != GE) goto L305; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0); - if (GET_CODE (x) != PLUS) goto L305; - if (GET_MODE (x) != SImode) goto L305; - x = XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L305; - x = XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L305; - if (XWINT (x, 0) != -1) goto L305; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1); - if (GET_CODE (x) != CONST_INT) goto L305; - if (XWINT (x, 0) != 0) goto L305; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1); - if (GET_CODE (x) != LABEL_REF) goto L305; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0); - operands[1] = x; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 2); - if (GET_CODE (x) != PC) goto L305; - x = XVECEXP (pat, 0, 1); - if (GET_CODE (x) != SET) goto L305; - x = XEXP (XVECEXP (pat, 0, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L305; - x = XEXP (XVECEXP (pat, 0, 1), 1); - if (GET_CODE (x) != PLUS) goto L305; - if (GET_MODE (x) != SImode) goto L305; - x = XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L305; - x = XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1); - if (GET_CODE (x) != CONST_INT) goto L305; - if (XWINT (x, 0) != -1) goto L305; - if (! (DATA_REG_P (operands[0]))) goto L305; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 305; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L305: - - return 0; -} - -rtx peep_operand[4]; diff --git a/gnu/usr.bin/gcc2/arch/m68k/insn-recog.c b/gnu/usr.bin/gcc2/arch/m68k/insn-recog.c deleted file mode 100644 index 1aea9785e4b..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/insn-recog.c +++ /dev/null @@ -1,6589 +0,0 @@ -/* Generated automatically by the program `genrecog' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "real.h" -#include "output.h" -#include "flags.h" - - -/* `recog' contains a decision tree - that recognizes whether the rtx X0 is a valid instruction. - - recog returns -1 if the rtx is not valid. - If the rtx is valid, recog returns a nonnegative number - which is the insn code number for the pattern that matched. - This is the same as the order in the machine description of - the entry that matched. This number can be used as an index into - entry that matched. This number can be used as an index into various - insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands - (found in insn-output.c). - - The third argument to recog is an optional pointer to an int. - If present, recog will accept a pattern if it matches except for - missing CLOBBER expressions at the end. In that case, the value - pointed to by the optional pointer will be set to the number of - CLOBBERs that need to be added (it should be initialized to zero by - the caller). If it is set nonzero, the caller should allocate a - PARALLEL of the appropriate size, copy the initial entries, and call - add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.*/ - -rtx recog_operand[MAX_RECOG_OPERANDS]; - -rtx *recog_operand_loc[MAX_RECOG_OPERANDS]; - -rtx *recog_dup_loc[MAX_DUP_OPERANDS]; - -char recog_dup_num[MAX_DUP_OPERANDS]; - -#define operands recog_operand - -int -recog_1 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case HImode: - switch (GET_CODE (x1)) - { - case TRUNCATE: - goto L628; - case ZERO_EXTEND: - goto L208; - case SIGN_EXTEND: - goto L220; - case FIX: - goto L313; - case PLUS: - goto L386; - case MINUS: - goto L455; - case MULT: - goto L501; - case DIV: - goto L623; - case UDIV: - goto L641; - case MOD: - goto L683; - case UMOD: - goto L701; - case AND: - goto L746; - case IOR: - goto L785; - case XOR: - goto L824; - case NEG: - goto L862; - case NOT: - goto L928; - } - } - if (general_operand (x1, HImode)) - { - ro[1] = x1; - return 30; - } - goto ret0; - - L628: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - switch (GET_CODE (x2)) - { - case DIV: - goto L629; - case UDIV: - goto L647; - case MOD: - goto L689; - case UMOD: - goto L707; - } - } - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 43; - } - goto ret0; - - L629: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L630; - } - goto ret0; - - L630: - x3 = XEXP (x2, 1); - switch (GET_CODE (x3)) - { - case SIGN_EXTEND: - if (GET_MODE (x3) == SImode && 1) - goto L631; - break; - case CONST_INT: - ro[2] = x3; - return 129; - } - goto ret0; - - L631: - x4 = XEXP (x3, 0); - if (nonimmediate_operand (x4, HImode)) - { - ro[2] = x4; - return 128; - } - goto ret0; - - L647: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L648; - } - goto ret0; - - L648: - x3 = XEXP (x2, 1); - switch (GET_CODE (x3)) - { - case ZERO_EXTEND: - if (GET_MODE (x3) == SImode && 1) - goto L649; - break; - case CONST_INT: - ro[2] = x3; - return 132; - } - goto ret0; - - L649: - x4 = XEXP (x3, 0); - if (nonimmediate_operand (x4, HImode)) - { - ro[2] = x4; - return 131; - } - goto ret0; - - L689: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L690; - } - goto ret0; - - L690: - x3 = XEXP (x2, 1); - switch (GET_CODE (x3)) - { - case SIGN_EXTEND: - if (GET_MODE (x3) == SImode && 1) - goto L691; - break; - case CONST_INT: - ro[2] = x3; - return 141; - } - goto ret0; - - L691: - x4 = XEXP (x3, 0); - if (nonimmediate_operand (x4, HImode)) - { - ro[2] = x4; - return 140; - } - goto ret0; - - L707: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L708; - } - goto ret0; - - L708: - x3 = XEXP (x2, 1); - switch (GET_CODE (x3)) - { - case ZERO_EXTEND: - if (GET_MODE (x3) == SImode && 1) - goto L709; - break; - case CONST_INT: - ro[2] = x3; - return 144; - } - goto ret0; - - L709: - x4 = XEXP (x3, 0); - if (nonimmediate_operand (x4, HImode)) - { - ro[2] = x4; - return 143; - } - goto ret0; - - L208: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - return 48; - } - goto ret0; - - L220: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - return 51; - } - goto ret0; - - L313: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == FIX && 1) - goto L314; - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 76; - } - L357: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 79; - } - goto ret0; - - L314: - x3 = XEXP (x2, 0); - if (pnum_clobbers != 0 && register_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_68040) - { - *pnum_clobbers = 2; - return 71; - } - } - goto ret0; - - L386: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L387; - } - goto ret0; - - L387: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 85; - } - goto ret0; - - L455: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L456; - } - goto ret0; - - L456: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 99; - } - goto ret0; - - L501: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L502; - } - goto ret0; - - L502: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 109; - } - goto ret0; - - L623: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L624; - } - goto ret0; - - L624: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 127; - } - goto ret0; - - L641: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L642; - } - goto ret0; - - L642: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 130; - } - goto ret0; - - L683: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L684; - } - goto ret0; - - L684: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 139; - } - goto ret0; - - L701: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L702; - } - goto ret0; - - L702: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 142; - } - goto ret0; - - L746: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L747; - } - goto ret0; - - L747: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 148; - } - goto ret0; - - L785: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L786; - } - goto ret0; - - L786: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 155; - } - goto ret0; - - L824: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L825; - } - goto ret0; - - L825: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 162; - } - goto ret0; - - L862: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 169; - } - goto ret0; - - L928: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 187; - } - goto ret0; - ret0: return -1; -} - -int -recog_2 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case QImode: - switch (GET_CODE (x1)) - { - case TRUNCATE: - goto L192; - case FIX: - goto L328; - case PLUS: - goto L403; - case MINUS: - goto L466; - case AND: - goto L763; - case IOR: - goto L802; - case XOR: - goto L841; - case NEG: - goto L871; - case NOT: - goto L937; - case EQ: - goto L1275; - case NE: - goto L1280; - case GT: - goto L1285; - case GTU: - goto L1290; - case LT: - goto L1295; - case LTU: - goto L1300; - case GE: - goto L1305; - case GEU: - goto L1310; - case LE: - goto L1315; - case LEU: - goto L1320; - } - } - if (general_operand (x1, QImode)) - { - ro[1] = x1; - return 32; - } - goto ret0; - - L192: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 41; - } - L196: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 42; - } - goto ret0; - - L328: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == FIX && 1) - goto L329; - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 75; - } - L353: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 78; - } - goto ret0; - - L329: - x3 = XEXP (x2, 0); - if (pnum_clobbers != 0 && register_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_68040) - { - *pnum_clobbers = 2; - return 72; - } - } - goto ret0; - - L403: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L404; - } - goto ret0; - - L404: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 88; - } - goto ret0; - - L466: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L467; - } - goto ret0; - - L467: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 101; - } - goto ret0; - - L763: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L764; - } - goto ret0; - - L764: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 151; - } - goto ret0; - - L802: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L803; - } - goto ret0; - - L803: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 158; - } - goto ret0; - - L841: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L842; - } - goto ret0; - - L842: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 165; - } - goto ret0; - - L871: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 171; - } - goto ret0; - - L937: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 189; - } - goto ret0; - - L1275: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1276; - goto ret0; - - L1276: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 248; - goto ret0; - - L1280: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1281; - goto ret0; - - L1281: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 249; - goto ret0; - - L1285: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1286; - goto ret0; - - L1286: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 250; - goto ret0; - - L1290: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1291; - goto ret0; - - L1291: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 251; - goto ret0; - - L1295: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1296; - goto ret0; - - L1296: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 252; - goto ret0; - - L1300: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1301; - goto ret0; - - L1301: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 253; - goto ret0; - - L1305: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1306; - goto ret0; - - L1306: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 254; - goto ret0; - - L1310: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1311; - goto ret0; - - L1311: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 255; - goto ret0; - - L1315: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1316; - goto ret0; - - L1316: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 256; - goto ret0; - - L1320: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1321; - goto ret0; - - L1321: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 257; - goto ret0; - ret0: return -1; -} - -int -recog_3 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SImode) - goto ret0; - switch (GET_CODE (x1)) - { - case PLUS: - goto L375; - case MINUS: - goto L444; - case MULT: - goto L506; - case IOR: - goto L780; - case XOR: - goto L819; - case NEG: - goto L858; - case NOT: - goto L924; - case ZERO_EXTRACT: - goto L1168; - case SIGN_EXTRACT: - goto L1180; - } - goto ret0; - - L375: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L381; - } - goto ret0; - - L381: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == SIGN_EXTEND && 1) - goto L382; - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 83; - } - goto ret0; - - L382: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[2] = x3; - return 84; - } - goto ret0; - - L444: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L450; - } - goto ret0; - - L450: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == SIGN_EXTEND && 1) - goto L451; - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 97; - } - goto ret0; - - L451: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[2] = x3; - return 98; - } - goto ret0; - - L506: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - switch (GET_CODE (x2)) - { - case SIGN_EXTEND: - goto L507; - case ZERO_EXTEND: - goto L525; - } - } - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L520; - } - goto ret0; - - L507: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[1] = x3; - goto L508; - } - goto ret0; - - L508: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case SIGN_EXTEND: - if (GET_MODE (x2) == SImode && 1) - goto L509; - break; - case CONST_INT: - ro[2] = x2; - if (INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff) - return 111; - } - goto ret0; - - L509: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[2] = x3; - return 110; - } - goto ret0; - - L525: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[1] = x3; - goto L526; - } - goto ret0; - - L526: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case ZERO_EXTEND: - if (GET_MODE (x2) == SImode && 1) - goto L527; - break; - case CONST_INT: - ro[2] = x2; - if (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff) - return 114; - } - goto ret0; - - L527: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, HImode)) - { - ro[2] = x3; - return 113; - } - goto ret0; - - L520: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_68020) - return 112; - } - goto ret0; - - L780: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L781; - } - goto ret0; - - L781: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 154; - } - goto ret0; - - L819: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L820; - } - goto ret0; - - L820: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 161; - } - goto ret0; - - L858: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 168; - } - goto ret0; - - L924: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 186; - } - goto ret0; - - L1168: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - goto L1169; - } - break; - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[1] = x2; - goto L1175; - } - } - goto ret0; - - L1169: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1170; - } - L1199: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1200; - } - goto ret0; - - L1170: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 32) - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))) - return 231; - } - x2 = XEXP (x1, 1); - goto L1199; - - L1200: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD) - return 236; - } - goto ret0; - - L1175: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1176; - } - L1240: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1241; - } - goto ret0; - - L1176: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && GET_CODE (operands[3]) == CONST_INT - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))) - return 232; - } - x2 = XEXP (x1, 1); - goto L1240; - - L1241: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD) - return 242; - } - goto ret0; - - L1180: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - goto L1181; - } - break; - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[1] = x2; - goto L1187; - } - } - goto ret0; - - L1181: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1182; - } - L1193: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1194; - } - goto ret0; - - L1182: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 32) - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))) - return 233; - } - x2 = XEXP (x1, 1); - goto L1193; - - L1194: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD) - return 235; - } - goto ret0; - - L1187: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1188; - } - L1234: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1235; - } - goto ret0; - - L1188: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && GET_CODE (operands[3]) == CONST_INT - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))) - return 234; - } - x2 = XEXP (x1, 1); - goto L1234; - - L1235: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD) - return 241; - } - goto ret0; - ret0: return -1; -} - -int -recog_4 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (general_operand (x2, HImode)) - { - ro[0] = x2; - goto L391; - } - L967: - if (register_operand (x2, HImode)) - { - ro[0] = x2; - goto L968; - } - break; - case QImode: - if (general_operand (x2, QImode)) - { - ro[0] = x2; - goto L408; - } - L978: - if (register_operand (x2, QImode)) - { - ro[0] = x2; - goto L979; - } - } - goto ret0; - - L391: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case HImode: - switch (GET_CODE (x1)) - { - case PLUS: - goto L392; - case MINUS: - goto L461; - case AND: - goto L752; - case IOR: - goto L791; - case XOR: - goto L830; - case NEG: - goto L867; - case NOT: - goto L933; - } - } - if (general_operand (x1, HImode)) - { - ro[1] = x1; - return 31; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L392: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L393; - L398: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L399; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L393: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 86; - } - x2 = XEXP (x1, 0); - goto L398; - - L399: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 87; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L461: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L462; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L462: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 100; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L752: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L753; - L758: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L759; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L753: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 149; - } - x2 = XEXP (x1, 0); - goto L758; - - L759: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 150; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L791: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L792; - L797: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L798; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L792: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 156; - } - x2 = XEXP (x1, 0); - goto L797; - - L798: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 157; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L830: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L831; - L836: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L837; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L831: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 163; - } - x2 = XEXP (x1, 0); - goto L836; - - L837: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 164; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L867: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - return 170; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L933: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - return 188; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L967; - - L968: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != HImode) - goto ret0; - switch (GET_CODE (x1)) - { - case ASHIFT: - goto L969; - case ASHIFTRT: - goto L1008; - case LSHIFT: - goto L1047; - case LSHIFTRT: - goto L1086; - case ROTATE: - goto L1113; - case ROTATERT: - goto L1140; - } - goto ret0; - - L969: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L970; - goto ret0; - - L970: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 195; - } - goto ret0; - - L1008: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1009; - goto ret0; - - L1009: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 202; - } - goto ret0; - - L1047: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1048; - goto ret0; - - L1048: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 209; - } - goto ret0; - - L1086: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1087; - goto ret0; - - L1087: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 216; - } - goto ret0; - - L1113: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1114; - goto ret0; - - L1114: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 221; - } - goto ret0; - - L1140: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1141; - goto ret0; - - L1141: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 226; - } - goto ret0; - - L408: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case QImode: - switch (GET_CODE (x1)) - { - case PLUS: - goto L409; - case MINUS: - goto L472; - case AND: - goto L769; - case IOR: - goto L808; - case XOR: - goto L847; - case NEG: - goto L876; - case NOT: - goto L942; - } - } - if (general_operand (x1, QImode)) - { - ro[1] = x1; - return 33; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L409: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L410; - L415: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L416; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L410: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 89; - } - x2 = XEXP (x1, 0); - goto L415; - - L416: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 90; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L472: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L473; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L473: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 102; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L769: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L770; - L775: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L776; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L770: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 152; - } - x2 = XEXP (x1, 0); - goto L775; - - L776: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 153; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L808: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L809; - L814: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L815; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L809: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 159; - } - x2 = XEXP (x1, 0); - goto L814; - - L815: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 160; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L847: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L848; - L853: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L854; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L848: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 166; - } - x2 = XEXP (x1, 0); - goto L853; - - L854: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 167; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L876: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - return 172; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L942: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - return 190; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L978; - - L979: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != QImode) - goto ret0; - switch (GET_CODE (x1)) - { - case ASHIFT: - goto L980; - case ASHIFTRT: - goto L1019; - case LSHIFT: - goto L1058; - case LSHIFTRT: - goto L1097; - case ROTATE: - goto L1124; - case ROTATERT: - goto L1151; - } - goto ret0; - - L980: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L981; - goto ret0; - - L981: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 197; - } - goto ret0; - - L1019: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1020; - goto ret0; - - L1020: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 204; - } - goto ret0; - - L1058: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1059; - goto ret0; - - L1059: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 211; - } - goto ret0; - - L1097: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1098; - goto ret0; - - L1098: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 218; - } - goto ret0; - - L1124: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1125; - goto ret0; - - L1125: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 223; - } - goto ret0; - - L1151: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1152; - goto ret0; - - L1152: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 228; - } - goto ret0; - ret0: return -1; -} - -int -recog_5 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 1); - x2 = XEXP (x1, 0); - switch (GET_CODE (x2)) - { - case EQ: - goto L1326; - case NE: - goto L1335; - case GT: - goto L1344; - case GTU: - goto L1353; - case LT: - goto L1362; - case LTU: - goto L1371; - case GE: - goto L1380; - case GEU: - goto L1389; - case LE: - goto L1398; - case LEU: - goto L1407; - } - goto ret0; - - L1326: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1327; - goto ret0; - - L1327: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1328; - goto ret0; - - L1328: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1329; - case PC: - goto L1419; - } - goto ret0; - - L1329: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1330; - - L1330: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 258; - goto ret0; - - L1419: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1420; - goto ret0; - - L1420: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 268; - - L1335: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1336; - goto ret0; - - L1336: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1337; - goto ret0; - - L1337: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1338; - case PC: - goto L1428; - } - goto ret0; - - L1338: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1339; - - L1339: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 259; - goto ret0; - - L1428: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1429; - goto ret0; - - L1429: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 269; - - L1344: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1345; - goto ret0; - - L1345: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1346; - goto ret0; - - L1346: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1347; - case PC: - goto L1437; - } - goto ret0; - - L1347: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1348; - - L1348: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 260; - goto ret0; - - L1437: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1438; - goto ret0; - - L1438: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 270; - - L1353: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1354; - goto ret0; - - L1354: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1355; - goto ret0; - - L1355: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1356; - case PC: - goto L1446; - } - goto ret0; - - L1356: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1357; - - L1357: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 261; - goto ret0; - - L1446: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1447; - goto ret0; - - L1447: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 271; - - L1362: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1363; - goto ret0; - - L1363: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1364; - goto ret0; - - L1364: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1365; - case PC: - goto L1455; - } - goto ret0; - - L1365: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1366; - - L1366: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 262; - goto ret0; - - L1455: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1456; - goto ret0; - - L1456: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 272; - - L1371: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1372; - goto ret0; - - L1372: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1373; - goto ret0; - - L1373: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1374; - case PC: - goto L1464; - } - goto ret0; - - L1374: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1375; - - L1375: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 263; - goto ret0; - - L1464: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1465; - goto ret0; - - L1465: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 273; - - L1380: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1381; - goto ret0; - - L1381: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1382; - goto ret0; - - L1382: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1383; - case PC: - goto L1473; - } - goto ret0; - - L1383: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1384; - - L1384: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 264; - goto ret0; - - L1473: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1474; - goto ret0; - - L1474: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 274; - - L1389: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1390; - goto ret0; - - L1390: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1391; - goto ret0; - - L1391: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1392; - case PC: - goto L1482; - } - goto ret0; - - L1392: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1393; - - L1393: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 265; - goto ret0; - - L1482: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1483; - goto ret0; - - L1483: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 275; - - L1398: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1399; - goto ret0; - - L1399: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1400; - goto ret0; - - L1400: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1401; - case PC: - goto L1491; - } - goto ret0; - - L1401: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1402; - - L1402: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 266; - goto ret0; - - L1491: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1492; - goto ret0; - - L1492: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 276; - - L1407: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L1408; - goto ret0; - - L1408: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1409; - goto ret0; - - L1409: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L1410; - case PC: - goto L1500; - } - goto ret0; - - L1410: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1411; - - L1411: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 267; - goto ret0; - - L1500: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1501; - goto ret0; - - L1501: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 277; - ret0: return -1; -} - -int -recog_6 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XEXP (x0, 0); - switch (GET_MODE (x1)) - { - case DFmode: - if (GET_CODE (x1) == MEM && push_operand (x1, DFmode)) - { - ro[0] = x1; - goto L2; - } - L173: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - goto L227; - } - break; - case DImode: - if (GET_CODE (x1) == MEM && push_operand (x1, DImode)) - { - ro[0] = x1; - goto L5; - } - L184: - if (general_operand (x1, DImode)) - { - ro[0] = x1; - goto L185; - } - break; - case SImode: - if (GET_CODE (x1) == MEM && push_operand (x1, SImode)) - { - ro[0] = x1; - goto L148; - } - L150: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L203; - } - break; - case HImode: - if (general_operand (x1, HImode)) - { - ro[0] = x1; - goto L199; - } - L961: - if (register_operand (x1, HImode)) - { - ro[0] = x1; - goto L962; - } - break; - case QImode: - if (general_operand (x1, QImode)) - { - ro[0] = x1; - goto L191; - } - L972: - if (register_operand (x1, QImode)) - { - ro[0] = x1; - goto L973; - } - break; - case SFmode: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - goto L237; - } - break; - case XFmode: - if (nonimmediate_operand (x1, XFmode)) - { - ro[0] = x1; - goto L177; - } - } - L187: - switch (GET_MODE (x1)) - { - case SImode: - switch (GET_CODE (x1)) - { - case MEM: - if (push_operand (x1, SImode)) - { - ro[0] = x1; - goto L188; - } - break; - case ZERO_EXTRACT: - goto L1155; - } - L373: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L374; - } - L739: - if (not_sp_operand (x1, SImode)) - { - ro[0] = x1; - goto L740; - } - L944: - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L945; - } - } - switch (GET_CODE (x1)) - { - case CC0: - goto L8; - case STRICT_LOW_PART: - goto L160; - case PC: - goto L1324; - } - L1595: - ro[0] = x1; - goto L1596; - L1612: - switch (GET_CODE (x1)) - { - case PC: - goto L1613; - case CC0: - goto L1703; - } - switch (GET_MODE (x1)) - { - case SImode: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L1751; - } - break; - case DFmode: - if (register_operand (x1, DFmode)) - { - ro[0] = x1; - goto L1619; - } - L1718: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - goto L1719; - } - break; - case SFmode: - if (register_operand (x1, SFmode)) - { - ro[0] = x1; - goto L1626; - } - L1722: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - goto L1723; - } - break; - case XFmode: - if (general_operand (x1, XFmode)) - { - ro[0] = x1; - goto L1711; - } - break; - case QImode: - if (general_operand (x1, QImode)) - { - ro[0] = x1; - goto L1743; - } - break; - case HImode: - if (general_operand (x1, HImode)) - { - ro[0] = x1; - goto L1747; - } - } - goto ret0; - - L2: - x1 = XEXP (x0, 1); - if (general_operand (x1, DFmode)) - { - ro[1] = x1; - return 0; - } - x1 = XEXP (x0, 0); - goto L173; - - L227: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case DFmode: - switch (GET_CODE (x1)) - { - case FLOAT_EXTEND: - goto L228; - case FLOAT: - goto L262; - case FIX: - goto L333; - case PLUS: - goto L420; - case MINUS: - goto L477; - case MULT: - goto L599; - case DIV: - goto L659; - case NEG: - goto L890; - case SQRT: - goto L900; - case ABS: - goto L914; - } - } - if (general_operand (x1, DFmode)) - { - ro[1] = x1; - return 35; - } - x1 = XEXP (x0, 0); - goto L1595; - - L228: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - goto L233; - x1 = XEXP (x0, 0); - goto L1595; - - L233: - ro[1] = x2; - if (TARGET_FPA) - return 54; - L234: - ro[1] = x2; - if (TARGET_68881) - return 55; - x1 = XEXP (x0, 0); - goto L1595; - - L262: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - goto L267; - L276: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 67; - } - L284: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 69; - } - x1 = XEXP (x0, 0); - goto L1595; - - L267: - ro[1] = x2; - if (TARGET_FPA) - return 64; - L268: - ro[1] = x2; - if (TARGET_68881) - return 65; - goto L276; - - L333: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881 && !TARGET_68040) - return 73; - } - x1 = XEXP (x0, 0); - goto L1595; - - L420: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L421; - } - x1 = XEXP (x0, 0); - goto L1595; - - L421: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - goto L427; - x1 = XEXP (x0, 0); - goto L1595; - - L427: - ro[2] = x2; - if (TARGET_FPA) - return 92; - L428: - ro[2] = x2; - if (TARGET_68881) - return 93; - x1 = XEXP (x0, 0); - goto L1595; - - L477: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L478; - } - x1 = XEXP (x0, 0); - goto L1595; - - L478: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - goto L484; - x1 = XEXP (x0, 0); - goto L1595; - - L484: - ro[2] = x2; - if (TARGET_FPA) - return 104; - L485: - ro[2] = x2; - if (TARGET_68881) - return 105; - x1 = XEXP (x0, 0); - goto L1595; - - L599: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L600; - } - x1 = XEXP (x0, 0); - goto L1595; - - L600: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - goto L606; - x1 = XEXP (x0, 0); - goto L1595; - - L606: - ro[2] = x2; - if (TARGET_FPA) - return 122; - L607: - ro[2] = x2; - if (TARGET_68881) - return 123; - x1 = XEXP (x0, 0); - goto L1595; - - L659: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L660; - } - x1 = XEXP (x0, 0); - goto L1595; - - L660: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - goto L666; - x1 = XEXP (x0, 0); - goto L1595; - - L666: - ro[2] = x2; - if (TARGET_FPA) - return 134; - L667: - ro[2] = x2; - if (TARGET_68881) - return 135; - x1 = XEXP (x0, 0); - goto L1595; - - L890: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - goto L895; - x1 = XEXP (x0, 0); - goto L1595; - - L895: - ro[1] = x2; - if (TARGET_FPA) - return 177; - L896: - ro[1] = x2; - if (TARGET_68881) - return 178; - x1 = XEXP (x0, 0); - goto L1595; - - L900: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 179; - } - x1 = XEXP (x0, 0); - goto L1595; - - L914: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - goto L919; - x1 = XEXP (x0, 0); - goto L1595; - - L919: - ro[1] = x2; - if (TARGET_FPA) - return 184; - L920: - ro[1] = x2; - if (TARGET_68881) - return 185; - x1 = XEXP (x0, 0); - goto L1595; - - L5: - x1 = XEXP (x0, 1); - if (general_operand (x1, DImode)) - { - ro[1] = x1; - return 1; - } - x1 = XEXP (x0, 0); - goto L184; - - L185: - x1 = XEXP (x0, 1); - if (general_operand (x1, DImode)) - { - ro[1] = x1; - return 39; - } - x1 = XEXP (x0, 0); - goto L1595; - - L148: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[1] = x1; - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >= -0x8000 - && INTVAL (operands[1]) < 0x8000) - return 26; - } - x1 = XEXP (x0, 0); - goto L150; - - L203: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - switch (GET_CODE (x1)) - { - case ZERO_EXTEND: - goto L204; - case SIGN_EXTEND: - goto L216; - case FIX: - goto L298; - } - } - if (GET_CODE (x1) == CONST_INT && XWINT (x1, 0) == 0 && 1) - if ((TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) - return 27; - L154: - if (general_operand (x1, SImode)) - { - ro[1] = x1; - return 29; - } - x1 = XEXP (x0, 0); - goto L187; - - L204: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[1] = x2; - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - return 47; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - return 49; - } - } - x1 = XEXP (x0, 0); - goto L187; - - L216: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[1] = x2; - return 50; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - if (TARGET_68020) - return 52; - } - } - x1 = XEXP (x0, 0); - goto L187; - - L298: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case DFmode: - switch (GET_CODE (x2)) - { - case FIX: - goto L299; - } - break; - case SFmode: - if (GET_CODE (x2) == FIX && 1) - goto L366; - } - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 77; - } - L361: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 80; - } - x1 = XEXP (x0, 0); - goto L187; - - L299: - x3 = XEXP (x2, 0); - if (pnum_clobbers != 0 && register_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_68040) - { - *pnum_clobbers = 2; - return 70; - } - } - L371: - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_FPA) - return 82; - } - x1 = XEXP (x0, 0); - goto L187; - - L366: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_FPA) - return 81; - } - x1 = XEXP (x0, 0); - goto L187; - L199: - tem = recog_1 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L961; - - L962: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != HImode) - { - x1 = XEXP (x0, 0); - goto L1595; - } - switch (GET_CODE (x1)) - { - case ASHIFT: - goto L963; - case ASHIFTRT: - goto L1002; - case LSHIFT: - goto L1041; - case LSHIFTRT: - goto L1080; - case ROTATE: - goto L1107; - case ROTATERT: - goto L1134; - } - x1 = XEXP (x0, 0); - goto L1595; - - L963: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L964; - } - x1 = XEXP (x0, 0); - goto L1595; - - L964: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 194; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1002: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L1003; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1003: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 201; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1041: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L1042; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1042: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 208; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1080: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L1081; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1081: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 215; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1107: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L1108; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1108: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 220; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1134: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L1135; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1135: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 225; - } - x1 = XEXP (x0, 0); - goto L1595; - L191: - tem = recog_2 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L972; - - L973: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != QImode) - { - x1 = XEXP (x0, 0); - goto L1595; - } - switch (GET_CODE (x1)) - { - case ASHIFT: - goto L974; - case ASHIFTRT: - goto L1013; - case LSHIFT: - goto L1052; - case LSHIFTRT: - goto L1091; - case ROTATE: - goto L1118; - case ROTATERT: - goto L1145; - } - x1 = XEXP (x0, 0); - goto L1595; - - L974: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L975; - } - x1 = XEXP (x0, 0); - goto L1595; - - L975: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 196; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1013: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L1014; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1014: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 203; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1052: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L1053; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1053: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 210; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1091: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L1092; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1092: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 217; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1118: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L1119; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1119: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 222; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1145: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[1] = x2; - goto L1146; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1146: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 227; - } - x1 = XEXP (x0, 0); - goto L1595; - - L237: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SFmode: - switch (GET_CODE (x1)) - { - case FLOAT_TRUNCATE: - goto L238; - case FLOAT: - goto L252; - case FIX: - goto L337; - case PLUS: - goto L432; - case MINUS: - goto L489; - case MULT: - goto L611; - case DIV: - goto L671; - case NEG: - goto L880; - case ABS: - goto L904; - } - } - if (general_operand (x1, SFmode)) - { - ro[1] = x1; - return 34; - } - x1 = XEXP (x0, 0); - goto L1595; - - L238: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - goto L243; - L248: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 59; - } - x1 = XEXP (x0, 0); - goto L1595; - - L243: - ro[1] = x2; - if (TARGET_FPA) - return 57; - L244: - ro[1] = x2; - if (TARGET_68040_ONLY) - return 58; - goto L248; - - L252: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - goto L257; - L272: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 66; - } - L280: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 68; - } - x1 = XEXP (x0, 0); - goto L1595; - - L257: - ro[1] = x2; - if (TARGET_FPA) - return 61; - L258: - ro[1] = x2; - if (TARGET_68881) - return 62; - goto L272; - - L337: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_68881 && !TARGET_68040) - return 74; - } - x1 = XEXP (x0, 0); - goto L1595; - - L432: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L433; - } - x1 = XEXP (x0, 0); - goto L1595; - - L433: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - goto L439; - x1 = XEXP (x0, 0); - goto L1595; - - L439: - ro[2] = x2; - if (TARGET_FPA) - return 95; - L440: - ro[2] = x2; - if (TARGET_68881) - return 96; - x1 = XEXP (x0, 0); - goto L1595; - - L489: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L490; - } - x1 = XEXP (x0, 0); - goto L1595; - - L490: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - goto L496; - x1 = XEXP (x0, 0); - goto L1595; - - L496: - ro[2] = x2; - if (TARGET_FPA) - return 107; - L497: - ro[2] = x2; - if (TARGET_68881) - return 108; - x1 = XEXP (x0, 0); - goto L1595; - - L611: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L612; - } - x1 = XEXP (x0, 0); - goto L1595; - - L612: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - goto L618; - x1 = XEXP (x0, 0); - goto L1595; - - L618: - ro[2] = x2; - if (TARGET_FPA) - return 125; - L619: - ro[2] = x2; - if (TARGET_68881) - return 126; - x1 = XEXP (x0, 0); - goto L1595; - - L671: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L672; - } - x1 = XEXP (x0, 0); - goto L1595; - - L672: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - goto L678; - x1 = XEXP (x0, 0); - goto L1595; - - L678: - ro[2] = x2; - if (TARGET_FPA) - return 137; - L679: - ro[2] = x2; - if (TARGET_68881) - return 138; - x1 = XEXP (x0, 0); - goto L1595; - - L880: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - goto L885; - x1 = XEXP (x0, 0); - goto L1595; - - L885: - ro[1] = x2; - if (TARGET_FPA) - return 174; - L886: - ro[1] = x2; - if (TARGET_68881) - return 175; - x1 = XEXP (x0, 0); - goto L1595; - - L904: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - goto L909; - x1 = XEXP (x0, 0); - goto L1595; - - L909: - ro[1] = x2; - if (TARGET_FPA) - return 181; - L910: - ro[1] = x2; - if (TARGET_68881) - return 182; - x1 = XEXP (x0, 0); - goto L1595; - - L177: - x1 = XEXP (x0, 1); - if (nonimmediate_operand (x1, XFmode)) - goto L181; - x1 = XEXP (x0, 0); - goto L1595; - - L181: - ro[1] = x1; - if (TARGET_68881) - return 37; - L182: - ro[1] = x1; - if (! TARGET_68881) - return 38; - x1 = XEXP (x0, 0); - goto L1595; - - L188: - x1 = XEXP (x0, 1); - if (address_operand (x1, SImode)) - { - ro[1] = x1; - return 40; - } - x1 = XEXP (x0, 0); - goto L373; - - L1155: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[0] = x2; - goto L1156; - } - break; - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[0] = x2; - goto L1162; - } - } - goto L739; - - L1156: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[1] = x2; - goto L1157; - } - L1204: - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L1205; - } - goto L739; - - L1157: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1158; - } - x2 = XEXP (x1, 1); - goto L1204; - - L1158: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[3] = x1; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 32) - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[0], 0))) - return 229; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 1); - goto L1204; - - L1205: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1206; - } - goto L739; - - L1206: - x1 = XEXP (x0, 1); - switch (GET_CODE (x1)) - { - case XOR: - if (GET_MODE (x1) == SImode && 1) - goto L1207; - break; - case CONST_INT: - if (XWINT (x1, 0) == 0 && 1) - if (TARGET_68020 && TARGET_BITFIELD) - return 238; - if (XWINT (x1, 0) == -1 && 1) - if (TARGET_68020 && TARGET_BITFIELD) - return 239; - } - L1229: - if (general_operand (x1, SImode)) - { - ro[3] = x1; - if (TARGET_68020 && TARGET_BITFIELD) - return 240; - } - x1 = XEXP (x0, 0); - goto L739; - - L1207: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == ZERO_EXTRACT && 1) - goto L1208; - x1 = XEXP (x0, 0); - goto L739; - - L1208: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L1209; - x1 = XEXP (x0, 0); - goto L739; - - L1209: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[1]) && 1) - goto L1210; - x1 = XEXP (x0, 0); - goto L739; - - L1210: - x3 = XEXP (x2, 2); - if (rtx_equal_p (x3, ro[2]) && 1) - goto L1211; - x1 = XEXP (x0, 0); - goto L739; - - L1211: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, VOIDmode)) - { - ro[3] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) == -1 - || (GET_CODE (operands[1]) == CONST_INT - && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))) - return 237; - } - x1 = XEXP (x0, 0); - goto L739; - - L1162: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[1] = x2; - goto L1163; - } - L1245: - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L1246; - } - goto L739; - - L1163: - x2 = XEXP (x1, 2); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - goto L1164; - } - x2 = XEXP (x1, 1); - goto L1245; - - L1164: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[3] = x1; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) - && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 - && (GET_CODE (operands[0]) == REG - || ! mode_dependent_address_p (XEXP (operands[0], 0)))) - return 230; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 1); - goto L1245; - - L1246: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L1247; - } - goto L739; - - L1247: - x1 = XEXP (x0, 1); - switch (GET_CODE (x1)) - { - case CONST_INT: - if (XWINT (x1, 0) == 0 && 1) - if (TARGET_68020 && TARGET_BITFIELD) - return 243; - if (XWINT (x1, 0) == -1 && 1) - if (TARGET_68020 && TARGET_BITFIELD) - return 244; - } - L1259: - if (general_operand (x1, SImode)) - { - ro[3] = x1; - if (TARGET_68020 && TARGET_BITFIELD) - return 245; - } - x1 = XEXP (x0, 0); - goto L739; - L374: - tem = recog_3 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L739; - - L740: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SImode && GET_CODE (x1) == AND && 1) - goto L741; - x1 = XEXP (x0, 0); - goto L944; - - L741: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L742; - } - x1 = XEXP (x0, 0); - goto L944; - - L742: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 147; - } - x1 = XEXP (x0, 0); - goto L944; - - L945: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SImode) - { - x1 = XEXP (x0, 0); - goto L1595; - } - switch (GET_CODE (x1)) - { - case ASHIFT: - goto L946; - case ASHIFTRT: - goto L985; - case LSHIFT: - goto L1024; - case LSHIFTRT: - goto L1063; - case ROTATE: - goto L1102; - case ROTATERT: - goto L1129; - } - x1 = XEXP (x0, 0); - goto L1595; - - L946: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L947; - } - x1 = XEXP (x0, 0); - goto L1595; - - L947: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - goto L953; - L959: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 193; - } - x1 = XEXP (x0, 0); - goto L1595; - - L953: - ro[2] = x2; - if ((GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)) - return 191; - L954: - ro[2] = x2; - if ((! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)) - return 192; - goto L959; - - L985: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L986; - } - x1 = XEXP (x0, 0); - goto L1595; - - L986: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - goto L992; - L998: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 200; - } - x1 = XEXP (x0, 0); - goto L1595; - - L992: - ro[2] = x2; - if ((GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)) - return 198; - L993: - ro[2] = x2; - if ((! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)) - return 199; - goto L998; - - L1024: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1025; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1025: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - goto L1031; - L1037: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 207; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1031: - ro[2] = x2; - if ((GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)) - return 205; - L1032: - ro[2] = x2; - if ((! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)) - return 206; - goto L1037; - - L1063: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1064; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1064: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - goto L1070; - L1076: - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 214; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1070: - ro[2] = x2; - if ((GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)) - return 212; - L1071: - ro[2] = x2; - if ((! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)) - return 213; - goto L1076; - - L1102: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1103; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1103: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 219; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1129: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1130; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1130: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 224; - } - x1 = XEXP (x0, 0); - goto L1595; - - L8: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - if (nonimmediate_operand (x1, SImode)) - { - ro[0] = x1; - return 2; - } - break; - case HImode: - if (nonimmediate_operand (x1, HImode)) - { - ro[0] = x1; - return 3; - } - break; - case QImode: - if (nonimmediate_operand (x1, QImode)) - { - ro[0] = x1; - return 4; - } - } - switch (GET_CODE (x1)) - { - case COMPARE: - goto L46; - case ZERO_EXTRACT: - goto L101; - case CONST_INT: - case CONST_DOUBLE: - case CONST: - case SYMBOL_REF: - case LABEL_REF: - case SUBREG: - case REG: - case MEM: - L23: - if (general_operand (x1, SFmode)) - goto L27; - } - L37: - if (general_operand (x1, DFmode)) - goto L41; - L1262: - if (GET_MODE (x1) == SImode && GET_CODE (x1) == ZERO_EXTRACT && 1) - goto L1263; - x1 = XEXP (x0, 0); - goto L1595; - - L46: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[0] = x2; - goto L47; - } - break; - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[0] = x2; - goto L52; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[0] = x2; - goto L57; - } - break; - case DFmode: - if (general_operand (x2, DFmode)) - { - ro[0] = x2; - goto L70; - } - break; - case SFmode: - if (general_operand (x2, SFmode)) - { - ro[0] = x2; - goto L90; - } - } - x1 = XEXP (x0, 0); - goto L1595; - - L47: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 11; - } - x1 = XEXP (x0, 0); - goto L1595; - - L52: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 12; - } - x1 = XEXP (x0, 0); - goto L1595; - - L57: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 13; - } - x1 = XEXP (x0, 0); - goto L1595; - - L70: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - goto L76; - x1 = XEXP (x0, 0); - goto L1595; - - L76: - if (pnum_clobbers != 0 && 1) - { - ro[1] = x2; - if (TARGET_FPA) - { - *pnum_clobbers = 1; - return 15; - } - } - L77: - ro[1] = x2; - if (TARGET_68881) - return 16; - x1 = XEXP (x0, 0); - goto L1595; - - L90: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - goto L96; - x1 = XEXP (x0, 0); - goto L1595; - - L96: - if (pnum_clobbers != 0 && 1) - { - ro[1] = x2; - if (TARGET_FPA) - { - *pnum_clobbers = 1; - return 18; - } - } - L97: - ro[1] = x2; - if (TARGET_68881) - return 19; - x1 = XEXP (x0, 0); - goto L1595; - - L101: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[0] = x2; - goto L102; - } - break; - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[0] = x2; - goto L110; - } - } - goto L1262; - - L102: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 1 && 1) - goto L103; - goto L1262; - - L103: - x2 = XEXP (x1, 2); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MINUS && 1) - goto L104; - if (general_operand (x2, SImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 8) - return 24; - } - goto L1262; - - L104: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 7 && 1) - goto L121; - goto L1262; - - L121: - x3 = XEXP (x2, 1); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == AND && 1) - goto L122; - if (general_operand (x3, SImode)) - { - ro[1] = x3; - return 20; - } - goto L1262; - - L122: - x4 = XEXP (x3, 0); - if (general_operand (x4, SImode)) - { - ro[1] = x4; - goto L123; - } - goto L1262; - - L123: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 7 && 1) - return 22; - goto L1262; - - L110: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 1 && 1) - goto L111; - goto L1262; - - L111: - x2 = XEXP (x1, 2); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MINUS && 1) - goto L112; - if (general_operand (x2, SImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) == CONST_INT) - return 25; - } - goto L1262; - - L112: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 31 && 1) - goto L131; - goto L1262; - - L131: - x3 = XEXP (x2, 1); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == AND && 1) - goto L132; - if (general_operand (x3, SImode)) - { - ro[1] = x3; - return 21; - } - goto L1262; - - L132: - x4 = XEXP (x3, 0); - if (general_operand (x4, SImode)) - { - ro[1] = x4; - goto L133; - } - goto L1262; - - L133: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 31 && 1) - return 23; - goto L1262; - - L27: - if (pnum_clobbers != 0 && 1) - { - ro[0] = x1; - if (TARGET_FPA) - { - *pnum_clobbers = 1; - return 6; - } - } - L28: - ro[0] = x1; - if (TARGET_68881) - return 7; - goto L37; - - L41: - if (pnum_clobbers != 0 && 1) - { - ro[0] = x1; - if (TARGET_FPA) - { - *pnum_clobbers = 1; - return 9; - } - } - L42: - ro[0] = x1; - if (TARGET_68881) - return 10; - x1 = XEXP (x0, 0); - goto L1595; - - L1263: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case QImode: - if (memory_operand (x2, QImode)) - { - ro[0] = x2; - goto L1264; - } - break; - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[0] = x2; - goto L1270; - } - } - x1 = XEXP (x0, 0); - goto L1595; - - L1264: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L1265; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1265: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT) - return 246; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1270: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L1271; - } - x1 = XEXP (x0, 0); - goto L1595; - - L1271: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT) - return 247; - } - x1 = XEXP (x0, 0); - goto L1595; - L160: - tem = recog_4 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - goto L1595; - - L1324: - x1 = XEXP (x0, 1); - switch (GET_CODE (x1)) - { - case IF_THEN_ELSE: - goto L1325; - case LABEL_REF: - goto L1505; - } - x1 = XEXP (x0, 0); - goto L1595; - L1325: - tem = recog_5 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L1595; - - L1505: - x2 = XEXP (x1, 0); - ro[0] = x2; - return 278; - - L1596: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) == CALL && 1) - goto L1597; - x1 = XEXP (x0, 0); - goto L1612; - - L1597: - x2 = XEXP (x1, 0); - if (memory_operand (x2, QImode)) - { - ro[1] = x2; - goto L1598; - } - x1 = XEXP (x0, 0); - goto L1612; - - L1598: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - goto L1604; - x1 = XEXP (x0, 0); - goto L1612; - - L1604: - ro[2] = x2; - if (! flag_pic) - return 290; - L1605: - ro[2] = x2; - if (flag_pic) - return 291; - x1 = XEXP (x0, 0); - goto L1612; - - L1613: - x1 = XEXP (x0, 1); - if (address_operand (x1, SImode)) - { - ro[0] = x1; - return 297; - } - goto ret0; - - L1703: - x1 = XEXP (x0, 1); - if (nonimmediate_operand (x1, XFmode)) - { - ro[0] = x1; - if (TARGET_68881) - return 318; - } - if (GET_CODE (x1) == COMPARE && 1) - goto L1707; - goto ret0; - - L1707: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[0] = x2; - goto L1708; - } - goto ret0; - - L1708: - x2 = XEXP (x1, 1); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 320; - } - goto ret0; - - L1751: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SImode && GET_CODE (x1) == FIX && 1) - goto L1752; - if (address_operand (x1, QImode)) - { - ro[1] = x1; - return 298; - } - goto ret0; - - L1752: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 331; - } - goto ret0; - - L1619: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != DFmode) - { - x1 = XEXP (x0, 0); - goto L1718; - } - switch (GET_CODE (x1)) - { - case PLUS: - goto L1620; - case MINUS: - goto L1648; - case MULT: - goto L1662; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1620: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == MULT && 1) - goto L1621; - x1 = XEXP (x0, 0); - goto L1718; - - L1621: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - goto L1622; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1622: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1623; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1623: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 306; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1648: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == MULT && 1) - goto L1649; - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L1635; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1649: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - goto L1650; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1650: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1651; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1651: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 310; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1635: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == MULT && 1) - goto L1636; - x1 = XEXP (x0, 0); - goto L1718; - - L1636: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1637; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1637: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[3] = x3; - if (TARGET_FPA) - return 308; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1662: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case DFmode: - switch (GET_CODE (x2)) - { - case PLUS: - goto L1663; - case MINUS: - goto L1677; - } - } - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L1684; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1663: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - goto L1664; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1664: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1665; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1665: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 312; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1677: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - goto L1678; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1678: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1679; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1679: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 314; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1684: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == MINUS && 1) - goto L1685; - x1 = XEXP (x0, 0); - goto L1718; - - L1685: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[2] = x3; - goto L1686; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1686: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[3] = x3; - if (TARGET_FPA) - return 315; - } - x1 = XEXP (x0, 0); - goto L1718; - - L1719: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == DFmode && GET_CODE (x1) == FLOAT_TRUNCATE && 1) - goto L1720; - goto ret0; - - L1720: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 323; - } - goto ret0; - - L1626: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SFmode) - { - x1 = XEXP (x0, 0); - goto L1722; - } - switch (GET_CODE (x1)) - { - case PLUS: - goto L1627; - case MINUS: - goto L1655; - case MULT: - goto L1669; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1627: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SFmode && GET_CODE (x2) == MULT && 1) - goto L1628; - x1 = XEXP (x0, 0); - goto L1722; - - L1628: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - goto L1629; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1629: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1630; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1630: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 307; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1655: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SFmode && GET_CODE (x2) == MULT && 1) - goto L1656; - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L1642; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1656: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - goto L1657; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1657: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1658; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1658: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 311; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1642: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SFmode && GET_CODE (x2) == MULT && 1) - goto L1643; - x1 = XEXP (x0, 0); - goto L1722; - - L1643: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1644; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1644: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[3] = x3; - if (TARGET_FPA) - return 309; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1669: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SFmode: - switch (GET_CODE (x2)) - { - case PLUS: - goto L1670; - case MINUS: - goto L1691; - } - } - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L1698; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1670: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - goto L1671; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1671: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1672; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1672: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 313; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1691: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - goto L1692; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1692: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1693; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1693: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[3] = x2; - if (TARGET_FPA) - return 316; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1698: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SFmode && GET_CODE (x2) == MINUS && 1) - goto L1699; - x1 = XEXP (x0, 0); - goto L1722; - - L1699: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[2] = x3; - goto L1700; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1700: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[3] = x3; - if (TARGET_FPA) - return 317; - } - x1 = XEXP (x0, 0); - goto L1722; - - L1723: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SFmode && GET_CODE (x1) == FLOAT_TRUNCATE && 1) - goto L1724; - goto ret0; - - L1724: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 324; - } - goto ret0; - - L1711: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != XFmode) - goto ret0; - switch (GET_CODE (x1)) - { - case FLOAT_EXTEND: - goto L1712; - case FLOAT: - goto L1728; - case FIX: - goto L1740; - case PLUS: - goto L1756; - case MINUS: - goto L1761; - case MULT: - goto L1766; - case DIV: - goto L1771; - case NEG: - goto L1776; - case ABS: - goto L1780; - case SQRT: - goto L1784; - } - goto ret0; - - L1712: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 321; - } - L1716: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 322; - } - goto ret0; - - L1728: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 325; - } - L1732: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 326; - } - L1736: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - if (TARGET_68881) - return 327; - } - goto ret0; - - L1740: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 328; - } - goto ret0; - - L1756: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - goto L1757; - } - goto ret0; - - L1757: - x2 = XEXP (x1, 1); - if (nonimmediate_operand (x2, XFmode)) - { - ro[2] = x2; - if (TARGET_68881) - return 333; - } - goto ret0; - - L1761: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - goto L1762; - } - goto ret0; - - L1762: - x2 = XEXP (x1, 1); - if (nonimmediate_operand (x2, XFmode)) - { - ro[2] = x2; - if (TARGET_68881) - return 335; - } - goto ret0; - - L1766: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - goto L1767; - } - goto ret0; - - L1767: - x2 = XEXP (x1, 1); - if (nonimmediate_operand (x2, XFmode)) - { - ro[2] = x2; - if (TARGET_68881) - return 337; - } - goto ret0; - - L1771: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - goto L1772; - } - goto ret0; - - L1772: - x2 = XEXP (x1, 1); - if (nonimmediate_operand (x2, XFmode)) - { - ro[2] = x2; - if (TARGET_68881) - return 339; - } - goto ret0; - - L1776: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 340; - } - goto ret0; - - L1780: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 341; - } - goto ret0; - - L1784: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 342; - } - goto ret0; - - L1743: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == QImode && GET_CODE (x1) == FIX && 1) - goto L1744; - goto ret0; - - L1744: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 329; - } - goto ret0; - - L1747: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == HImode && GET_CODE (x1) == FIX && 1) - goto L1748; - goto ret0; - - L1748: - x2 = XEXP (x1, 0); - if (general_operand (x2, XFmode)) - { - ro[1] = x2; - if (TARGET_68881) - return 330; - } - goto ret0; - ret0: return -1; -} - -int -recog_7 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - switch (GET_MODE (x2)) - { - case SImode: - if (GET_CODE (x2) == PLUS && 1) - goto L1517; - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L1510; - } - } - if (GET_CODE (x2) == IF_THEN_ELSE && 1) - goto L1526; - goto ret0; - - L1517: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == PC && 1) - goto L1518; - goto ret0; - - L1518: - x3 = XEXP (x2, 1); - if (register_operand (x3, HImode)) - { - ro[0] = x3; - goto L1519; - } - goto ret0; - - L1519: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L1520; - goto ret0; - - L1520: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1521; - goto ret0; - - L1521: - x3 = XEXP (x2, 0); - ro[1] = x3; - return 281; - - L1510: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L1511; - goto ret0; - - L1511: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1512; - goto ret0; - - L1512: - x3 = XEXP (x2, 0); - ro[1] = x3; - return 280; - - L1526: - x3 = XEXP (x2, 0); - switch (GET_CODE (x3)) - { - case NE: - goto L1527; - case GE: - goto L1557; - } - goto ret0; - - L1527: - x4 = XEXP (x3, 0); - switch (GET_MODE (x4)) - { - case HImode: - if (general_operand (x4, HImode)) - { - ro[0] = x4; - goto L1528; - } - break; - case SImode: - if (general_operand (x4, SImode)) - { - ro[0] = x4; - goto L1543; - } - } - goto ret0; - - L1528: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1529; - goto ret0; - - L1529: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == LABEL_REF && 1) - goto L1530; - goto ret0; - - L1530: - x4 = XEXP (x3, 0); - ro[1] = x4; - goto L1531; - - L1531: - x3 = XEXP (x2, 2); - if (GET_CODE (x3) == PC && 1) - goto L1532; - goto ret0; - - L1532: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L1533; - goto ret0; - - L1533: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1534; - goto ret0; - - L1534: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == PLUS && 1) - goto L1535; - goto ret0; - - L1535: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L1536; - goto ret0; - - L1536: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1) - return 282; - goto ret0; - - L1543: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1544; - goto ret0; - - L1544: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == LABEL_REF && 1) - goto L1545; - goto ret0; - - L1545: - x4 = XEXP (x3, 0); - ro[1] = x4; - goto L1546; - - L1546: - x3 = XEXP (x2, 2); - if (GET_CODE (x3) == PC && 1) - goto L1547; - goto ret0; - - L1547: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L1548; - goto ret0; - - L1548: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1549; - goto ret0; - - L1549: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == PLUS && 1) - goto L1550; - goto ret0; - - L1550: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L1551; - goto ret0; - - L1551: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1) - return 283; - goto ret0; - - L1557: - x4 = XEXP (x3, 0); - if (GET_CODE (x4) != PLUS) - goto ret0; - switch (GET_MODE (x4)) - { - case HImode: - goto L1558; - case SImode: - goto L1575; - } - goto ret0; - - L1558: - x5 = XEXP (x4, 0); - if (general_operand (x5, HImode)) - { - ro[0] = x5; - goto L1559; - } - goto ret0; - - L1559: - x5 = XEXP (x4, 1); - if (GET_CODE (x5) == CONST_INT && XWINT (x5, 0) == -1 && 1) - goto L1560; - goto ret0; - - L1560: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1561; - goto ret0; - - L1561: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == LABEL_REF && 1) - goto L1562; - goto ret0; - - L1562: - x4 = XEXP (x3, 0); - ro[1] = x4; - goto L1563; - - L1563: - x3 = XEXP (x2, 2); - if (GET_CODE (x3) == PC && 1) - goto L1564; - goto ret0; - - L1564: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L1565; - goto ret0; - - L1565: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1566; - goto ret0; - - L1566: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == PLUS && 1) - goto L1567; - goto ret0; - - L1567: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L1568; - goto ret0; - - L1568: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1) - if (find_reg_note (insn, REG_NONNEG, 0)) - return 284; - goto ret0; - - L1575: - x5 = XEXP (x4, 0); - if (general_operand (x5, SImode)) - { - ro[0] = x5; - goto L1576; - } - goto ret0; - - L1576: - x5 = XEXP (x4, 1); - if (GET_CODE (x5) == CONST_INT && XWINT (x5, 0) == -1 && 1) - goto L1577; - goto ret0; - - L1577: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1578; - goto ret0; - - L1578: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == LABEL_REF && 1) - goto L1579; - goto ret0; - - L1579: - x4 = XEXP (x3, 0); - ro[1] = x4; - goto L1580; - - L1580: - x3 = XEXP (x2, 2); - if (GET_CODE (x3) == PC && 1) - goto L1581; - goto ret0; - - L1581: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L1582; - goto ret0; - - L1582: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L1583; - goto ret0; - - L1583: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == PLUS && 1) - goto L1584; - goto ret0; - - L1584: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L1585; - goto ret0; - - L1585: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1) - if (find_reg_note (insn, REG_NONNEG, 0)) - return 285; - goto ret0; - ret0: return -1; -} - -int -recog_8 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L537; - } - L718: - if (general_operand (x2, SImode)) - { - ro[0] = x2; - goto L719; - } - } - switch (GET_CODE (x2)) - { - case CC0: - goto L18; - case PC: - goto L1516; - } - goto ret0; - - L537: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MULT && 1) - goto L538; - x2 = XEXP (x1, 0); - goto L718; - - L538: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L539; - } - x2 = XEXP (x1, 0); - goto L718; - - L539: - x3 = XEXP (x2, 1); - if (nonimmediate_operand (x3, SImode)) - { - ro[2] = x3; - goto L540; - } - if (GET_CODE (x3) == CONST_INT && 1) - { - ro[2] = x3; - goto L556; - } - x2 = XEXP (x1, 0); - goto L718; - - L540: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L541; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L541: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - goto L542; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L542: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == TRUNCATE && 1) - goto L543; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L543: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != DImode) - { - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - } - switch (GET_CODE (x3)) - { - case LSHIFTRT: - goto L544; - case ASHIFT: - goto L575; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L544: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == DImode && GET_CODE (x4) == MULT && 1) - goto L545; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L545: - x5 = XEXP (x4, 0); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == ZERO_EXTEND && 1) - goto L546; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L546: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[1]) && 1) - goto L547; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L547: - x5 = XEXP (x4, 1); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == ZERO_EXTEND && 1) - goto L548; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L548: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[2]) && 1) - goto L549; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L549: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 32 && 1) - if (TARGET_68020) - return 116; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L575: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == DImode && GET_CODE (x4) == MULT && 1) - goto L576; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L576: - x5 = XEXP (x4, 0); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == SIGN_EXTEND && 1) - goto L577; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L577: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[1]) && 1) - goto L578; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L578: - x5 = XEXP (x4, 1); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == SIGN_EXTEND && 1) - goto L579; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L579: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[2]) && 1) - goto L580; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L580: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 32 && 1) - if (TARGET_68020) - return 119; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L556: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L557; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L557: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - goto L558; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L558: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == TRUNCATE && 1) - goto L559; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L559: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != DImode) - { - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - } - switch (GET_CODE (x3)) - { - case LSHIFTRT: - goto L560; - case ASHIFT: - goto L591; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L560: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == DImode && GET_CODE (x4) == MULT && 1) - goto L561; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L561: - x5 = XEXP (x4, 0); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == ZERO_EXTEND && 1) - goto L562; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L562: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[1]) && 1) - goto L563; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L563: - x5 = XEXP (x4, 1); - if (rtx_equal_p (x5, ro[2]) && 1) - goto L564; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L564: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 32 && 1) - if (TARGET_68020 - && (unsigned) INTVAL (operands[2]) <= 0x7fffffff) - return 117; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L591: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == DImode && GET_CODE (x4) == MULT && 1) - goto L592; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L592: - x5 = XEXP (x4, 0); - if (GET_MODE (x5) == DImode && GET_CODE (x5) == SIGN_EXTEND && 1) - goto L593; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L593: - x6 = XEXP (x5, 0); - if (rtx_equal_p (x6, ro[1]) && 1) - goto L594; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L594: - x5 = XEXP (x4, 1); - if (rtx_equal_p (x5, ro[2]) && 1) - goto L595; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L595: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 32 && 1) - if (TARGET_68020 - /* This test is a noop on 32 bit machines, - but important for a cross-compiler hosted on 64-bit machines. */ - && INTVAL (operands[2]) <= 0x7fffffff - && INTVAL (operands[2]) >= -0x80000000) - return 120; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L718; - - L719: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != SImode) - goto ret0; - switch (GET_CODE (x2)) - { - case DIV: - goto L720; - case UDIV: - goto L731; - } - goto ret0; - - L720: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L721; - } - goto ret0; - - L721: - x3 = XEXP (x2, 1); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - goto L722; - } - goto ret0; - - L722: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L723; - goto ret0; - - L723: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && general_operand (x2, SImode)) - { - ro[3] = x2; - goto L724; - } - goto ret0; - - L724: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MOD && 1) - goto L725; - goto ret0; - - L725: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - goto L726; - goto ret0; - - L726: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[2]) && 1) - if (TARGET_68020) - return 145; - goto ret0; - - L731: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L732; - } - goto ret0; - - L732: - x3 = XEXP (x2, 1); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - goto L733; - } - goto ret0; - - L733: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L734; - goto ret0; - - L734: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && general_operand (x2, SImode)) - { - ro[3] = x2; - goto L735; - } - goto ret0; - - L735: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == UMOD && 1) - goto L736; - goto ret0; - - L736: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - goto L737; - goto ret0; - - L737: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[2]) && 1) - if (TARGET_68020) - return 146; - goto ret0; - - L18: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[0] = x2; - goto L19; - } - L32: - if (general_operand (x2, DFmode)) - { - ro[0] = x2; - goto L33; - } - if (GET_CODE (x2) == COMPARE && 1) - goto L62; - goto ret0; - - L19: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L20; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L32; - - L20: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_FPA) - return 6; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L32; - - L33: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L34; - goto ret0; - - L34: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_FPA) - return 9; - } - goto ret0; - - L62: - x3 = XEXP (x2, 0); - switch (GET_MODE (x3)) - { - case DFmode: - if (general_operand (x3, DFmode)) - { - ro[0] = x3; - goto L63; - } - break; - case SFmode: - if (general_operand (x3, SFmode)) - { - ro[0] = x3; - goto L83; - } - } - goto ret0; - - L63: - x3 = XEXP (x2, 1); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - goto L64; - } - goto ret0; - - L64: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L65; - goto ret0; - - L65: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_FPA) - return 15; - } - goto ret0; - - L83: - x3 = XEXP (x2, 1); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - goto L84; - } - goto ret0; - - L84: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L85; - goto ret0; - - L85: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_FPA) - return 18; - } - goto ret0; - L1516: - return recog_7 (x0, insn, pnum_clobbers); - ret0: return -1; -} - -int -recog (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - int tem; - - L1609: - switch (GET_CODE (x0)) - { - case REG: - if (GET_MODE (x0) == SImode && XINT (x0, 0) == 15 && 1) - if (NEED_PROBE) - return 295; - break; - case SET: - goto L1; - case PARALLEL: - if (XVECLEN (x0, 0) == 2 && 1) - goto L16; - if (XVECLEN (x0, 0) == 3 && 1) - goto L286; - break; - case CALL: - goto L1587; - case UNSPEC_VOLATILE: - if (XINT (x0, 1) == 0 && XVECLEN (x0, 0) == 1 && 1) - goto L1607; - break; - case CONST_INT: - if (XWINT (x0, 0) == 0 && 1) - return 294; - break; - case RETURN: - if (USE_RETURN_INSN) - return 296; - } - goto ret0; - L1: - return recog_6 (x0, insn, pnum_clobbers); - - L16: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == SET && 1) - goto L536; - goto ret0; - L536: - return recog_8 (x0, insn, pnum_clobbers); - - L286: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == SET && 1) - goto L287; - goto ret0; - - L287: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (general_operand (x2, SImode)) - { - ro[0] = x2; - goto L288; - } - break; - case HImode: - if (general_operand (x2, HImode)) - { - ro[0] = x2; - goto L303; - } - break; - case QImode: - if (general_operand (x2, QImode)) - { - ro[0] = x2; - goto L318; - } - } - goto ret0; - - L288: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == FIX && 1) - goto L289; - goto ret0; - - L289: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DFmode && GET_CODE (x3) == FIX && 1) - goto L290; - goto ret0; - - L290: - x4 = XEXP (x3, 0); - if (register_operand (x4, DFmode)) - { - ro[1] = x4; - goto L291; - } - goto ret0; - - L291: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L292; - goto ret0; - - L292: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - goto L293; - } - goto ret0; - - L293: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L294; - goto ret0; - - L294: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68040) - return 70; - } - goto ret0; - - L303: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == FIX && 1) - goto L304; - goto ret0; - - L304: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DFmode && GET_CODE (x3) == FIX && 1) - goto L305; - goto ret0; - - L305: - x4 = XEXP (x3, 0); - if (register_operand (x4, DFmode)) - { - ro[1] = x4; - goto L306; - } - goto ret0; - - L306: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L307; - goto ret0; - - L307: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - goto L308; - } - goto ret0; - - L308: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L309; - goto ret0; - - L309: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68040) - return 71; - } - goto ret0; - - L318: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == QImode && GET_CODE (x2) == FIX && 1) - goto L319; - goto ret0; - - L319: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DFmode && GET_CODE (x3) == FIX && 1) - goto L320; - goto ret0; - - L320: - x4 = XEXP (x3, 0); - if (register_operand (x4, DFmode)) - { - ro[1] = x4; - goto L321; - } - goto ret0; - - L321: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L322; - goto ret0; - - L322: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - goto L323; - } - goto ret0; - - L323: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L324; - goto ret0; - - L324: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_68040) - return 72; - } - goto ret0; - - L1587: - x1 = XEXP (x0, 0); - if (memory_operand (x1, QImode)) - { - ro[0] = x1; - goto L1588; - } - goto ret0; - - L1588: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - goto L1592; - goto ret0; - - L1592: - ro[1] = x1; - if (! flag_pic) - return 287; - L1593: - ro[1] = x1; - if (flag_pic) - return 288; - goto ret0; - - L1607: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == CONST_INT && XWINT (x1, 0) == 0 && 1) - return 293; - goto ret0; - ret0: return -1; -} - -rtx -split_insns (x0, insn) - register rtx x0; - rtx insn; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5, x6; - rtx tem; - - goto ret0; - ret0: return 0; -} - diff --git a/gnu/usr.bin/gcc2/arch/m68k/m68k.h b/gnu/usr.bin/gcc2/arch/m68k/m68k.h deleted file mode 100644 index 5fd24d24e37..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/m68k.h +++ /dev/null @@ -1,1791 +0,0 @@ -/* Definitions of target machine for GNU compiler. Sun 68000/68020 version. - Copyright (C) 1987, 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: m68k.h,v 1.1.1.1 1995/10/18 08:39:20 deraadt Exp $ -*/ - - -/* Note that some other tm.h files include this one and then override - many of the definitions that relate to assembler syntax. */ - - -/* Names to predefine in the preprocessor for this target machine. */ - -/* See sun3.h, sun2.h, isi.h for different CPP_PREDEFINES. */ - -/* Print subsidiary information on the compiler version in use. */ -#ifdef MOTOROLA -#define TARGET_VERSION fprintf (stderr, " (68k, Motorola syntax)"); -#else -#define TARGET_VERSION fprintf (stderr, " (68k, MIT syntax)"); -#endif - -/* Define SUPPORT_SUN_FPA to include support for generating code for - the Sun Floating Point Accelerator, an optional product for Sun 3 - machines. By default, it is not defined. Avoid defining it unless - you need to output code for the Sun3+FPA architecture, as it has the - effect of slowing down the register set operations in hard-reg-set.h - (total number of registers will exceed number of bits in a long, - if defined, causing the set operations to expand to loops). - SUPPORT_SUN_FPA is typically defined in sun3.h. */ - -/* Run-time compilation parameters selecting different hardware subsets. */ - -extern int target_flags; - -/* Macros used in the machine description to test the flags. */ - -/* Compile for a 68020 (not a 68000 or 68010). */ -#define TARGET_68020 (target_flags & 1) - -/* Compile 68881 insns for floating point (not library calls). */ -#define TARGET_68881 (target_flags & 2) - -/* Compile using 68020 bitfield insns. */ -#define TARGET_BITFIELD (target_flags & 4) - -/* Compile using rtd insn calling sequence. - This will not work unless you use prototypes at least - for all functions that can take varying numbers of args. */ -#define TARGET_RTD (target_flags & 8) - -/* Compile passing first two args in regs 0 and 1. - This exists only to test compiler features that will - be needed for RISC chips. It is not usable - and is not intended to be usable on this cpu. */ -#define TARGET_REGPARM (target_flags & 020) - -/* Compile with 16-bit `int'. */ -#define TARGET_SHORT (target_flags & 040) - -/* Compile with special insns for Sun FPA. */ -#ifdef SUPPORT_SUN_FPA -#define TARGET_FPA (target_flags & 0100) -#else -#define TARGET_FPA 0 -#endif - -/* Compile (actually, link) for Sun SKY board. */ -#define TARGET_SKY (target_flags & 0200) - -/* Optimize for 68040, but still allow execution on 68020 - (-m68020-40 or -m68040). - The 68040 will execute all 68030 and 68881/2 instructions, but some - of them must be emulated in software by the OS. When TARGET_68040 is - turned on, these instructions won't be used. This code will still - run on a 68030 and 68881/2. */ -#define TARGET_68040 (target_flags & 01400) - -/* Use the 68040-only fp instructions (-m68040). */ -#define TARGET_68040_ONLY (target_flags & 01000) - -/* Macro to define tables used to set the flags. - This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } - where VALUE is the bits to set or minus the bits to clear. - An empty string NAME is used to identify the default VALUE. */ - -#define TARGET_SWITCHES \ - { { "68020", -01400}, \ - { "c68020", -01400}, \ - { "68020", 5}, \ - { "c68020", 5}, \ - { "68881", 2}, \ - { "bitfield", 4}, \ - { "68000", -01405}, \ - { "c68000", -01405}, \ - { "soft-float", -01102}, \ - { "nobitfield", -4}, \ - { "rtd", 8}, \ - { "nortd", -8}, \ - { "short", 040}, \ - { "noshort", -040}, \ - { "fpa", 0100}, \ - { "nofpa", -0100}, \ - { "sky", 0200}, \ - { "nosky", -0200}, \ - { "68020-40", 0407}, \ - { "68030", -01400}, \ - { "68030", 5}, \ - { "68040", 01007}, \ - { "", TARGET_DEFAULT}} -/* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */ - -/* For PIC, function CSE is undesirable since it causes all function - calls to go via the GOT rather than the PLT. */ -#ifdef SUPPORT_SUN_FPA -/* Blow away 68881 flag silently on TARGET_FPA (since we can't clear - any bits in TARGET_SWITCHES above) */ -#define OVERRIDE_OPTIONS \ -{ \ - if (TARGET_FPA) target_flags &= ~2; \ - if (! TARGET_68020 && flag_pic == 2) \ - error("-fPIC is not currently supported on the 68000 or 68010\n"); \ - if (flag_pic) \ - flag_no_function_cse = 1; \ -} -#else -#define OVERRIDE_OPTIONS \ -{ \ - if (! TARGET_68020 && flag_pic == 2) \ - error("-fPIC is not currently supported on the 68000 or 68010\n"); \ - if (flag_pic) \ - flag_no_function_cse = 1; \ -} -#endif /* defined SUPPORT_SUN_FPA */ - -/* target machine storage layout */ - -/* Define for XFmode extended real floating point support. - This will automatically cause REAL_ARITHMETIC to be defined. */ -#define LONG_DOUBLE_TYPE_SIZE 96 - -/* Define if you don't want extended real, but do want to use the - software floating point emulator for REAL_ARITHMETIC and - decimal <-> binary conversion. */ -/* #define REAL_ARITHMETIC */ - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. - This is true for 68020 insns such as bfins and bfexts. - We make it true always by avoiding using the single-bit insns - except in special cases with constant bit numbers. */ -#define BITS_BIG_ENDIAN 1 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is true on the 68000. */ -#define BYTES_BIG_ENDIAN 1 - -/* Define this if most significant word of a multiword number is the lowest - numbered. */ -/* For 68000 we can decide arbitrarily - since there are no machine instructions for them. - So let's be consistent. */ -#define WORDS_BIG_ENDIAN 1 - -/* number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 68000, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD 32 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD 4 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE 32 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY (TARGET_SHORT ? 16 : 32) - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY 16 - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 16 - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 16 - -/* No data type wants to be aligned rounder than this. */ -#define BIGGEST_ALIGNMENT 16 - -/* Set this nonzero if move instructions will actually fail to work - when given unaligned data. */ -#define STRICT_ALIGNMENT 1 - -#define SELECT_RTX_SECTION(MODE, X) \ -{ \ - if (!flag_pic) \ - readonly_data_section(); \ - else if (LEGITIMATE_PIC_OPERAND_P (X)) \ - readonly_data_section(); \ - else \ - data_section(); \ -} - -/* Define number of bits in most basic integer type. - (If undefined, default is BITS_PER_WORD). */ - -#define INT_TYPE_SIZE (TARGET_SHORT ? 16 : 32) - -/* Define these to avoid dependence on meaning of `int'. - Note that WCHAR_TYPE_SIZE is used in cexp.y, - where TARGET_SHORT is not available. */ - -#define WCHAR_TYPE "long int" -#define WCHAR_TYPE_SIZE 32 - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - For the 68000, we give the data registers numbers 0-7, - the address registers numbers 010-017, - and the 68881 floating point registers numbers 020-027. */ -#ifndef SUPPORT_SUN_FPA -#define FIRST_PSEUDO_REGISTER 24 -#else -#define FIRST_PSEUDO_REGISTER 56 -#endif - -/* This defines the register which is used to hold the offset table for PIC. */ -#define PIC_OFFSET_TABLE_REGNUM 13 - -#ifndef SUPPORT_SUN_FPA - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - On the 68000, only the stack pointer is such. */ - -#define FIXED_REGISTERS \ - {/* Data registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - \ - /* Address registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 1, \ - \ - /* Floating point registers \ - (if available). */ \ - 0, 0, 0, 0, 0, 0, 0, 0 } - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ - {1, 1, 0, 0, 0, 0, 0, 0, \ - 1, 1, 0, 0, 0, 0, 0, 1, \ - 1, 1, 0, 0, 0, 0, 0, 0 } - -#else /* SUPPORT_SUN_FPA */ - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - On the 68000, only the stack pointer is such. */ - -/* fpa0 is also reserved so that it can be used to move shit back and - forth between high fpa regs and everything else. */ - -#define FIXED_REGISTERS \ - {/* Data registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - \ - /* Address registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 1, \ - \ - /* Floating point registers \ - (if available). */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - \ - /* Sun3 FPA registers. */ \ - 1, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0 } - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ - {1, 1, 0, 0, 0, 0, 0, 0, \ - 1, 1, 0, 0, 0, 0, 0, 1, \ - 1, 1, 0, 0, 0, 0, 0, 0, \ - /* FPA registers. */ \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0 } - -#endif /* defined SUPPORT_SUN_FPA */ - - -/* Make sure everything's fine if we *don't* have a given processor. - This assumes that putting a register in fixed_regs will keep the - compiler's mitts completely off it. We don't bother to zero it out - of register classes. If neither TARGET_FPA or TARGET_68881 is set, - the compiler won't touch since no instructions that use these - registers will be valid. - - Reserve PIC_OFFSET_TABLE_REGNUM (a5) for doing PIC relocation if - position independent code is being generated by making it a - fixed register */ - -#ifndef SUPPORT_SUN_FPA - -#define CONDITIONAL_REGISTER_USAGE \ -{ \ - if (flag_pic) \ - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ -} - -#else /* defined SUPPORT_SUN_FPA */ - -#define CONDITIONAL_REGISTER_USAGE \ -{ \ - int i; \ - HARD_REG_SET x; \ - if (!TARGET_FPA) \ - { \ - COPY_HARD_REG_SET (x, reg_class_contents[(int)FPA_REGS]); \ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \ - if (TEST_HARD_REG_BIT (x, i)) \ - fixed_regs[i] = call_used_regs[i] = 1; \ - } \ - if (TARGET_FPA) \ - { \ - COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); \ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \ - if (TEST_HARD_REG_BIT (x, i)) \ - fixed_regs[i] = call_used_regs[i] = 1; \ - } \ - if (flag_pic) \ - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ -} - -#endif /* defined SUPPORT_SUN_FPA */ - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - - On the 68000, ordinary registers hold 32 bits worth; - for the 68881 registers, a single register is always enough for - anything that can be stored in them at all. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((REGNO) >= 16 ? GET_MODE_NUNITS (MODE) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -#ifndef SUPPORT_SUN_FPA - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the 68000, the cpu registers can hold any mode but the 68881 registers - can hold only SFmode or DFmode. The 68881 registers can't hold anything - if 68881 use is disabled. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - (((REGNO) < 16) \ - || ((REGNO) < 24 \ - && TARGET_68881 \ - && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT))) - -#else /* defined SUPPORT_SUN_FPA */ - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the 68000, the cpu registers can hold any mode but the 68881 registers - can hold only SFmode or DFmode. And the 68881 registers can't hold anything - if 68881 use is disabled. However, the Sun FPA register can - (apparently) hold whatever you feel like putting in them. - If using the fpa, don't put a double in d7/a0. */ - -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ -(((REGNO) < 16 \ - && !(TARGET_FPA \ - && GET_MODE_CLASS ((MODE)) != MODE_INT \ - && GET_MODE_UNIT_SIZE ((MODE)) > 4 \ - && (REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8 \ - && (REGNO) % (GET_MODE_UNIT_SIZE ((MODE)) / 4) != 0)) \ - || ((REGNO) < 24 \ - ? TARGET_68881 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ - : ((REGNO) < 56 ? TARGET_FPA : 0))) - -#endif /* defined SUPPORT_SUN_FPA */ - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (! TARGET_68881 \ - || ((GET_MODE_CLASS (MODE1) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \ - == (GET_MODE_CLASS (MODE2) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* m68000 pc isn't overloaded on a register. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 15 - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 14 - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ -#define FRAME_POINTER_REQUIRED 0 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 14 - -/* Register in which static-chain is passed to a function. */ -#define STATIC_CHAIN_REGNUM 8 - -/* Register in which address to store a structure value - is passed to a function. */ -#define STRUCT_VALUE_REGNUM 9 - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -/* The 68000 has three kinds of registers, so eight classes would be - a complete set. One of them is not needed. */ - -#ifndef SUPPORT_SUN_FPA - -enum reg_class { - NO_REGS, DATA_REGS, - ADDR_REGS, FP_REGS, - GENERAL_REGS, DATA_OR_FP_REGS, - ADDR_OR_FP_REGS, ALL_REGS, - LIM_REG_CLASSES }; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ - { "NO_REGS", "DATA_REGS", \ - "ADDR_REGS", "FP_REGS", \ - "GENERAL_REGS", "DATA_OR_FP_REGS", \ - "ADDR_OR_FP_REGS", "ALL_REGS" } - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS \ -{ \ - 0x00000000, /* NO_REGS */ \ - 0x000000ff, /* DATA_REGS */ \ - 0x0000ff00, /* ADDR_REGS */ \ - 0x00ff0000, /* FP_REGS */ \ - 0x0000ffff, /* GENERAL_REGS */ \ - 0x00ff00ff, /* DATA_OR_FP_REGS */ \ - 0x00ffff00, /* ADDR_OR_FP_REGS */ \ - 0x00ffffff, /* ALL_REGS */ \ -} - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) (((REGNO)>>3)+1) - -#else /* defined SUPPORT_SUN_FPA */ - -/* - * Notes on final choices: - * - * 1) Didn't feel any need to union-ize LOW_FPA_REGS with anything - * else. - * 2) Removed all unions that involve address registers with - * floating point registers (left in unions of address and data with - * floating point). - * 3) Defined GENERAL_REGS as ADDR_OR_DATA_REGS. - * 4) Defined ALL_REGS as FPA_OR_FP_OR_GENERAL_REGS. - * 4) Left in everything else. - */ -enum reg_class { NO_REGS, LO_FPA_REGS, FPA_REGS, FP_REGS, - FP_OR_FPA_REGS, DATA_REGS, DATA_OR_FPA_REGS, DATA_OR_FP_REGS, - DATA_OR_FP_OR_FPA_REGS, ADDR_REGS, GENERAL_REGS, - GENERAL_OR_FPA_REGS, GENERAL_OR_FP_REGS, ALL_REGS, - LIM_REG_CLASSES }; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ - { "NO_REGS", "LO_FPA_REGS", "FPA_REGS", "FP_REGS", \ - "FP_OR_FPA_REGS", "DATA_REGS", "DATA_OR_FPA_REGS", "DATA_OR_FP_REGS", \ - "DATA_OR_FP_OR_FPA_REGS", "ADDR_REGS", "GENERAL_REGS", \ - "GENERAL_OR_FPA_REGS", "GENERAL_OR_FP_REGS", "ALL_REGS" } - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS \ -{ \ - {0, 0}, /* NO_REGS */ \ - {0xff000000, 0x000000ff}, /* LO_FPA_REGS */ \ - {0xff000000, 0x00ffffff}, /* FPA_REGS */ \ - {0x00ff0000, 0x00000000}, /* FP_REGS */ \ - {0xffff0000, 0x00ffffff}, /* FP_OR_FPA_REGS */ \ - {0x000000ff, 0x00000000}, /* DATA_REGS */ \ - {0xff0000ff, 0x00ffffff}, /* DATA_OR_FPA_REGS */ \ - {0x00ff00ff, 0x00000000}, /* DATA_OR_FP_REGS */ \ - {0xffff00ff, 0x00ffffff}, /* DATA_OR_FP_OR_FPA_REGS */\ - {0x0000ff00, 0x00000000}, /* ADDR_REGS */ \ - {0x0000ffff, 0x00000000}, /* GENERAL_REGS */ \ - {0xff00ffff, 0x00ffffff}, /* GENERAL_OR_FPA_REGS */\ - {0x00ffffff, 0x00000000}, /* GENERAL_OR_FP_REGS */\ - {0xffffffff, 0x00ffffff}, /* ALL_REGS */ \ -} - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -extern enum reg_class regno_reg_class[]; -#define REGNO_REG_CLASS(REGNO) (regno_reg_class[(REGNO)>>3]) - -#endif /* SUPPORT_SUN_FPA */ - -/* The class value for index registers, and the one for base regs. */ - -#define INDEX_REG_CLASS GENERAL_REGS -#define BASE_REG_CLASS ADDR_REGS - -/* Get reg_class from a letter such as appears in the machine description. - We do a trick here to modify the effective constraints on the - machine description; we zorch the constraint letters that aren't - appropriate for a specific target. This allows us to guarantee - that a specific kind of register will not be used for a given target - without fiddling with the register classes above. */ - -#ifndef SUPPORT_SUN_FPA - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'a' ? ADDR_REGS : \ - ((C) == 'd' ? DATA_REGS : \ - ((C) == 'f' ? (TARGET_68881 ? FP_REGS : \ - NO_REGS) : \ - NO_REGS))) - -#else /* defined SUPPORT_SUN_FPA */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'a' ? ADDR_REGS : \ - ((C) == 'd' ? DATA_REGS : \ - ((C) == 'f' ? (TARGET_68881 ? FP_REGS : \ - NO_REGS) : \ - ((C) == 'x' ? (TARGET_FPA ? FPA_REGS : \ - NO_REGS) : \ - ((C) == 'y' ? (TARGET_FPA ? LO_FPA_REGS : \ - NO_REGS) : \ - NO_REGS))))) - -#endif /* defined SUPPORT_SUN_FPA */ - -/* The letters I, J, K, L and M in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - For the 68000, `I' is used for the range 1 to 8 - allowed as immediate shift counts and in addq. - `J' is used for the range of signed numbers that fit in 16 bits. - `K' is for numbers that moveq can't handle. - `L' is for range -8 to -1, range of values that can be added with subq. */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (VALUE) > 0 && (VALUE) <= 8 : \ - (C) == 'J' ? (VALUE) >= -0x8000 && (VALUE) <= 0x7FFF : \ - (C) == 'K' ? (VALUE) < -0x80 || (VALUE) >= 0x80 : \ - (C) == 'L' ? (VALUE) < 0 && (VALUE) >= -8 : 0) - -/* - * A small bit of explanation: - * "G" defines all of the floating constants that are *NOT* 68881 - * constants. this is so 68881 constants get reloaded and the - * fpmovecr is used. "H" defines *only* the class of constants that - * the fpa can use, because these can be gotten at in any fpa - * instruction and there is no need to force reloads. - */ -#ifndef SUPPORT_SUN_FPA -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? ! (TARGET_68881 && standard_68881_constant_p (VALUE)) : 0 ) -#else /* defined SUPPORT_SUN_FPA */ -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? ! (TARGET_68881 && standard_68881_constant_p (VALUE)) : \ - (C) == 'H' ? (TARGET_FPA && standard_sun_fpa_constant_p (VALUE)) : 0) -#endif /* defined SUPPORT_SUN_FPA */ - -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. - On the 68000 series, use a data reg if possible when the - value is a constant in the range where moveq could be used - and we ensure that QImodes are reloaded into data regs. - Also, if a floating constant needs reloading, put it in memory - if possible. */ - -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((GET_CODE (X) == CONST_INT \ - && (unsigned) (INTVAL (X) + 0x80) < 0x100 \ - && (CLASS) != ADDR_REGS) \ - ? DATA_REGS \ - : (GET_MODE (X) == QImode && (CLASS) != ADDR_REGS) \ - ? DATA_REGS \ - : (GET_CODE (X) == CONST_DOUBLE \ - && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ - ? NO_REGS \ - : (CLASS)) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On the 68000, this is the size of MODE in words, - except in the FP regs, where a single reg is always enough. */ -#ifndef SUPPORT_SUN_FPA - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((CLASS) == FP_REGS ? 1 \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* Moves between fp regs and other regs are two insns. */ -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - (((CLASS1) == FP_REGS && (CLASS2) != FP_REGS) \ - || ((CLASS2) == FP_REGS && (CLASS1) != FP_REGS) \ - ? 4 : 2) - -#else /* defined SUPPORT_SUN_FPA */ - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((CLASS) == FP_REGS || (CLASS) == FPA_REGS || (CLASS) == LO_FPA_REGS ? 1 \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - -/* Moves between fp regs and other regs are two insns. */ -/* Likewise for high fpa regs and other regs. */ -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - ((((CLASS1) == FP_REGS && (CLASS2) != FP_REGS) \ - || ((CLASS2) == FP_REGS && (CLASS1) != FP_REGS) \ - || ((CLASS1) == FPA_REGS && (CLASS2) != FPA_REGS) \ - || ((CLASS2) == FPA_REGS && (CLASS1) != FPA_REGS)) \ - ? 4 : 2) - -#endif /* define SUPPORT_SUN_FPA */ - -/* Stack layout; function entry, exit and calling. */ - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Nonzero if we need to generate stack-probe insns. - On most systems they are not needed. - When they are needed, define this as the stack offset to probe at. */ -#define NEED_PROBE 0 - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. */ -#define FRAME_GROWS_DOWNWARD - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ -#define STARTING_FRAME_OFFSET 0 - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On the 68000, sp@- in a byte insn really pushes a word. */ -#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1) - -/* Offset of first parameter from the argument pointer register value. */ -#define FIRST_PARM_OFFSET(FNDECL) 8 - -/* Value is the number of byte of arguments automatically - popped when returning from a subroutine call. - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the 68000, the RTS insn cannot pop anything. - On the 68010, the RTD insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RTD can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RTD is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. */ - -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) \ - ((TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) \ - ? (SIZE) : 0) - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. */ - -/* On the 68000 the return value is in D0 regardless. */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), 0) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -/* On the 68000 the return value is in D0 regardless. */ - -#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, 0) - -/* 1 if N is a possible register number for a function value. - On the 68000, d0 is the only register thus used. */ - -#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) - -/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for - more than one register. */ - -#define NEEDS_UNTYPED_CALL 0 - -/* Define this if PCC uses the nonreentrant convention for returning - structure and union values. */ - -#define PCC_STATIC_STRUCT_RETURN - -/* 1 if N is a possible register number for function argument passing. - On the 68000, no registers are used in this way. */ - -#define FUNCTION_ARG_REGNO_P(N) 0 - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. - - On the m68k, this is a single integer, which is a number of bytes - of arguments scanned so far. */ - -#define CUMULATIVE_ARGS int - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. - - On the m68k, the offset starts at 0. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ - ((CUM) = 0) - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM) += ((MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + 3) & ~3 \ - : (int_size_in_bytes (TYPE) + 3) & ~3)) - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -/* On the 68000 all args are pushed, except if -mregparm is specified - then the first two words of arguments are passed in d0, d1. - *NOTE* -mregparm does not work. - It exists only to test register calling conventions. */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8) ? gen_rtx (REG, (MODE), (CUM) / 4) : 0) - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8 \ - && 8 < ((CUM) + ((MODE) == BLKmode \ - ? int_size_in_bytes (TYPE) \ - : GET_MODE_SIZE (MODE)))) \ - ? 2 - (CUM) / 4 : 0) - -/* Generate the assembly code for function entry. */ -#define FUNCTION_PROLOGUE(FILE, SIZE) output_function_prologue(FILE, SIZE) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - asm_fprintf (FILE, "\tlea %LLP%d,%Ra0\n\tjsr mcount\n", (LABELNO)) - -/* Output assembler code to FILE to initialize this source file's - basic block profiling info, if that has not already been done. */ - -#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \ - asm_fprintf (FILE, "\ttstl %LLPBX0\n\tbne %LLPI%d\n\tpea %LLPBX0\n\tjsr %U__bb_init_func\n\taddql %I4,%Rsp\n%LLPI%d:\n", \ - LABELNO, LABELNO); - -/* Output assembler code to FILE to increment the entry-count for - the BLOCKNO'th basic block in this source file. */ - -#define BLOCK_PROFILER(FILE, BLOCKNO) \ - asm_fprintf (FILE, "\taddql %I1,%LLPBX2+%d\n", 4 * BLOCKNO) - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. The value is tested only in - functions that have frame pointers. - No definition is equivalent to always zero. */ - -#define EXIT_IGNORE_STACK 1 - -/* Generate the assembly code for function exit. */ -#define FUNCTION_EPILOGUE(FILE, SIZE) output_function_epilogue (FILE, SIZE) - -/* This is a hook for other tm files to change. */ -/* #define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) */ - -/* Determine if the epilogue should be output as RTL. - You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ -#define USE_RETURN_INSN use_return_insn () - -/* Store in the variable DEPTH the initial difference between the - frame pointer reg contents and the stack pointer reg contents, - as of the start of the function body. This depends on the layout - of the fixed parts of the stack frame and on how registers are saved. - - On the 68k, if we have a frame, we must add one word to its length - to allow for the place that a6 is stored when we do have a frame pointer. - Otherwise, we would need to compute the offset from the frame pointer - of a local variable as a function of frame_pointer_needed, which - is hard. */ - -#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ -{ int regno; \ - int offset = -4; \ - for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++) \ - if (regs_ever_live[regno] && ! call_used_regs[regno]) \ - offset += 12; \ - for (regno = 0; regno < 16; regno++) \ - if (regs_ever_live[regno] && ! call_used_regs[regno]) \ - offset += 4; \ - (DEPTH) = (offset + ((get_frame_size () + 3) & -4) \ - + (get_frame_size () == 0 ? 0 : 4)); \ -} - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On the 68k, the trampoline looks like this: - mov @#.,a0 - jsr @#___trampoline - jsr @#___trampoline - .long STATIC - .long FUNCTION -The reason for having three jsr insns is so that an entire line -of the instruction cache is filled in a predictable way -that will always be the same. - -We always use the assembler label ___trampoline -regardless of whether the system adds underscores. */ - -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x207c)); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4eb9)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "*___trampoline"));\ - ASM_OUTPUT_SHORT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x4eb9)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (SYMBOL_REF, SImode, "*___trampoline"));\ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 26 - -/* Alignment required for a trampoline. 16 is used to find the - beginning of a line in the instruction cache. */ - -#define TRAMPOLINE_ALIGN 16 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 2)), TRAMP); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 18)), CXT); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 22)), FNADDR); \ -} - -/* This is the library routine that is used - to transfer control from the trampoline - to the actual nested function. */ - -/* A colon is used with no explicit operands - to cause the template string to be scanned for %-constructs. */ -/* The function name __transfer_from_trampoline is not actually used. - The function definition just permits use of "asm with operands" - (though the operand list is empty). */ -#define TRANSFER_FROM_TRAMPOLINE \ -void \ -__transfer_from_trampoline () \ -{ \ - register char *a0 asm ("%a0"); \ - asm (GLOBAL_ASM_OP " ___trampoline"); \ - asm ("___trampoline:"); \ - asm volatile ("move%.l %0,%@" : : "m" (a0[22])); \ - asm volatile ("move%.l %1,%0" : "=a" (a0) : "m" (a0[18])); \ - asm ("rts":); \ -} - -/* Addressing modes, and classification of registers for them. */ - -#define HAVE_POST_INCREMENT -/* #define HAVE_POST_DECREMENT */ - -#define HAVE_PRE_DECREMENT -/* #define HAVE_PRE_INCREMENT */ - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < 16 || (unsigned) reg_renumber[REGNO] < 16) -#define REGNO_OK_FOR_BASE_P(REGNO) \ -(((REGNO) ^ 010) < 8 || (unsigned) (reg_renumber[REGNO] ^ 010) < 8) -#define REGNO_OK_FOR_DATA_P(REGNO) \ -((REGNO) < 8 || (unsigned) reg_renumber[REGNO] < 8) -#define REGNO_OK_FOR_FP_P(REGNO) \ -(((REGNO) ^ 020) < 8 || (unsigned) (reg_renumber[REGNO] ^ 020) < 8) -#ifdef SUPPORT_SUN_FPA -#define REGNO_OK_FOR_FPA_P(REGNO) \ -(((REGNO) >= 24 && (REGNO) < 56) || (reg_renumber[REGNO] >= 24 && reg_renumber[REGNO] < 56)) -#endif - -/* Now macros that check whether X is a register and also, - strictly, whether it is in a specified class. - - These macros are specific to the 68000, and may be used only - in code for printing assembler insns and in conditions for - define_optimization. */ - -/* 1 if X is a data register. */ - -#define DATA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_DATA_P (REGNO (X))) - -/* 1 if X is an fp register. */ - -#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X))) - -/* 1 if X is an address register */ - -#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X))) - -#ifdef SUPPORT_SUN_FPA -/* 1 if X is a register in the Sun FPA. */ -#define FPA_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FPA_P (REGNO (X))) -#else -/* Answer must be no if we don't have an FPA. */ -#define FPA_REG_P(X) 0 -#endif - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_CONSTANT_P(X) 1 - -/* Nonzero if the constant value X is a legitimate general operand - when generating PIC code. It is given that flag_pic is on and - that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_PIC_OPERAND_P(X) \ - (! symbolic_operand (X, VOIDmode) \ - || ((GET_CODE(X) == SYMBOL_REF) && SYMBOL_REF_FLAG(X))) - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - After reload, it makes no difference, since pseudo regs have - been eliminated by then. */ - -#ifndef REG_OK_STRICT - -/* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg. */ -#define REG_OK_FOR_INDEX_P(X) ((REGNO (X) ^ 020) >= 8) -/* Nonzero if X is a hard reg that can be used as a base reg - or if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) ((REGNO (X) & ~027) != 0) - -#else - -/* Nonzero if X is a hard reg that can be used as an index. */ -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -/* Nonzero if X is a hard reg that can be used as a base reg. */ -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) - -#endif - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - When generating PIC, an address involving a SYMBOL_REF is legitimate - if and only if it is the sum of pic_offset_table_rtx and the SYMBOL_REF. - We use LEGITIMATE_PIC_OPERAND_P to throw out the illegitimate addresses, - and we explicitly check for the sum of pic_offset_table_rtx and a SYMBOL_REF. - - Likewise for a LABEL_REF when generating PIC. - - The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ - -#define INDIRECTABLE_1_ADDRESS_P(X) \ - ((CONSTANT_ADDRESS_P (X) && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (X))) \ - || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ - || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC) \ - && REG_P (XEXP (X, 0)) \ - && REG_OK_FOR_BASE_P (XEXP (X, 0))) \ - || (GET_CODE (X) == PLUS \ - && REG_P (XEXP (X, 0)) && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && GET_CODE (XEXP (X, 1)) == CONST_INT \ - && ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000) \ - || (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \ - && flag_pic && GET_CODE (XEXP (X, 1)) == SYMBOL_REF) \ - || (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \ - && flag_pic && GET_CODE (XEXP (X, 1)) == LABEL_REF)) \ - -#if 0 -/* This should replace the last two (non-pic) lines - except that Sun's assembler does not seem to handle such operands. */ - && (TARGET_68020 ? CONSTANT_ADDRESS_P (XEXP (X, 1)) \ - : (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && ((unsigned) INTVAL (XEXP (X, 1)) + 0x8000) < 0x10000)))) -#endif - - -#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \ -{ if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; } - -/* Only labels on dispatch tables are valid for indexing from. */ -#define GO_IF_INDEXABLE_BASE(X, ADDR) \ -{ rtx temp; \ - if (GET_CODE (X) == LABEL_REF \ - && (temp = next_nonnote_insn (XEXP (X, 0))) != 0 \ - && GET_CODE (temp) == JUMP_INSN \ - && (GET_CODE (PATTERN (temp)) == ADDR_VEC \ - || GET_CODE (PATTERN (temp)) == ADDR_DIFF_VEC)) \ - goto ADDR; \ - if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR; } - -#define GO_IF_INDEXING(X, ADDR) \ -{ if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 0))) \ - { GO_IF_INDEXABLE_BASE (XEXP (X, 1), ADDR); } \ - if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 1))) \ - { GO_IF_INDEXABLE_BASE (XEXP (X, 0), ADDR); } } - -#define GO_IF_INDEXED_ADDRESS(X, ADDR) \ -{ GO_IF_INDEXING (X, ADDR); \ - if (GET_CODE (X) == PLUS) \ - { if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (unsigned) INTVAL (XEXP (X, 1)) + 0x80 < 0x100) \ - { rtx go_temp = XEXP (X, 0); GO_IF_INDEXING (go_temp, ADDR); } \ - if (GET_CODE (XEXP (X, 0)) == CONST_INT \ - && (unsigned) INTVAL (XEXP (X, 0)) + 0x80 < 0x100) \ - { rtx go_temp = XEXP (X, 1); GO_IF_INDEXING (go_temp, ADDR); } } } - -#define LEGITIMATE_INDEX_REG_P(X) \ - ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \ - || (GET_CODE (X) == SIGN_EXTEND \ - && GET_CODE (XEXP (X, 0)) == REG \ - && GET_MODE (XEXP (X, 0)) == HImode \ - && REG_OK_FOR_INDEX_P (XEXP (X, 0)))) - -#define LEGITIMATE_INDEX_P(X) \ - (LEGITIMATE_INDEX_REG_P (X) \ - || (TARGET_68020 && GET_CODE (X) == MULT \ - && LEGITIMATE_INDEX_REG_P (XEXP (X, 0)) \ - && GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (INTVAL (XEXP (X, 1)) == 2 \ - || INTVAL (XEXP (X, 1)) == 4 \ - || INTVAL (XEXP (X, 1)) == 8))) - -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ GO_IF_NONINDEXED_ADDRESS (X, ADDR); \ - GO_IF_INDEXED_ADDRESS (X, ADDR); } - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. - - For the 68000, we handle X+REG by loading X into a register R and - using R+REG. R will go in an address reg and indexing will be used. - However, if REG is a broken-out memory address or multiplication, - nothing needs to be done because REG can certainly go in an address reg. */ - -#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; } -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ -{ register int ch = (X) != (OLDX); \ - if (GET_CODE (X) == PLUS) \ - { int copied = 0; \ - if (GET_CODE (XEXP (X, 0)) == MULT) \ - { COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);} \ - if (GET_CODE (XEXP (X, 1)) == MULT) \ - { COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);} \ - if (ch && GET_CODE (XEXP (X, 1)) == REG \ - && GET_CODE (XEXP (X, 0)) == REG) \ - goto WIN; \ - if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); } \ - if (GET_CODE (XEXP (X, 0)) == REG \ - || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \ - && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode)) \ - { register rtx temp = gen_reg_rtx (Pmode); \ - register rtx val = force_operand (XEXP (X, 1), 0); \ - emit_move_insn (temp, val); \ - COPY_ONCE (X); \ - XEXP (X, 1) = temp; \ - goto WIN; } \ - else if (GET_CODE (XEXP (X, 1)) == REG \ - || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND \ - && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG \ - && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode)) \ - { register rtx temp = gen_reg_rtx (Pmode); \ - register rtx val = force_operand (XEXP (X, 0), 0); \ - emit_move_insn (temp, val); \ - COPY_ONCE (X); \ - XEXP (X, 0) = temp; \ - goto WIN; }}} - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - On the 68000, only predecrement and postincrement address depend thus - (the amount of decrement or increment being the length of the operand). */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ - if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC) goto LABEL - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE HImode - -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -#define CASE_VECTOR_PC_RELATIVE - -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 1 - -/* Don't cse the address of the function being compiled. */ -#define NO_RECURSIVE_FUNCTION_CSE - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX 4 - -/* Define this if zero-extension is slow (more than one real instruction). */ -#define SLOW_ZERO_EXTEND - -/* Nonzero if access to memory by bytes is slow and undesirable. */ -#define SLOW_BYTE_ACCESS 0 - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE -1 - -/* When a prototype says `char' or `short', really pass an `int'. */ -#define PROMOTE_PROTOTYPES - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ -#define Pmode SImode - -/* A function address in a call instruction - is a byte address (for indexing purposes) - so give the MEM rtx a byte's mode. */ -#define FUNCTION_MODE QImode - -/* Compute the cost of computing a constant rtl expression RTX - whose rtx-code is CODE. The body of this macro is a portion - of a switch statement. If the code is computed here, - return it with a return statement. Otherwise, break from the switch. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - /* Constant zero is super cheap due to clr instruction. */ \ - if (RTX == const0_rtx) return 0; \ - /* Constants between -128 and 127 are cheap due to moveq */ \ - if (INTVAL (RTX) >= -128 && INTVAL (RTX) <= 127) return 1; \ - /* Constants between -136 and 254 are easily generated */ \ - /* by intelligent uses of moveq, add[q], and subq */ \ - if ((OUTER_CODE) == SET && INTVAL (RTX) >= -136 \ - && INTVAL (RTX) <= 254) return 2; \ - case CONST: \ - case LABEL_REF: \ - case SYMBOL_REF: \ - return 3; \ - case CONST_DOUBLE: \ - return 5; - -/* Compute the cost of various arithmetic operations. - These are vaguely right for a 68020. */ -/* The costs for long multiply have been adjusted to - work properly in synth_mult on the 68020, - relative to an average of the time for add and the time for shift, - taking away a little more because sometimes move insns are needed. */ -#define MULL_COST (TARGET_68040 ? 5 : 13) -#define MULW_COST (TARGET_68040 ? 3 : 8) - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case PLUS: \ - /* An lea costs about three times as much as a simple add. */ \ - if (GET_MODE (X) == SImode \ - && GET_CODE (XEXP (X, 0)) == REG \ - && GET_CODE (XEXP (X, 1)) == MULT \ - && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG \ - && GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT \ - && (INTVAL (XEXP (XEXP (X, 1), 1)) == 2 \ - || INTVAL (XEXP (XEXP (X, 1), 1)) == 4 \ - || INTVAL (XEXP (XEXP (X, 1), 1)) == 8)) \ - return COSTS_N_INSNS (3); /* lea an@(dx:l:i),am */ \ - break; \ - case ASHIFT: \ - case ASHIFTRT: \ - case LSHIFT: \ - case LSHIFTRT: \ - /* A shift by a big integer takes an extra instruction. */ \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (INTVAL (XEXP (X, 1)) == 16)) \ - return COSTS_N_INSNS (2); /* clrw;swap */ \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && !(INTVAL (XEXP (X, 1)) > 0 \ - && INTVAL (XEXP (X, 1)) <= 8)) \ - return COSTS_N_INSNS (3); /* lsr #i,dn */ \ - break; \ - case MULT: \ - if (GET_CODE (XEXP (x, 1)) == CONST_INT \ - && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) \ - { \ - /* A shift by a big integer takes an extra instruction. */ \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && (INTVAL (XEXP (X, 1)) == (1 << 16))) \ - return COSTS_N_INSNS (2); /* clrw;swap */ \ - if (GET_CODE (XEXP (X, 1)) == CONST_INT \ - && !(INTVAL (XEXP (X, 1)) > 1 \ - && INTVAL (XEXP (X, 1)) <= 256)) \ - return COSTS_N_INSNS (3); /* lsr #i,dn */ \ - break; \ - } \ - else if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ - return COSTS_N_INSNS (MULW_COST); \ - else \ - return COSTS_N_INSNS (MULL_COST); \ - break; \ - case DIV: \ - case UDIV: \ - case MOD: \ - case UMOD: \ - if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ - return COSTS_N_INSNS (27); /* div.w */ \ - return COSTS_N_INSNS (43); /* div.l */ - -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). */ - -/* Set if the cc value is actually in the 68881, so a floating point - conditional branch must be output. */ -#define CC_IN_68881 04000 - -/* Store in cc_status the expressions that the condition codes will - describe after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -/* On the 68000, all the insns to store in an address register fail to - set the cc's. However, in some cases these instructions can make it - possibly invalid to use the saved cc's. In those cases we clear out - some or all of the saved cc's so they won't be used. */ - -#define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN) - -#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ -{ if (cc_prev_status.flags & CC_IN_68881) \ - return FLOAT; \ - if (cc_prev_status.flags & CC_NO_OVERFLOW) \ - return NO_OV; \ - return NORMAL; } - -/* Control the assembler format that we output. */ - -/* Output at beginning of assembler file. */ - -#define ASM_FILE_START(FILE) \ - fprintf (FILE, "#NO_APP\n"); - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#define ASM_APP_ON "#APP\n" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "#NO_APP\n" - -/* Output before read-only data. */ - -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP ".data" - -/* Here are four prefixes that are used by asm_fprintf to - facilitate customization for alternate assembler syntaxes. - Machines with no likelihood of an alternate syntax need not - define these and need not use asm_fprintf. */ - -/* The prefix for register names. Note that REGISTER_NAMES - is supposed to include this prefix. */ - -#define REGISTER_PREFIX "" - -/* The prefix for local labels. You should be able to define this as - an empty string, or any arbitrary string (such as ".", ".L%", etc) - without having to make any other changes to account for the specific - definition. Note it is a string literal, not interpreted by printf - and friends. */ - -#define LOCAL_LABEL_PREFIX "" - -/* The prefix to add to user-visible assembler symbols. */ - -#define USER_LABEL_PREFIX "_" - -/* The prefix for immediate operands. */ - -#define IMMEDIATE_PREFIX "#" - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -#ifndef SUPPORT_SUN_FPA - -#define REGISTER_NAMES \ -{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ - "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \ - "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7" } - -#else /* SUPPORTED_SUN_FPA */ - -#define REGISTER_NAMES \ -{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ - "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \ - "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \ - "fpa0", "fpa1", "fpa2", "fpa3", "fpa4", "fpa5", "fpa6", "fpa7", \ - "fpa8", "fpa9", "fpa10", "fpa11", "fpa12", "fpa13", "fpa14", "fpa15", \ - "fpa16", "fpa17", "fpa18", "fpa19", "fpa20", "fpa21", "fpa22", "fpa23", \ - "fpa24", "fpa25", "fpa26", "fpa27", "fpa28", "fpa29", "fpa30", "fpa31" } - -#endif /* defined SUPPORT_SUN_FPA */ - -/* How to renumber registers for dbx and gdb. - On the Sun-3, the floating point registers have numbers - 18 to 25, not 16 to 23 as they do in the compiler. */ - -#define DBX_REGISTER_NUMBER(REGNO) ((REGNO) < 16 ? (REGNO) : (REGNO) + 2) - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#define GLOBAL_ASM_OP ".globl" -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fprintf (FILE, "%s ", GLOBAL_ASM_OP); \ - assemble_name (FILE, NAME); \ - fputs ("\n", FILE);} while (0) - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - asm_fprintf (FILE, "%0U%s", NAME) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM) - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM) - -/* This is how to output a `long double' extended real constant. */ - -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ -do { long l[3]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "\t.long 0x%x,0x%x,0x%x\n", l[0], l[1], l[2]); \ - else \ - fprintf (FILE, "\t.long 0x%lx,0x%lx,0x%lx\n", l[0], l[1], l[2]); \ - } while (0) - -/* This is how to output an assembler line defining a `double' constant. */ - -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - do { char dstr[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ - fprintf (FILE, "\t.double 0r%s\n", dstr); \ - } while (0) - -/* This is how to output an assembler line defining a `float' constant. */ - -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ -do { long l; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - fprintf (FILE, "\t.long 0x%x\n", l); \ - else \ - fprintf (FILE, "\t.long 0x%lx\n", l); \ - } while (0) - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fprintf (FILE, "\t.long "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* Likewise for `char' and `short' constants. */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "\t.word "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fprintf (FILE, "\t.byte "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf (FILE, "\t.byte 0x%x\n", (VALUE)) - -/* This is how to output an insn to push a register on the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - asm_fprintf (FILE, "\tmovel %s,%Rsp@-\n", reg_names[REGNO]) - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - asm_fprintf (FILE, "\tmovel %Rsp@+,%s\n", reg_names[REGNO]) - -/* This is how to output an element of a case-vector that is absolute. - (The 68000 does not use such vectors, - but we must define this macro anyway.) */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - asm_fprintf (FILE, "\t.long %LL%d\n", VALUE) - -/* This is how to output an element of a case-vector that is relative. */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -/* We don't have a way to align to more than a two-byte boundary, so do the - best we can and don't complain. */ -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) >= 1) \ - fprintf (FILE, "\t.even\n"); - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.skip %u\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) - -/* Define the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "(" -#define ASM_CLOSE_PAREN ")" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - -/* Output a float value (represented as a C double) as an immediate operand. - This macro is a 68k-specific macro. */ - -#define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \ - do { \ - if (CODE == 'f') \ - { \ - char dstr[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.9g", dstr); \ - asm_fprintf ((FILE), "%I0r%s", dstr); \ - } \ - else \ - { \ - long l; \ - REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ - if (sizeof (int) == sizeof (long)) \ - asm_fprintf ((FILE), "%I0x%x", l); \ - else \ - asm_fprintf ((FILE), "%I0x%lx", l); \ - } \ - } while (0) - -/* Output a double value (represented as a C double) as an immediate operand. - This macro is a 68k-specific macro. */ -#define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \ - do { char dstr[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ - asm_fprintf (FILE, "%I0r%s", dstr); \ - } while (0) - -/* Note, long double immediate operands are not actually - generated by m68k.md. */ -#define ASM_OUTPUT_LONG_DOUBLE_OPERAND(FILE,VALUE) \ - do { char dstr[30]; \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ - asm_fprintf (FILE, "%I0r%s", dstr); \ - } while (0) - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and X is null. - - On the 68000, we use several CODE characters: - '.' for dot needed in Motorola-style opcode names. - '-' for an operand pushing on the stack: - sp@-, -(sp) or -(%sp) depending on the style of syntax. - '+' for an operand pushing on the stack: - sp@+, (sp)+ or (%sp)+ depending on the style of syntax. - '@' for a reference to the top word on the stack: - sp@, (sp) or (%sp) depending on the style of syntax. - '#' for an immediate operand prefix (# in MIT and Motorola syntax - but & in SGS syntax). - '!' for the fpcr register (used in some float-to-fixed conversions). - '$' for the letter `s' in an op code, but only on the 68040. - '&' for the letter `d' in an op code, but only on the 68040. - '/' for register prefix needed by longlong.h. - - 'b' for byte insn (no effect, on the Sun; this is for the ISI). - 'd' to force memory addressing to be absolute, not relative. - 'f' for float insn (print a CONST_DOUBLE as a float rather than in hex) - 'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather - than directly). Second part of 'y' below. - 'x' for float insn (print a CONST_DOUBLE as a float rather than in hex), - or print pair of registers as rx:ry. - 'y' for a FPA insn (print pair of registers as rx:ry). This also outputs - CONST_DOUBLE's as SunFPA constant RAM registers if - possible, so it should not be used except for the SunFPA. */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '.' || (CODE) == '#' || (CODE) == '-' \ - || (CODE) == '+' || (CODE) == '@' || (CODE) == '!' \ - || (CODE) == '$' || (CODE) == '&' || (CODE) == '/') - -/* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand X. X is an RTL - expression. - - CODE is a value that can be used to specify one of several ways - of printing the operand. It is used when identical operands - must be printed differently depending on the context. CODE - comes from the `%' specification that was used to request - printing of the operand. If the specification was just `%DIGIT' - then CODE is 0; if the specification was `%LTR DIGIT' then CODE - is the ASCII code for LTR. - - If X is a register, this macro should print the register's name. - The names can be found in an array `reg_names' whose type is - `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'. - - When the machine description has a specification `%PUNCT' (a `%' - followed by a punctuation character), this macro is called with - a null pointer for X and the punctuation character for CODE. - - See m68k.c for the m68k specific codes. */ - -#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE) - -/* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand that is a memory - reference whose address is ADDR. ADDR is an RTL expression. - - On some machines, the syntax for a symbolic address depends on - the section that the address refers to. On these machines, - define the macro `ENCODE_SECTION_INFO' to store the information - into the `symbol_ref', and then check for it here. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) - - -/* Define functions defined in aux-output.c and used in templates. */ - -extern char *output_move_double (); -extern char *output_move_const_single (); -extern char *output_move_const_double (); -extern char *output_btst (); - -/* -Local variables: -version-control: t -End: -*/ diff --git a/gnu/usr.bin/gcc2/arch/m68k/md b/gnu/usr.bin/gcc2/arch/m68k/md deleted file mode 100644 index 108c1c4884c..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/md +++ /dev/null @@ -1,5628 +0,0 @@ -;;- Machine description for GNU compiler -;;- Motorola 68000 Version -;; Copyright (C) 1987, 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - -;; $Id: md,v 1.1.1.1 1995/10/18 08:39:20 deraadt Exp $ - - -;;- instruction definitions - -;;- @@The original PO technology requires these to be ordered by speed, -;;- @@ so that assigner will pick the fastest. - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;;- When naming insn's (operand 0 of define_insn) be careful about using -;;- names from other targets machine descriptions. - -;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code -;;- updates for most instructions. - -;;- Operand classes for the register allocator: -;;- 'a' one of the address registers can be used. -;;- 'd' one of the data registers can be used. -;;- 'f' one of the m68881 registers can be used -;;- 'r' either a data or an address register can be used. -;;- 'x' if one of the Sun FPA registers -;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15). - -;;- Immediate Floating point operator constraints -;;- 'G' a floating point constant that is *NOT* one of the standard -;; 68881 constant values (to force calling output_move_const_double -;; to get it from rom if it is a 68881 constant). -;;- 'H' one of the standard FPA constant values -;; -;; See the functions standard_XXX_constant_p in output-m68k.c for more -;; info. - -;;- Immediate integer operand constraints: -;;- 'I' 1 .. 8 -;;- 'J' -32768 .. 32767 -;;- 'K' all integers EXCEPT -128 .. 127 -;;- 'L' -8 .. -1 - -;;- Assembler specs: -;;- "%." size separator ("." or "") move%.l d0,d1 -;;- "%#" immediate separator ("#" or "") move%.l %#0,d0 -;;- "%-" push operand "sp@-" move%.l d0,%- -;;- "%+" pop operand "sp@+" move%.l d0,%+ -;;- "%@" top of stack "sp@" move%.l d0,%@ -;;- "%!" fpcr register -;;- "%$" single-precision fp specifier ("s" or "") f%$add.x fp0,fp1 -;;- "%&" double-precision fp specifier ("d" or "") f%&add.x fp0,fp1 - -;;- Information about 68040 port. - -;;- The 68040 executes all 68030 and 68881/2 instructions, but some must -;;- be emulated in software by the OS. It is faster to avoid these -;;- instructions and issue a library call rather than trapping into -;;- the kernel. The affected instructions are fintrz and fscale. The -;;- TARGET_68040 flag turns the use of the opcodes off. - -;;- The '040 also implements a set of new floating-point instructions -;;- which specify the rounding precision in the opcode. This finally -;;- permit the 68k series to be truly IEEE compliant, and solves all -;;- issues of excess precision accumulating in the extended registers. -;;- By default, GCC does not use these instructions, since such code will -;;- not run on an '030. To use these instructions, use the -m68040-only -;;- switch. By changing TARGET_DEFAULT to include TARGET_68040_ONLY, -;;- you can make these instructions the default. - -;;- These new instructions aren't directly in the md. They are brought -;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather -;;- than "". - - -;;- FPA port explanation: - -;;- Usage of the Sun FPA and the 68881 together - -;;- The current port of gcc to the sun fpa disallows use of the m68881 -;;- instructions completely if code is targeted for the fpa. This is -;;- for the following reasons: - -;;- 1) Expressing the preference hierarchy (ie. use the fpa if you -;;- can, the 68881 otherwise, and data registers only if you are -;;- forced to it) is a bitch with the current constraint scheme, -;;- especially since it would have to work for any combination of -;;- -mfpa, -m68881. - -;;- 2) There are no instructions to move between the two types of -;;- registers; the stack must be used as an intermediary. - -;;- It could indeed be done; I think the best way would be to have -;;- separate patterns for TARGET_FPA (which implies a 68881), -;;- TARGET_68881, and no floating point co-processor. Use -;;- define_expands for all of the named instruction patterns, and -;;- include code in the FPA instruction to deal with the 68881 with -;;- preferences specifically set to favor the fpa. Some of this has -;;- already been done: -;;- -;;- 1) Separation of most of the patterns out into a TARGET_FPA -;;- case and a TARGET_68881 case (the exceptions are the patterns -;;- which would need one define_expand and three define_insn's under -;;- it (with a lot of duplicate code between them) to replace the -;;- current single define_insn. These are mov{[ds]f,[ds]i} and the -;;- first two patterns in the md. -;;- -;;- Some would still have to be done: -;;- -;;- 1) Add code to the fpa patterns which correspond to 68881 -;;- patterns to deal with the 68881 case (including preferences!). -;;- What you might actually do here is combine the fpa and 68881 code -;;- back together into one pattern for those instructions where it's -;;- absolutely necessary and save yourself some duplicate code. I'm -;;- not completely sure as to whether you could get away with doing -;;- this only for the mov* insns, or if you'd have to do it for all -;;- named insns. -;;- 2) Add code to the mov{[ds]f,[ds]i} instructions to handle -;;- moving between fpa regs and 68881 regs. - -;;- Since the fpa is more powerful than the 68881 and also has more -;;- registers, and since I think the resultant md would be medium ugly -;;- (lot's of duplicate code, ugly constraint strings), I elected not -;;- to do this change. - -;;- Another reason why someone *might* want to do the change is to -;;- control which register classes are accessed in a slightly cleaner -;;- way than I have. See the blurb on CONDITIONAL_REGISTER_USAGE in -;;- the internals manual. - -;;- Yet another reason why someone might want to do this change is to -;;- allow use of some of the 68881 insns which have no equivalent on -;;- the fpa. The sqrt instruction comes fairly quickly to mind. - -;;- If this is ever done, don't forget to change sun3.h so that -;;- it *will* define __HAVE_68881__ when the FPA is in use. - -;;- Condition code hack - -;;- When a floating point compare is done in the fpa, the resulting -;;- condition codes are left in the fpastatus register. The values in -;;- this register must be moved into the 68000 cc register before any -;;- jump is executed. Once this has been done, regular jump -;;- instructions are fine (ie. floating point jumps are not necessary. -;;- They are only done if the cc is in the 68881). - -;;- The instructions that move the fpastatus register to the 68000 -;;- register clobber a data register (the move cannot be done direct). -;;- These instructions might be bundled either with the compare -;;- instruction, or the branch instruction. If we were using both the -;;- fpa and the 68881 together, we would wish to only mark the -;;- register clobbered if we were doing the compare in the fpa, but I -;;- think that that decision (whether to clobber the register or not) -;;- must be done before register allocation (makes sense) and hence we -;;- can't know if the floating point compare will be done in the fpa -;;- or the fp. So whenever we are asked for code that uses the fpa, -;;- we will mark a data register as clobbered. This is reasonable, as -;;- almost all floating point compare operations done with fpa code -;;- enabled will be done in the fpa. It's even more reasonable since -;;- we decided to make the 68881 and the fpa mutually exclusive. - -;;- We place to code to move the fpastatus register inside of a -;;- define_expand so that we can do it conditionally based on whether -;;- we are targeting an fpa or not. - -;;- This still leaves us with the question of where we wish to put the -;;- code to move the fpastatus reg. If we put it in the compare -;;- instruction, we can restrict the clobbering of the register to -;;- floating point compares, but we can't take advantage of floating -;;- point subtracts & etc. that alter the fpastatus register. If we -;;- put it in the branch instruction, all branches compiled with fpa -;;- code enabled will clobber a data register, but we will be able to -;;- take advantage of fpa subtracts. This balance favors putting the -;;- code in with the compare instruction. - -;;- Note that if some enterprising hacker should decide to switch -;;- this, he'll need to modify the code in NOTICE_UPDATE_CC. - -;;- Usage of the top 16 fpa registers - -;;- The only locations which we may transfer fpa registers 16-31 from -;;- or to are the fpa registers 0-15. (68000 registers and memory -;;- locations are impossible). This causes problems in gcc, which -;;- assumes that mov?? instructions require no additional registers -;;- (see section 11.7) and since floating point moves *must* be -;;- supported into general registers (see section 12.3 under -;;- HARD_REGNO_OK_FOR_MODE_P) from anywhere. - -;;- My solution was to reserve fpa0 for moves into or out of these top -;;- 16 registers and to disparage the choice to reload into or out of -;;- these registers as much as I could. That alternative is always -;;- last in the list, so it will not be used unless all else fails. I -;;- will note that according to my current information, sun's compiler -;;- doesn't use these top 16 registers at all. - -;;- There is another possible way to do it. I *believe* that if you -;;- make absolutely sure that the code will not be executed in the -;;- reload pass, you can support the mov?? names with define_expands -;;- which require new registers. This may be possible by the -;;- appropriate juggling of constraints. I may come back to this later. - -;;- Usage of constant RAM - -;;- This has been handled correctly (I believe) but the way I've done -;;- it could use a little explanation. The constant RAM can only be -;;- accessed when the instruction is in "command register" mode. -;;- "command register" mode means that no accessing of memory or the -;;- 68000 registers is being done. This can be expressed easily in -;;- constraints, so generally the mode of the instruction is -;;- determined by a branch off of which_alternative. In outputting -;;- instructions, a 'w' means to output an access to the constant ram -;;- (if the arg is CONST_DOUBLE and is one of the available -;;- constants), and 'x' means to output a register pair (if the arg is -;;- a 68000 register) and a 'y' is the combination of the above two -;;- processes. You use a 'y' in two operand DF instructions where you -;;- *know* the other operand is an fpa register, you use an 'x' in DF -;;- instructions where the arg might be a 68000 register and the -;;- instruction is *not* in "command register" mode, and you use a 'w' -;;- in two situations: 1) The instruction *is* in command register -;;- mode (and hence won't be accessing 68000 registers), or 2) The -;;- instruction is a two operand SF instruction where you know the -;;- other operand is an fpa register. - -;;- Optimization issues - -;;- I actually think that I've included all of the fpa instructions -;;- that should be included. Note that if someone is interested in -;;- doing serious floating point work on the sun fpa, I would advise -;;- the use of the "asm" instruction in gcc to allow you to use the -;;- sin, cos, and exponential functions on the fpa board. - -;;- END FPA Explanation Section. - - -;;- Some of these insn's are composites of several m68000 op codes. -;;- The assembler (or final @@??) insures that the appropriate one is -;;- selected. - -(define_insn "" - [(set (match_operand:DF 0 "push_operand" "=m") - (match_operand:DF 1 "general_operand" "ro<>fyE"))] - "" - "* -{ - if (FP_REG_P (operands[1])) - return \"fmove%.d %f1,%0\"; - if (FPA_REG_P (operands[1])) - return \"fpmove%.d %1, %x0\"; - return output_move_double (operands); -}") - -(define_insn "" - [(set (match_operand:DI 0 "push_operand" "=m") - (match_operand:DI 1 "general_operand" "ro<>Fy"))] - "" - "* -{ - return output_move_double (operands); -}") - -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "rm"))] - "" - "* -{ -#ifdef ISI_OV - /* ISI's assembler fails to handle tstl a0. */ - if (! ADDRESS_REG_P (operands[0])) -#else - if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) -#endif - return \"tst%.l %0\"; - /* If you think that the 68020 does not support tstl a0, - reread page B-167 of the 68020 manual more carefully. */ - /* On an address reg, cmpw may replace cmpl. */ -#ifdef SGS_CMP_ORDER - return \"cmp%.w %0,%#0\"; -#else - return \"cmp%.w %#0,%0\"; -#endif -}") - -;; This can't use an address register, because comparisons -;; with address registers as second operand always test the whole word. -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "dm"))] - "" - "tst%.w %0") - -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "dm"))] - "" - "tst%.b %0") - -(define_expand "tstsf" - [(set (cc0) - (match_operand:SF 0 "general_operand" ""))] - "TARGET_68881 || TARGET_FPA" - " -{ - if (TARGET_FPA) - { - emit_insn (gen_tstsf_fpa (operands[0])); - DONE; - } -}") - -(define_insn "tstsf_fpa" - [(set (cc0) - (match_operand:SF 0 "general_operand" "xmdF")) - (clobber (match_scratch:SI 1 "=d"))] - "TARGET_FPA" - "fptst%.s %x0\;fpmove fpastatus,%1\;movw %1,cc") - -(define_insn "" - [(set (cc0) - (match_operand:SF 0 "general_operand" "fdm"))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return \"ftst%.x %0\"; - return \"ftst%.s %0\"; -}") - -(define_expand "tstdf" - [(set (cc0) - (match_operand:DF 0 "general_operand" ""))] - "TARGET_68881 || TARGET_FPA" - " -{ - if (TARGET_FPA) - { - emit_insn (gen_tstsf_fpa (operands[0])); - DONE; - } -}") - -(define_insn "tstdf_fpa" - [(set (cc0) - (match_operand:DF 0 "general_operand" "xrmF")) - (clobber (match_scratch:SI 1 "=d"))] - "TARGET_FPA" - "fptst%.d %x0\;fpmove fpastatus,%1\;movw %1,cc") - -(define_insn "" - [(set (cc0) - (match_operand:DF 0 "general_operand" "fm"))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return \"ftst%.x %0\"; - return \"ftst%.d %0\"; -}") - -;; compare instructions. - -;; A composite of the cmp, cmpa, & cmpi m68000 op codes. -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>") - (match_operand:SI 1 "general_operand" "mr,Ksr,>")))] - "" - "* -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return \"cmpm%.l %1,%0\"; - if (REG_P (operands[1]) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return \"cmp%.l %d1,%d0\"; -#else - return \"cmp%.l %d0,%d1\"; -#endif - } -#ifdef SGS_CMP_ORDER - return \"cmp%.l %d0,%d1\"; -#else - return \"cmp%.l %d1,%d0\"; -#endif -}") - -(define_insn "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m") - (match_operand:HI 1 "general_operand" "d,rnm,m,n")))] - "" - "* -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return \"cmpm%.w %1,%0\"; - if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return \"cmp%.w %d1,%d0\"; -#else - return \"cmp%.w %d0,%d1\"; -#endif - } -#ifdef SGS_CMP_ORDER - return \"cmp%.w %d0,%d1\"; -#else - return \"cmp%.w %d1,%d0\"; -#endif -}") - -(define_insn "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>") - (match_operand:QI 1 "general_operand" "dm,nd,>")))] - "" - "* -{ - if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - return \"cmpm%.b %1,%0\"; - if (REG_P (operands[1]) - || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) - { cc_status.flags |= CC_REVERSED; -#ifdef SGS_CMP_ORDER - return \"cmp%.b %d1,%d0\"; -#else - return \"cmp%.b %d0,%d1\"; -#endif - } -#ifdef SGS_CMP_ORDER - return \"cmp%.b %d0,%d1\"; -#else - return \"cmp%.b %d1,%d0\"; -#endif -}") - -(define_expand "cmpdf" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - " -{ - if (TARGET_FPA) - { - emit_insn (gen_cmpdf_fpa (operands[0], operands[1])); - DONE; - } -}") - -(define_insn "cmpdf_fpa" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "x,y") - (match_operand:DF 1 "general_operand" "xH,rmF"))) - (clobber (match_scratch:SI 2 "=d,d"))] - "TARGET_FPA" - "fpcmp%.d %y1,%0\;fpmove fpastatus,%2\;movw %2,cc") - -(define_insn "" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "f,mG") - (match_operand:DF 1 "general_operand" "fmG,f")))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return \"fcmp%.x %0,%1\"; - else - return \"fcmp%.d %0,%f1\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.d %1,%f0\"; -#else - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return \"fcmp%.x %1,%0\"; - else - return \"fcmp%.d %f1,%0\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.d %f0,%1\"; -#endif -}") - -(define_expand "cmpsf" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - " -{ - if (TARGET_FPA) - { - emit_insn (gen_cmpsf_fpa (operands[0], operands[1])); - DONE; - } -}") - -(define_insn "cmpsf_fpa" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "x,y") - (match_operand:SF 1 "general_operand" "xH,rmF"))) - (clobber (match_scratch:SI 2 "=d,d"))] - "TARGET_FPA" - "fpcmp%.s %w1,%x0\;fpmove fpastatus,%2\;movw %2,cc") - -(define_insn "" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "f,mdG") - (match_operand:SF 1 "general_operand" "fmdG,f")))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"fcmp%.x %0,%1\"; - else - return \"fcmp%.s %0,%f1\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.s %1,%f0\"; -#else - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"fcmp%.x %1,%0\"; - else - return \"fcmp%.s %f1,%0\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.s %f0,%1\"; -#endif -}") - -;; Recognizers for btst instructions. - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") - (const_int 1) - (minus:SI (const_int 7) - (match_operand:SI 1 "general_operand" "di"))))] - "" - "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") - (const_int 1) - (minus:SI (const_int 31) - (match_operand:SI 1 "general_operand" "di"))))] - "" - "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") - -;; The following two patterns are like the previous two -;; except that they use the fact that bit-number operands -;; are automatically masked to 3 or 5 bits. - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") - (const_int 1) - (minus:SI (const_int 7) - (and:SI - (match_operand:SI 1 "general_operand" "d") - (const_int 7)))))] - "" - "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") - (const_int 1) - (minus:SI (const_int 31) - (and:SI - (match_operand:SI 1 "general_operand" "d") - (const_int 31)))))] - "" - "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") - -;; Nonoffsettable mem refs are ok in this one pattern -;; since we don't try to adjust them. -(define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md") - (const_int 1) - (match_operand:SI 1 "general_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT - && (unsigned) INTVAL (operands[1]) < 8" - "* -{ - operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1])); - return output_btst (operands, operands[1], operands[0], insn, 7); -}") - -(define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do") - (const_int 1) - (match_operand:SI 1 "general_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT" - "* -{ - if (GET_CODE (operands[0]) == MEM) - { - operands[0] = adj_offsettable_operand (operands[0], - INTVAL (operands[1]) / 8); - operands[1] = gen_rtx (CONST_INT, VOIDmode, - 7 - INTVAL (operands[1]) % 8); - return output_btst (operands, operands[1], operands[0], insn, 7); - } - operands[1] = gen_rtx (CONST_INT, VOIDmode, - 31 - INTVAL (operands[1])); - return output_btst (operands, operands[1], operands[0], insn, 31); -}") - - -;; move instructions - -;; A special case in which it is not desirable -;; to reload the constant into a data register. -(define_insn "" - [(set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "general_operand" "J"))] - "GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >= -0x8000 - && INTVAL (operands[1]) < 0x8000" - "* -{ - if (operands[1] == const0_rtx) - return \"clr%.l %0\"; - return \"pea %a1\"; -}") - -;This is never used. -;(define_insn "swapsi" -; [(set (match_operand:SI 0 "general_operand" "+r") -; (match_operand:SI 1 "general_operand" "+r")) -; (set (match_dup 1) (match_dup 0))] -; "" -; "exg %1,%0") - -;; Special case of fullword move when source is zero. -;; The reason this is special is to avoid loading a zero -;; into a data reg with moveq in order to store it elsewhere. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (const_int 0))] - ;; clr insns on 68000 read before writing. - ;; This isn't so on the 68010, but we have no alternative for it. - "(TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))" - "* -{ - if (ADDRESS_REG_P (operands[0])) - return \"sub%.l %0,%0\"; - /* moveq is faster on the 68000. */ - if (DATA_REG_P (operands[0]) && !TARGET_68020) -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %#0,%0\"; -#else - return \"moveq %#0,%0\"; -#endif - return \"clr%.l %0\"; -}") - -;; General case of fullword move. -;; -;; This is the main "hook" for PIC code. When generating -;; PIC, movsi is responsible for determining when the source address -;; needs PIC relocation and appropriately calling legitimize_pic_address -;; to perform the actual relocation. -;; -;; In both the PIC and non-PIC cases the patterns generated will -;; matched by the next define_insn. -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (flag_pic && symbolic_operand (operands[1], SImode)) - { - /* The source is an address which requires PIC relocation. - Call legitimize_pic_address with the source, mode, and a relocation - register (a new pseudo, or the final destination if reload_in_progress - is set). Then fall through normally */ - extern rtx legitimize_pic_address(); - rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); - operands[1] = legitimize_pic_address (operands[1], SImode, temp); - } -}") - -;; General case of fullword move. The register constraints -;; force integer constants in range for a moveq to be reloaded -;; if they are headed for memory. -(define_insn "" - ;; Notes: make sure no alternative allows g vs g. - ;; We don't allow f-regs since fixed point cannot go in them. - ;; We do allow y and x regs since fixed point is allowed in them. - [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m") - (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))] - "" - "* -{ - if (which_alternative == 3) - return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\"; - if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0])) - return \"fpmove%.l %x1,%x0\"; - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return \"clr%.l %0\"; - else if (DATA_REG_P (operands[0]) - && INTVAL (operands[1]) < 128 - && INTVAL (operands[1]) >= -128) - { -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %1,%0\"; -#else - return \"moveq %1,%0\"; -#endif - } -#ifndef NO_ADDSUB_Q - else if (DATA_REG_P (operands[0]) - /* Do this with a moveq #N-8, dreg; addq #8,dreg */ - && INTVAL (operands[1]) < 136 - && INTVAL (operands[1]) >= 128) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %1,%0\;addq%.w %#8,%0\"; -#else - return \"moveq %1,%0\;addq%.w %#8,%0\"; -#endif - } - else if (DATA_REG_P (operands[0]) - /* Do this with a moveq #N+8, dreg; subq #8,dreg */ - && INTVAL (operands[1]) < -128 - && INTVAL (operands[1]) >= -136) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 8); -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %1,%0;subq%.w %#8,%0\"; -#else - return \"moveq %1,%0;subq%.w %#8,%0\"; -#endif - } -#endif - else if (DATA_REG_P (operands[0]) - /* If N is in the right range and is even, then use - moveq #N/2, dreg; addl dreg,dreg */ - && INTVAL (operands[1]) > 127 - && INTVAL (operands[1]) <= 254 - && INTVAL (operands[1]) % 2 == 0) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 2); -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %1,%0\;add%.w %0,%0\"; -#else - return \"moveq %1,%0\;add%.w %0,%0\"; -#endif - } - else if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return \"move%.w %1,%0\"; - else if (push_operand (operands[0], SImode) - && INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return \"pea %a1\"; - } - else if ((GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST) - && push_operand (operands[0], SImode)) - return \"pea %a1\"; - else if ((GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST) - && ADDRESS_REG_P (operands[0])) - return \"lea %a1,%0\"; - return \"move%.l %1,%0\"; -}") - -(define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=g") - (match_operand:HI 1 "general_operand" "g"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return \"clr%.w %0\"; - else if (DATA_REG_P (operands[0]) - && INTVAL (operands[1]) < 128 - && INTVAL (operands[1]) >= -128) - { -#if defined(MOTOROLA) && !defined(CRDS) - return \"moveq%.l %1,%0\"; -#else - return \"moveq %1,%0\"; -#endif - } - else if (INTVAL (operands[1]) < 0x8000 - && INTVAL (operands[1]) >= -0x8000) - return \"move%.w %1,%0\"; - } - else if (CONSTANT_P (operands[1])) - return \"move%.l %1,%0\"; -#ifndef SGS_NO_LI - /* Recognize the insn before a tablejump, one that refers - to a table of offsets. Such an insn will need to refer - to a label on the insn. So output one. Use the label-number - of the table of offsets to generate this label. */ - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF) - && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS - && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS) - { - rtx labelref; - if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF) - labelref = XEXP (XEXP (operands[1], 0), 0); - else - labelref = XEXP (XEXP (operands[1], 0), 1); -#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES) -#ifdef SGS - asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#else /* not SGS */ - asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#endif /* not SGS */ -#else /* SGS_SWITCH_TABLES or not MOTOROLA */ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", - CODE_LABEL_NUMBER (XEXP (labelref, 0))); -#ifdef SGS_SWITCH_TABLES - /* Set flag saying we need to define the symbol - LD%n (with value L%n-LI%n) at the end of the switch table. */ - switch_table_difference_label_flag = 1; -#endif /* SGS_SWITCH_TABLES */ -#endif /* SGS_SWITCH_TABLES or not MOTOROLA */ - } -#endif /* SGS_NO_LI */ - return \"move%.w %1,%0\"; -}") - -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (match_operand:HI 1 "general_operand" "rmn"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return \"clr%.w %0\"; - } - return \"move%.w %1,%0\"; -}") - -(define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a") - (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))] - "" - "* -{ - rtx xoperands[4]; - - /* This is probably useless, since it loses for pushing a struct - of several bytes a byte at a time. */ - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC - && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) - { - xoperands[1] = operands[1]; - xoperands[2] - = gen_rtx (MEM, QImode, - gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); - /* Just pushing a byte puts it in the high byte of the halfword. */ - /* We must put it in the low-order, high-numbered byte. */ - output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands); - return \"\"; - } - - /* Moving a byte into an address register is not possible. */ - /* Use d0 as an intermediate, but don't clobber its contents. */ - if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) - { - /* ??? For 2.5, don't allow this choice and use secondary reloads - instead. - - See if the address register is used in the address. If it - is, we have to generate a more complex sequence than those below. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], NULL_RTX)) - { - /* See if the stack pointer is used in the address. If it isn't, - we can push d0 or d1 (the insn can't use both of them) on - the stack, perform our move into d0/d1, copy the byte from d0/1, - and pop d0/1. */ - if (! reg_mentioned_p (stack_pointer_rtx, operands[1])) - { - if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) - return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\"; - else - return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\"; - } - else - { - /* Otherwise, we know that d0 cannot be used in the address - (since sp and one address register is). Assume that sp is - being used as a base register and replace the address - register that is our operand[0] with d0. */ - rtx reg_map[FIRST_PSEUDO_REGISTER]; - int i; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_map[i] = 0; - - reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0); - operands[1] = copy_rtx (operands[1]); - replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0); - return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; - } - } - - /* If the address of operand 1 uses d0, choose d1 as intermediate. */ - if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) - return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\"; - /* Otherwise d0 is usable. - (An effective address on the 68k can't use two d-regs.) */ - else - return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; - } - - /* Likewise for moving from an address reg. */ - if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) - { - /* ??? For 2.5, don't allow this choice and use secondary reloads - instead. - - See if the address register is used in the address. If it - is, we have to generate a more complex sequence than those below. */ - if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1, - operands[0], NULL_RTX)) - { - /* See if the stack pointer is used in the address. If it isn't, - we can push d0 or d1 (the insn can't use both of them) on - the stack, copy the byte to d0/1, perform our move from d0/d1, - and pop d0/1. */ - if (! reg_mentioned_p (stack_pointer_rtx, operands[0])) - { - if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) - return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\"; - else - return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\"; - } - else - { - /* Otherwise, we know that d0 cannot be used in the address - (since sp and one address register is). Assume that sp is - being used as a base register and replace the address - register that is our operand[1] with d0. */ - rtx reg_map[FIRST_PSEUDO_REGISTER]; - int i; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_map[i] = 0; - - reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0); - operands[0] = copy_rtx (operands[0]); - replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0); - return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; - } - } - - if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) - return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\"; - else - return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; - } - - /* clr and st insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - if (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) - { - if (operands[1] == const0_rtx) - return \"clr%.b %0\"; - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) == -1) - { - CC_STATUS_INIT; - return \"st %0\"; - } - } - if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) - return \"move%.l %1,%0\"; - if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) - return \"move%.w %1,%0\"; - return \"move%.b %1,%0\"; -}") - -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) - (match_operand:QI 1 "general_operand" "dmn"))] - "" - "* -{ - if (operands[1] == const0_rtx - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) - return \"clr%.b %0\"; - return \"move%.b %1,%0\"; -}") - -(define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm") - (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))] -; [(set (match_operand:SF 0 "general_operand" "=rmf") -; (match_operand:SF 1 "general_operand" "rmfF"))] - "" - "* -{ - if (which_alternative >= 4) - return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\"; - if (FPA_REG_P (operands[0])) - { - if (FPA_REG_P (operands[1])) - return \"fpmove%.s %x1,%x0\"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - else if (FP_REG_P (operands[1])) - return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\"; - return \"fpmove%.s %x1,%x0\"; - } - if (FPA_REG_P (operands[1])) - { - if (FP_REG_P (operands[0])) - return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\"; - else - return \"fpmove%.s %x1,%x0\"; - } - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"f%$move%.x %1,%0\"; - else if (ADDRESS_REG_P (operands[1])) - return \"move%.l %1,%-\;f%$move%.s %+,%0\"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_single (operands); - return \"f%$move%.s %f1,%0\"; - } - if (FP_REG_P (operands[1])) - { - if (ADDRESS_REG_P (operands[0])) - return \"fmove%.s %1,%-\;move%.l %+,%0\"; - return \"fmove%.s %f1,%0\"; - } - return \"move%.l %1,%0\"; -}") - -(define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm") - (match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))] -; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") -; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] - "" - "* -{ - if (which_alternative == 6) - return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; - if (FPA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - if (FP_REG_P (operands[1])) - return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\"; - return \"fpmove%.d %x1,%x0\"; - } - else if (FPA_REG_P (operands[1])) - { - if (FP_REG_P(operands[0])) - return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\"; - else - return \"fpmove%.d %x1,%x0\"; - } - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"f%&move%.x %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"move%.l %1,%-\", xoperands); - output_asm_insn (\"move%.l %1,%-\", operands); - return \"f%&move%.d %+,%0\"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - return \"f%&move%.d %f1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - else - return \"fmove%.d %f1,%0\"; - } - return output_move_double (operands); -} -") - -(define_expand "movxf" - [(set (match_operand:XF 0 "nonimmediate_operand" "") - (match_operand:XF 1 "general_operand" ""))] - "" - " -{ - if (CONSTANT_P (operands[1])) - { - operands[1] = force_const_mem (XFmode, operands[1]); - if (! memory_address_p (XFmode, XEXP (operands[1], 0)) - && ! reload_in_progress) - operands[1] = change_address (operands[1], XFmode, - XEXP (operands[1], 0)); - } -}") - -(define_insn "" - [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f") - (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"fmove%.x %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - output_asm_insn (\"move%.l %1,%-\", xoperands); - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"move%.l %1,%-\", xoperands); - output_asm_insn (\"move%.l %1,%-\", operands); - return \"fmove%.x %+,%0\"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return \"fmove%.x %1,%0\"; - return \"fmove%.x %f1,%0\"; - } - if (REG_P (operands[0])) - { - output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - output_asm_insn (\"move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - return \"fmove%.x %f1,%0\"; -} -") - -(define_insn "" - [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,&rf,&rof<>") - (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))] - "! TARGET_68881" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"fmove%.x %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - output_asm_insn (\"move%.l %1,%-\", xoperands); - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"move%.l %1,%-\", xoperands); - output_asm_insn (\"move%.l %1,%-\", operands); - return \"fmove%.x %+,%0\"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return \"fmove%.x %1,%0\"; - return \"fmove%.x %f1,%0\"; - } - if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - output_asm_insn (\"move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - else - return \"fmove%.x %f1,%0\"; - } - return output_move_double (operands); -} -") - -;; movdi can apply to fp regs in some cases -(define_insn "movdi" - ;; Let's see if it really still needs to handle fp regs, and, if so, why. - [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm") - (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))] -; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") -; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))] -; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f") -; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))] - "" - "* -{ - if (which_alternative == 8) - return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; - if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) - return \"fpmove%.d %x1,%x0\"; - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return \"fmove%.x %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"move%.l %1,%-\", xoperands); - output_asm_insn (\"move%.l %1,%-\", operands); - return \"fmove%.d %+,%0\"; - } - if (GET_CODE (operands[1]) == CONST_DOUBLE) - return output_move_const_double (operands); - return \"fmove%.d %f1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - else - return \"fmove%.d %f1,%0\"; - } - return output_move_double (operands); -} -") - -;; Thus goes after the move instructions -;; because the move instructions are better (require no spilling) -;; when they can apply. It goes before the add/sub insns -;; so we will prefer it to them. - -(define_insn "pushasi" - [(set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "address_operand" "p"))] - "" - "pea %a1") - -;; truncation instructions -(define_insn "truncsiqi2" - [(set (match_operand:QI 0 "general_operand" "=dm,d") - (truncate:QI - (match_operand:SI 1 "general_operand" "doJ,i")))] - "" - "* -{ - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return \"move%.l %1,%0\"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 3); - return \"move%.b %1,%0\"; -}") - -(define_insn "trunchiqi2" - [(set (match_operand:QI 0 "general_operand" "=dm,d") - (truncate:QI - (match_operand:HI 1 "general_operand" "doJ,i")))] - "" - "* -{ - if (GET_CODE (operands[0]) == REG - && (GET_CODE (operands[1]) == MEM - || GET_CODE (operands[1]) == CONST_INT)) - { - /* Must clear condition codes, since the move.w bases them on - the entire 16 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return \"move%.w %1,%0\"; - } - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return \"move%.l %1,%0\"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 1); - return \"move%.b %1,%0\"; -}") - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=dm,d") - (truncate:HI - (match_operand:SI 1 "general_operand" "roJ,i")))] - "" - "* -{ - if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return \"move%.l %1,%0\"; - } - if (GET_CODE (operands[1]) == MEM) - operands[1] = adj_offsettable_operand (operands[1], 2); - return \"move%.w %1,%0\"; -}") - -;; zero extension instructions - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0); -}") - -(define_expand "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); -}") - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - if (GET_CODE (operands[0]) == SUBREG) - operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), - SUBREG_WORD (operands[0])); - else - operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); -}") - -;; Patterns to recognize zero-extend insns produced by the combiner. -;; We don't allow both operands in memory, because of aliasing problems. -;; Explicitly disallow two memory operands via the condition since reloading -;; of this case will result in worse code than the uncombined patterns. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=do<>,d<") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return \"and%.l %#0xFFFF,%0\"; - if (reg_mentioned_p (operands[0], operands[1])) - return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\"; - return \"clr%.l %0\;move%.w %1,%0\"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - return \"move%.w %1,%0\;clr%.w %0\"; - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return \"clr%.w %0\;move%.w %1,%0\"; - else - { - output_asm_insn (\"clr%.w %0\", operands); - operands[0] = adj_offsettable_operand (operands[0], 2); - return \"move%.w %1,%0\"; - } -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=do<>,d") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return \"and%.w %#0xFF,%0\"; - if (reg_mentioned_p (operands[0], operands[1])) - return \"move%.b %1,%0\;and%.w %#0xFF,%0\"; - return \"clr%.w %0\;move%.b %1,%0\"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - if (REGNO (XEXP (XEXP (operands[0], 0), 0)) - == STACK_POINTER_REGNUM) - { - output_asm_insn (\"clr%.w %-\", operands); - operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), - plus_constant (stack_pointer_rtx, 1)); - return \"move%.b %1,%0\"; - } - else - return \"move%.b %1,%0\;clr%.b %0\"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return \"clr%.b %0\;move%.b %1,%0\"; - else - { - output_asm_insn (\"clr%.b %0\", operands); - operands[0] = adj_offsettable_operand (operands[0], 1); - return \"move%.b %1,%0\"; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=do<>,d") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* -{ - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return \"and%.l %#0xFF,%0\"; - if (reg_mentioned_p (operands[0], operands[1])) - return \"move%.b %1,%0\;and%.l %#0xFF,%0\"; - return \"clr%.l %0\;move%.b %1,%0\"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); -#ifdef MOTOROLA -#ifdef SGS - return \"clr%.l -(%0)\;move%.b %1,3(%0)\"; -#else - return \"clr%.l -(%0)\;move%.b %1,(3,%0)\"; -#endif -#else - return \"clrl %0@-\;moveb %1,%0@(3)\"; -#endif - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); -#ifdef MOTOROLA -#ifdef SGS - return \"clr%.l (%0)+\;move%.b %1,-1(%0)\"; -#else - return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\"; -#endif -#else - return \"clrl %0@+\;moveb %1,%0@(-1)\"; -#endif - } - else - { - output_asm_insn (\"clr%.l %0\", operands); - operands[0] = adj_offsettable_operand (operands[0], 3); - return \"move%.b %1,%0\"; - } -}") - -;; sign extension instructions - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=*d,a") - (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "0,rm")))] - "" - "* -{ - if (ADDRESS_REG_P (operands[0])) - return \"move%.w %1,%0\"; - return \"ext%.l %0\"; -}") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] - "" - "ext%.w %0") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] - "TARGET_68020" - "extb%.l %0") - -;; Conversions between float and double. - -(define_expand "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "") - (float_extend:DF - (match_operand:SF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y") - (float_extend:DF - (match_operand:SF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpstod %w1,%0") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=*fdm,f") - (float_extend:DF - (match_operand:SF 1 "general_operand" "f,dmF")))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return \"\"; - } - return \"f%&move%.x %1,%0\"; - } - if (FP_REG_P (operands[0])) - return \"f%&move%.s %f1,%0\"; - if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - return \"fmove%.d %f1,%0\"; -}") - -;; This cannot output into an f-reg because there is no way to be -;; sure of truncating in that case. -;; But on the Sun FPA, we can be sure. -(define_expand "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "") - (float_truncate:SF - (match_operand:DF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y") - (float_truncate:SF - (match_operand:DF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpdtos %y1,%0") - -;; On the '040 we can truncate in a register accurately and easily. -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (float_truncate:SF - (match_operand:DF 1 "general_operand" "fmG")))] - "TARGET_68040_ONLY" - "* -{ - if (FP_REG_P (operands[1])) - return \"f%$move%.x %1,%0\"; - return \"f%$move%.d %f1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=dm") - (float_truncate:SF - (match_operand:DF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.s %f1,%0") - -;; Conversion between fixed point and floating point. -;; Note that among the fix-to-float insns -;; the ones that start with SImode come first. -;; That is so that an operand that is a CONST_INT -;; (and therefore lacks a specific machine mode). -;; will be recognized as SImode (which is always valid) -;; rather than as QImode or HImode. - -(define_expand "floatsisf2" - [(set (match_operand:SF 0 "general_operand" "") - (float:SF (match_operand:SI 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=y,x") - (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))] - "TARGET_FPA" - "fpltos %1,%0") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (float:SF (match_operand:SI 1 "general_operand" "dmi")))] - "TARGET_68881" - "f%$move%.l %1,%0") - -(define_expand "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "") - (float:DF (match_operand:SI 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=y,x") - (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))] - "TARGET_FPA" - "fpltod %1,%0") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (float:DF (match_operand:SI 1 "general_operand" "dmi")))] - "TARGET_68881" - "f%&move%.l %1,%0") - -(define_insn "floathisf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (float:SF (match_operand:HI 1 "general_operand" "dmn")))] - "TARGET_68881" - "f%$move%.w %1,%0") - -(define_insn "floathidf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (float:DF (match_operand:HI 1 "general_operand" "dmn")))] - "TARGET_68881" - "fmove%.w %1,%0") - -(define_insn "floatqisf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (float:SF (match_operand:QI 1 "general_operand" "dmn")))] - "TARGET_68881" - "fmove%.b %1,%0") - -(define_insn "floatqidf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (float:DF (match_operand:QI 1 "general_operand" "dmn")))] - "TARGET_68881" - "f%&move%.b %1,%0") - -;; New routines to convert floating-point values to integers -;; to be used on the '040. These should be faster than trapping -;; into the kernel to emulate fintrz. They should also be faster -;; than calling the subroutines fixsfsi or fixdfsi. - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_scratch:SI 2 "=d")) - (clobber (match_scratch:SI 3 "=d"))] - "TARGET_68040" - "* -{ - CC_STATUS_INIT; - return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!\"; -}") - -(define_insn "fix_truncdfhi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_scratch:SI 2 "=d")) - (clobber (match_scratch:SI 3 "=d"))] - "TARGET_68040" - "* -{ - CC_STATUS_INIT; - return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!\"; -}") - -(define_insn "fix_truncdfqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_scratch:SI 2 "=d")) - (clobber (match_scratch:SI 3 "=d"))] - "TARGET_68040" - "* -{ - CC_STATUS_INIT; - return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!\"; -}") - -;; Convert a float to a float whose value is an integer. -;; This is the first stage of converting it to an integer type. - -(define_insn "ftruncdf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (fix:DF (match_operand:DF 1 "general_operand" "fFm")))] - "TARGET_68881 && !TARGET_68040" - "* -{ - if (FP_REG_P (operands[1])) - return \"fintrz%.x %f1,%0\"; - return \"fintrz%.d %f1,%0\"; -}") - -(define_insn "ftruncsf2" - [(set (match_operand:SF 0 "general_operand" "=f") - (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))] - "TARGET_68881 && !TARGET_68040" - "* -{ - if (FP_REG_P (operands[1])) - return \"fintrz%.x %f1,%0\"; - return \"fintrz%.s %f1,%0\"; -}") - -;; Convert a float whose value is an integer -;; to an actual integer. Second stage of converting float to integer type. -(define_insn "fixsfqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (fix:QI (match_operand:SF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.b %1,%0") - -(define_insn "fixsfhi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (fix:HI (match_operand:SF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.w %1,%0") - -(define_insn "fixsfsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (fix:SI (match_operand:SF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.l %1,%0") - -(define_insn "fixdfqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (fix:QI (match_operand:DF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.b %1,%0") - -(define_insn "fixdfhi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (fix:HI (match_operand:DF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.w %1,%0") - -(define_insn "fixdfsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (fix:SI (match_operand:DF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.l %1,%0") - -;; Convert a float to an integer. -;; On the Sun FPA, this is done in one step. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=x,y") - (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))] - "TARGET_FPA" - "fpstol %w1,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=x,y") - (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))] - "TARGET_FPA" - "fpdtol %y1,%0") - -;; add instructions - -;; Note that the middle two alternatives are near-duplicates -;; in order to handle insns generated by reload. -;; This is needed since they are not themselves reloaded, -;; so commutativity won't apply to them. -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r") - (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") - (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))] - "" - "* -{ - if (! operands_match_p (operands[0], operands[1])) - { - if (!ADDRESS_REG_P (operands[1])) - { - rtx tmp = operands[1]; - - operands[1] = operands[2]; - operands[2] = tmp; - } - - /* These insns can result from reloads to access - stack slots over 64k from the frame pointer. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000) - return \"move%.l %2,%0\;add%.l %1,%0\"; -#ifdef SGS - if (GET_CODE (operands[2]) == REG) - return \"lea 0(%1,%2.l),%0\"; - else - return \"lea %c2(%1),%0\"; -#else /* not SGS */ -#ifdef MOTOROLA - if (GET_CODE (operands[2]) == REG) - return \"lea (%1,%2.l),%0\"; - else - return \"lea (%c2,%1),%0\"; -#else /* not MOTOROLA (MIT syntax) */ - if (GET_CODE (operands[2]) == REG) - return \"lea %1@(0,%2:l),%0\"; - else - return \"lea %1@(%c2),%0\"; -#endif /* not MOTOROLA */ -#endif /* not SGS */ - } - if (GET_CODE (operands[2]) == CONST_INT) - { -#ifndef NO_ADDSUB_Q - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return (ADDRESS_REG_P (operands[0]) - ? \"addq%.w %2,%0\" - : \"addq%.l %2,%0\"); - if (INTVAL (operands[2]) < 0 - && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2])); - return (ADDRESS_REG_P (operands[0]) - ? \"subq%.w %2,%0\" - : \"subq%.l %2,%0\"); - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw.*/ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return \"addq%.w %#8,%0\;addq%.w %2,%0\"; - } - if (INTVAL (operands[2]) < -8 - && INTVAL (operands[2]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2]) - 8); - return \"subq%.w %#8,%0\;subq%.w %2,%0\"; - } -#endif - if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[2]) >= -0x8000 - && INTVAL (operands[2]) < 0x8000) - return \"add%.w %2,%0\"; - } - return \"add%.l %2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=a") - (plus:SI (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI - (match_operand:HI 2 "nonimmediate_operand" "rm"))))] - "" - "add%.w %2,%0") - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=m,r") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "dn,rmn")))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[2]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[2]) >= 32768) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) - 65536); - - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return \"addq%.w %2,%0\"; - if (INTVAL (operands[2]) < 0 - && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2])); - return \"subq%.w %2,%0\"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return \"addq%.w %#8,%0\;addq%.w %2,%0\"; - } - if (INTVAL (operands[2]) < -8 - && INTVAL (operands[2]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[2]) - 8); - return \"subq%.w %#8,%0\;subq%.w %2,%0\"; - } - } -#endif - return \"add%.w %2,%0\"; -}") - -;; These insns must use MATCH_DUP instead of the more expected -;; use of a matching constraint because the "output" here is also -;; an input, so you can't use the matching constraint. That also means -;; that you can't use the "%", so you need patterns with the matched -;; operand in both positions. - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (plus:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dn,rmn")))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[1]) >= 32768) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 65536); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return \"addq%.w %1,%0\"; - if (INTVAL (operands[1]) < 0 - && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1])); - return \"subq%.w %1,%0\"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[1]) > 8 - && INTVAL (operands[1]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); - return \"addq%.w %#8,%0\;addq%.w %1,%0\"; - } - if (INTVAL (operands[1]) < -8 - && INTVAL (operands[1]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1]) - 8); - return \"subq%.w %#8,%0\;subq%.w %1,%0\"; - } - } -#endif - return \"add%.w %1,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn") - (match_dup 0)))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - /* If the constant would be a negative number when interpreted as - HImode, make it negative. This is usually, but not always, done - elsewhere in the compiler. First check for constants out of range, - which could confuse us. */ - - if (INTVAL (operands[1]) >= 32768) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 65536); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return \"addq%.w %1,%0\"; - if (INTVAL (operands[1]) < 0 - && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1])); - return \"subq%.w %1,%0\"; - } - /* On everything except the 68000 it is faster to use two - addqw instructions to add a small integer (8 < N <= 16) - to an address register. Likewise for subqw. */ - if (INTVAL (operands[1]) > 8 - && INTVAL (operands[1]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); - return \"addq%.w %#8,%0\;addq%.w %1,%0\"; - } - if (INTVAL (operands[1]) < -8 - && INTVAL (operands[1]) >= -16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - - INTVAL (operands[1]) - 8); - return \"subq%.w %#8,%0\;subq%.w %1,%0\"; - } - } -#endif - return \"add%.w %1,%0\"; -}") - -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=m,d") - (plus:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "dn,dmn")))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 128) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) - 256); - - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return \"addq%.b %2,%0\"; - if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); - return \"subq%.b %2,%0\"; - } - } -#endif - return \"add%.b %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (plus:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dn,dmn")))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 128) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 256); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return \"addq%.b %1,%0\"; - if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); - return \"subq%.b %1,%0\"; - } - } -#endif - return \"add%.b %1,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn") - (match_dup 0)))] - "" - "* -{ -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 128) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) - 256); - - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return \"addq%.b %1,%0\"; - if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); - return \"subq%.b %1,%0\"; - } - } -#endif - return \"add%.b %1,%0\"; -}") - -(define_expand "adddf3" - [(set (match_operand:DF 0 "general_operand" "") - (plus:DF (match_operand:DF 1 "general_operand" "") - (match_operand:DF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y") - (plus:DF (match_operand:DF 1 "general_operand" "%xH,y") - (match_operand:DF 2 "general_operand" "xH,dmF")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - return \"fpadd%.d %y2,%0\"; - if (rtx_equal_p (operands[0], operands[2])) - return \"fpadd%.d %y1,%0\"; - if (which_alternative == 0) - return \"fpadd3%.d %w2,%w1,%0\"; - return \"fpadd3%.d %x2,%x1,%0\"; -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (plus:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"f%&add%.x %2,%0\"; - return \"f%&add%.d %f2,%0\"; -}") - -(define_expand "addsf3" - [(set (match_operand:SF 0 "general_operand" "") - (plus:SF (match_operand:SF 1 "general_operand" "") - (match_operand:SF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y") - (plus:SF (match_operand:SF 1 "general_operand" "%xH,y") - (match_operand:SF 2 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - return \"fpadd%.s %w2,%0\"; - if (rtx_equal_p (operands[0], operands[2])) - return \"fpadd%.s %w1,%0\"; - if (which_alternative == 0) - return \"fpadd3%.s %w2,%w1,%0\"; - return \"fpadd3%.s %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (plus:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fdmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return \"f%$add%.x %2,%0\"; - return \"f%$add%.s %f2,%0\"; -}") - -;; subtract instructions - -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d") - (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs") - (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))] - "" - "* -{ - if (! operands_match_p (operands[0], operands[1])) - { - if (operands_match_p (operands[0], operands[2])) - { -#ifndef NO_ADDSUB_Q - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) > 0 - && INTVAL (operands[1]) <= 8) - return \"subq%.l %1,%0\;neg%.l %0\"; - } -#endif - return \"sub%.l %1,%0\;neg%.l %0\"; - } - /* This case is matched by J, but negating -0x8000 - in an lea would give an invalid displacement. - So do this specially. */ - if (INTVAL (operands[2]) == -0x8000) - return \"move%.l %1,%0\;sub%.l %2,%0\"; -#ifdef SGS - return \"lea %n2(%1),%0\"; -#else -#ifdef MOTOROLA - return \"lea (%n2,%1),%0\"; -#else /* not MOTOROLA (MIT syntax) */ - return \"lea %1@(%n2),%0\"; -#endif /* not MOTOROLA */ -#endif /* not SGS */ - } - if (GET_CODE (operands[2]) == CONST_INT) - { -#ifndef NO_ADDSUB_Q - if (INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 8) - return \"subq%.l %2,%0\"; - /* Using two subqw for 8 < N <= 16 being subtracted from an - address register is faster on all but 68000 */ - if (INTVAL (operands[2]) > 8 - && INTVAL (operands[2]) <= 16 - && ADDRESS_REG_P (operands[0]) - && TARGET_68020) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); - return \"subq%.w %#8,%0\;subq%.w %2,%0\"; - } -#endif - if (ADDRESS_REG_P (operands[0]) - && INTVAL (operands[2]) >= -0x8000 - && INTVAL (operands[2]) < 0x8000) - return \"sub%.w %2,%0\"; - } - return \"sub%.l %2,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=a") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI - (match_operand:HI 2 "nonimmediate_operand" "rm"))))] - "" - "sub%.w %2,%0") - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=m,r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "general_operand" "dn,rmn")))] - "" - "sub%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (minus:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dn,rmn")))] - "" - "sub%.w %1,%0") - -(define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=m,d") - (minus:QI (match_operand:QI 1 "general_operand" "0,0") - (match_operand:QI 2 "general_operand" "dn,dmn")))] - "" - "sub%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (minus:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dn,dmn")))] - "" - "sub%.b %1,%0") - -(define_expand "subdf3" - [(set (match_operand:DF 0 "general_operand" "") - (minus:DF (match_operand:DF 1 "general_operand" "") - (match_operand:DF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y,y") - (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF") - (match_operand:DF 2 "general_operand" "xH,dmF,0")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[2])) - return \"fprsub%.d %y1,%0\"; - if (rtx_equal_p (operands[0], operands[1])) - return \"fpsub%.d %y2,%0\"; - if (which_alternative == 0) - return \"fpsub3%.d %w2,%w1,%0\"; - return \"fpsub3%.d %x2,%x1,%0\"; -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (minus:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"f%&sub%.x %2,%0\"; - return \"f%&sub%.d %f2,%0\"; -}") - -(define_expand "subsf3" - [(set (match_operand:SF 0 "general_operand" "") - (minus:SF (match_operand:SF 1 "general_operand" "") - (match_operand:SF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y,y") - (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") - (match_operand:SF 2 "general_operand" "xH,rmF,0")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[2])) - return \"fprsub%.s %w1,%0\"; - if (rtx_equal_p (operands[0], operands[1])) - return \"fpsub%.s %w2,%0\"; - if (which_alternative == 0) - return \"fpsub3%.s %w2,%w1,%0\"; - return \"fpsub3%.s %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (minus:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fdmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return \"f%$sub%.x %2,%0\"; - return \"f%$sub%.s %f2,%0\"; -}") - -;; multiply instructions - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "dmn")))] - "" - "* -{ -#if defined(MOTOROLA) && !defined(CRDS) - return \"muls%.w %2,%0\"; -#else - return \"muls %2,%0\"; -#endif -}") - -(define_insn "mulhisi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "%0")) - (sign_extend:SI - (match_operand:HI 2 "nonimmediate_operand" "dm"))))] - "" - "* -{ -#if defined(MOTOROLA) && !defined(CRDS) - return \"muls%.w %2,%0\"; -#else - return \"muls %2,%0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "%0")) - (match_operand:SI 2 "const_int_operand" "n")))] - "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff" - "* -{ -#if defined(MOTOROLA) && !defined(CRDS) - return \"muls%.w %2,%0\"; -#else - return \"muls %2,%0\"; -#endif -}") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "dmsK")))] - "TARGET_68020" - "muls%.l %2,%0") - -(define_insn "umulhisi3" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "%0")) - (zero_extend:SI - (match_operand:HI 2 "nonimmediate_operand" "dm"))))] - "" - "* -{ -#if defined(MOTOROLA) && !defined(CRDS) - return \"mulu%.w %2,%0\"; -#else - return \"mulu %2,%0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (mult:SI (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "%0")) - (match_operand:SI 2 "const_int_operand" "n")))] - "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff" - "* -{ -#if defined(MOTOROLA) && !defined(CRDS) - return \"mulu%.w %2,%0\"; -#else - return \"mulu %2,%0\"; -#endif -}") - -;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the -;; proper matching constraint. This is because the matching is between -;; the high-numbered word of the DImode operand[0] and operand[1]. -(define_expand "umulsidi3" - [(parallel - [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) - (mult:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonimmediate_operand" ""))) - (set (subreg:SI (match_dup 0) 0) - (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32))))])] - "TARGET_68020" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonimmediate_operand" "dm"))) - (set (match_operand:SI 3 "register_operand" "=d") - (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32))))] - "TARGET_68020" - "mulu%.l %2,%3:%0") - -; Match immediate case. For 2.4 only match things < 2^31. -; It's tricky with larger values in these patterns since we need to match -; values between the two parallel multiplies, between a CONST_DOUBLE and -; a CONST_INT. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "const_int_operand" "n"))) - (set (match_operand:SI 3 "register_operand" "=d") - (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (match_dup 2)) - (const_int 32))))] - "TARGET_68020 - && (unsigned) INTVAL (operands[2]) <= 0x7fffffff" - "mulu%.l %2,%3:%0") - -(define_expand "mulsidi3" - [(parallel - [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) - (mult:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonimmediate_operand" ""))) - (set (subreg:SI (match_dup 0) 0) - (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32))))])] - "TARGET_68020" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonimmediate_operand" "dm"))) - (set (match_operand:SI 3 "register_operand" "=d") - (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32))))] - "TARGET_68020" - "muls%.l %2,%3:%0") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "const_int_operand" "n"))) - (set (match_operand:SI 3 "register_operand" "=d") - (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) - (match_dup 2)) - (const_int 32))))] - "TARGET_68020 - /* This test is a noop on 32 bit machines, - but important for a cross-compiler hosted on 64-bit machines. */ - && INTVAL (operands[2]) <= 0x7fffffff - && INTVAL (operands[2]) >= -0x80000000" - "muls%.l %2,%3:%0") - -(define_expand "muldf3" - [(set (match_operand:DF 0 "general_operand" "") - (mult:DF (match_operand:DF 1 "general_operand" "") - (match_operand:DF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y") - (mult:DF (match_operand:DF 1 "general_operand" "%xH,y") - (match_operand:DF 2 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[1], operands[2])) - return \"fpsqr%.d %y1,%0\"; - if (rtx_equal_p (operands[0], operands[1])) - return \"fpmul%.d %y2,%0\"; - if (rtx_equal_p (operands[0], operands[2])) - return \"fpmul%.d %y1,%0\"; - if (which_alternative == 0) - return \"fpmul3%.d %w2,%w1,%0\"; - return \"fpmul3%.d %x2,%x1,%0\"; -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (mult:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (GET_CODE (operands[2]) == CONST_DOUBLE - && floating_exact_log2 (operands[2]) && !TARGET_68040) - { - int i = floating_exact_log2 (operands[2]); - operands[2] = gen_rtx (CONST_INT, VOIDmode, i); - return \"fscale%.l %2,%0\"; - } - if (REG_P (operands[2])) - return \"f%&mul%.x %2,%0\"; - return \"f%&mul%.d %f2,%0\"; -}") - -(define_expand "mulsf3" - [(set (match_operand:SF 0 "general_operand" "") - (mult:SF (match_operand:SF 1 "general_operand" "") - (match_operand:SF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y") - (mult:SF (match_operand:SF 1 "general_operand" "%xH,y") - (match_operand:SF 2 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[1], operands[2])) - return \"fpsqr%.s %w1,%0\"; - if (rtx_equal_p (operands[0], operands[1])) - return \"fpmul%.s %w2,%0\"; - if (rtx_equal_p (operands[0], operands[2])) - return \"fpmul%.s %w1,%0\"; - if (which_alternative == 0) - return \"fpmul3%.s %w2,%w1,%0\"; - return \"fpmul3%.s %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (mult:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fdmF")))] - "TARGET_68881" - "* -{ -#ifdef FSGLMUL_USE_S - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? \"fsmul%.s %2,%0\" - : \"fsglmul%.s %2,%0\"); -#else - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? \"fsmul%.x %2,%0\" - : \"fsglmul%.x %2,%0\"); -#endif - return (TARGET_68040_ONLY - ? \"fsmul%.s %f2,%0\" - : \"fsglmul%.s %f2,%0\"); -}") - -;; divide instructions - -(define_insn "divhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (div:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "dmn")))] - "" - "* -{ -#ifdef MOTOROLA - return \"ext%.l %0\;divs%.w %2,%0\"; -#else - return \"extl %0\;divs %2,%0\"; -#endif -}") - -(define_insn "divhisi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] - "" - "* -{ -#ifdef MOTOROLA - return \"divs%.w %2,%0\"; -#else - return \"divs %2,%0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "const_int_operand" "n"))))] - "" - "* -{ -#ifdef MOTOROLA - return \"divs%.w %2,%0\"; -#else - return \"divs %2,%0\"; -#endif -}") - -(define_insn "udivhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (udiv:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "dmn")))] - "" - "* -{ -#ifdef MOTOROLA - return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\"; -#else - return \"andl %#0xFFFF,%0\;divu %2,%0\"; -#endif -}") - -(define_insn "udivhisi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI - (udiv:SI - (match_operand:SI 1 "general_operand" "0") - (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] - "" - "* -{ -#ifdef MOTOROLA - return \"divu%.w %2,%0\"; -#else - return \"divu %2,%0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "const_int_operand" "n"))))] - "" - "* -{ -#ifdef MOTOROLA - return \"divu%.w %2,%0\"; -#else - return \"divu %2,%0\"; -#endif -}") - -(define_expand "divdf3" - [(set (match_operand:DF 0 "general_operand" "") - (div:DF (match_operand:DF 1 "general_operand" "") - (match_operand:DF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y,y") - (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF") - (match_operand:DF 2 "general_operand" "xH,rmF,0")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[2])) - return \"fprdiv%.d %y1,%0\"; - if (rtx_equal_p (operands[0], operands[1])) - return \"fpdiv%.d %y2,%0\"; - if (which_alternative == 0) - return \"fpdiv3%.d %w2,%w1,%0\"; - return \"fpdiv3%.d %x2,%x1,%x0\"; -}") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (div:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"f%&div%.x %2,%0\"; - return \"f%&div%.d %f2,%0\"; -}") - -(define_expand "divsf3" - [(set (match_operand:SF 0 "general_operand" "") - (div:SF (match_operand:SF 1 "general_operand" "") - (match_operand:SF 2 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y,y") - (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") - (match_operand:SF 2 "general_operand" "xH,rmF,0")))] - "TARGET_FPA" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - return \"fpdiv%.s %w2,%0\"; - if (rtx_equal_p (operands[0], operands[2])) - return \"fprdiv%.s %w1,%0\"; - if (which_alternative == 0) - return \"fpdiv3%.s %w2,%w1,%0\"; - return \"fpdiv3%.s %2,%1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (div:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fdmF")))] - "TARGET_68881" - "* -{ -#ifdef FSGLDIV_USE_S - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? \"fsdiv%.s %2,%0\" - : \"fsgldiv%.s %2,%0\"); -#else - if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) - return (TARGET_68040_ONLY - ? \"fsdiv%.x %2,%0\" - : \"fsgldiv%.x %2,%0\"); -#endif - return (TARGET_68040_ONLY - ? \"fsdiv%.s %f2,%0\" - : \"fsgldiv%.s %f2,%0\"); -}") - -;; Remainder instructions. - -(define_insn "modhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (mod:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "dmn")))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"ext%.l %0\;divs%.w %2,%0\;swap %0\"; -#else - return \"extl %0\;divs %2,%0\;swap %0\"; -#endif -}") - -(define_insn "modhisi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI - (mod:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"divs%.w %2,%0\;swap %0\"; -#else - return \"divs %2,%0\;swap %0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "const_int_operand" "n"))))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"divs%.w %2,%0\;swap %0\"; -#else - return \"divs %2,%0\;swap %0\"; -#endif -}") - -(define_insn "umodhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (umod:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "dmn")))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\"; -#else - return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\"; -#endif -}") - -(define_insn "umodhisi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI - (umod:SI - (match_operand:SI 1 "general_operand" "0") - (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"divu%.w %2,%0\;swap %0\"; -#else - return \"divu %2,%0\;swap %0\"; -#endif -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "const_int_operand" "n"))))] - "" - "* -{ - /* The swap insn produces cc's that don't correspond to the result. */ - CC_STATUS_INIT; -#ifdef MOTOROLA - return \"divu%.w %2,%0\;swap %0\"; -#else - return \"divu %2,%0\;swap %0\"; -#endif -}") - -(define_insn "divmodsi4" - [(set (match_operand:SI 0 "general_operand" "=d") - (div:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "dmsK"))) - (set (match_operand:SI 3 "general_operand" "=d") - (mod:SI (match_dup 1) (match_dup 2)))] - "TARGET_68020" - "* -{ - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return \"divs%.l %2,%0\"; - else - return \"divsl%.l %2,%3:%0\"; -}") - -(define_insn "udivmodsi4" - [(set (match_operand:SI 0 "general_operand" "=d") - (udiv:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "dmsK"))) - (set (match_operand:SI 3 "general_operand" "=d") - (umod:SI (match_dup 1) (match_dup 2)))] - "TARGET_68020" - "* -{ - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return \"divu%.l %2,%0\"; - else - return \"divul%.l %2,%3:%0\"; -}") - -;; logical-and instructions - -;; Prevent AND from being made with sp. This doesn't exist in the machine -;; and reload will cause inefficient code. Since sp is a FIXED_REG, we -;; can't allocate pseudos into it. -(define_insn "andsi3" - [(set (match_operand:SI 0 "not_sp_operand" "=m,d") - (and:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "dKs,dmKs")))] - "" - "* -{ - int logval; - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xffff) == 0xffffffff - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - if (operands[2] == const0_rtx) - return \"clr%.w %0\"; - return \"and%.w %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - /* This does not set condition codes in a standard way. */ - CC_STATUS_INIT; - return \"bclr %1,%0\"; - } - return \"and%.l %2,%0\"; -}") - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=m,d") - (and:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "dn,dmn")))] - "" - "and%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (and:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dn,dmn")))] - "" - "and%.w %1,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (and:HI (match_operand:HI 1 "general_operand" "dn,dmn") - (match_dup 0)))] - "" - "and%.w %1,%0") - -(define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=m,d") - (and:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "dn,dmn")))] - "" - "and%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (and:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dn,dmn")))] - "" - "and%.b %1,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (and:QI (match_operand:QI 1 "general_operand" "dn,dmn") - (match_dup 0)))] - "" - "and%.b %1,%0") - -;; inclusive-or instructions - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=m,d") - (ior:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "dKs,dmKs")))] - "" - "* -{ - register int logval; - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return \"or%.w %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - CC_STATUS_INIT; - return \"bset %1,%0\"; - } - return \"or%.l %2,%0\"; -}") - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=m,d") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "dn,dmn")))] - "" - "or%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (ior:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dn,dmn")))] - "" - "or%.w %1,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) - (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn") - (match_dup 0)))] - "" - "or%.w %1,%0") - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=m,d") - (ior:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "dn,dmn")))] - "" - "or%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (ior:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dn,dmn")))] - "" - "or%.b %1,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) - (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn") - (match_dup 0)))] - "" - "or%.b %1,%0") - -;; xor instructions - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=do,m") - (xor:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "di,dKs")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) - { - if (! DATA_REG_P (operands[0])) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return \"eor%.w %2,%0\"; - } - return \"eor%.l %2,%0\"; -}") - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=dm") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "dn")))] - "" - "eor%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (xor:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dn")))] - "" - "eor%.w %1,%0") - - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (xor:HI (match_operand:HI 1 "general_operand" "dn") - (match_dup 0)))] - "" - "eor%.w %1,%0") - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=dm") - (xor:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "dn")))] - "" - "eor%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) - (xor:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dn")))] - "" - "eor%.b %1,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) - (xor:QI (match_operand:QI 1 "general_operand" "dn") - (match_dup 0)))] - "" - "eor%.b %1,%0") - -;; negation instructions - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (neg:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "neg%.l %0") - -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (neg:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "neg%.w %0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (neg:HI (match_dup 0)))] - "" - "neg%.w %0") - -(define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (neg:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "neg%.b %0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) - (neg:QI (match_dup 0)))] - "" - "neg%.b %0") - -(define_expand "negsf2" - [(set (match_operand:SF 0 "general_operand" "") - (neg:SF (match_operand:SF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y") - (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpneg%.s %w1,%0") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f,d") - (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))] - "TARGET_68881" - "* -{ - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); - return \"bchg %1,%0\"; - } - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"f%$neg%.x %1,%0\"; - return \"f%$neg%.s %f1,%0\"; -}") - -(define_expand "negdf2" - [(set (match_operand:DF 0 "general_operand" "") - (neg:DF (match_operand:DF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y") - (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpneg%.d %y1, %0") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f,d") - (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))] - "TARGET_68881" - "* -{ - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); - return \"bchg %1,%0\"; - } - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"f%&neg%.x %1,%0\"; - return \"f%&neg%.d %f1,%0\"; -}") - -;; Sqrt instruction for the 68881 - -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "general_operand" "=f") - (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[1])) - return \"fsqrt%.x %1,%0\"; - else - return \"fsqrt%.d %1,%0\"; -}") - -;; Absolute value instructions - -(define_expand "abssf2" - [(set (match_operand:SF 0 "general_operand" "") - (abs:SF (match_operand:SF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=x,y") - (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpabs%.s %y1,%0") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=f") - (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"f%$abs%.x %1,%0\"; - return \"f%$abs%.s %f1,%0\"; -}") - -(define_expand "absdf2" - [(set (match_operand:DF 0 "general_operand" "") - (abs:DF (match_operand:DF 1 "general_operand" "")))] - "TARGET_68881 || TARGET_FPA" - "") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=x,y") - (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] - "TARGET_FPA" - "fpabs%.d %y1,%0") - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=f") - (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"f%&abs%.x %1,%0\"; - return \"f%&abs%.d %f1,%0\"; -}") - -;; one complement instructions - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (not:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "not%.l %0") - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (not:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "not%.w %0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) - (not:HI (match_dup 0)))] - "" - "not%.w %0") - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (not:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "not%.b %0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) - (not:QI (match_dup 0)))] - "" - "not%.b %0") - -;; arithmetic shift instructions -;; We don't need the shift memory by 1 bit instruction - -;; On all 68k models, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" - "* -{ - CC_STATUS_INIT; - return \"swap %0\;clr%.w %0\"; -}") - -;; On the 68000, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" - "* -{ - CC_STATUS_INIT; - - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"asl%.w %2,%0\;swap %0\;clr%.w %0\"; -}") - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "* -{ - if (operands[2] == const1_rtx) - return \"add%.l %0,%0\"; - return \"asl%.l %2,%0\"; -}") - -(define_insn "ashlhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (ashift:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "asl%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (ashift:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "asl%.w %1,%0") - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (ashift:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "asl%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (ashift:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "asl%.b %1,%0") - -;; On all 68k models, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" - "swap %0\;ext%.l %0") - -;; On the 68000, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" - "* -{ - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; -}") - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "* -{ - return \"asr%.l %2,%0\"; -}") - -(define_insn "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "asr%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (ashiftrt:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "asr%.w %1,%0") - -(define_insn "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "asr%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (ashiftrt:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "asr%.b %1,%0") - -;; logical shift instructions - -;; On all 68k models, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" - "* -{ - CC_STATUS_INIT; - return \"swap %0\;clr%.w %0\"; -}") - -;; On the 68000, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" - "* -{ - CC_STATUS_INIT; - - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\"; -}") - -(define_insn "lshlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "* -{ - if (operands[2] == const1_rtx) - return \"add%.l %0,%0\"; - return \"lsl%.l %2,%0\"; -}") - -(define_insn "lshlhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (lshift:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "lsl%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (lshift:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "lsl%.w %1,%0") - -(define_insn "lshlqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (lshift:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "lsl%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (lshift:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "lsl%.b %1,%0") - -;; On all 68k models, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" - "* -{ - CC_STATUS_INIT; - return \"clr%.w %0\;swap %0\"; -}") - -;; On the 68000, this makes faster code in a special case. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" - "* -{ - /* I think lsr%.w sets the CC properly. */ - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\"; -}") - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "* -{ - return \"lsr%.l %2,%0\"; -}") - -(define_insn "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "lsr%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (lshiftrt:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "lsr%.w %1,%0") - -(define_insn "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "lsr%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (lshiftrt:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "lsr%.b %1,%0") - -;; rotate instructions - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (rotate:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "rol%.l %2,%0") - -(define_insn "rotlhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (rotate:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "rol%.w %2,%0") - - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (rotate:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "rol%.w %1,%0") - -(define_insn "rotlqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (rotate:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "rol%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (rotate:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "rol%.b %1,%0") - -(define_insn "rotrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (rotatert:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "dI")))] - "" - "ror%.l %2,%0") - -(define_insn "rotrhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (rotatert:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "dI")))] - "" - "ror%.w %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (rotatert:HI (match_dup 0) - (match_operand:HI 1 "general_operand" "dI")))] - "" - "ror%.w %1,%0") - -(define_insn "rotrqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (rotatert:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "dI")))] - "" - "ror%.b %2,%0") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) - (rotatert:QI (match_dup 0) - (match_operand:QI 1 "general_operand" "dI")))] - "" - "ror%.b %1,%0") - -;; Special cases of bit-field insns which we should -;; recognize in preference to the general case. -;; These handle aligned 8-bit and 16-bit fields, -;; which can usually be done with move instructions. - -; -; Special case for 32-bit field in memory. This only occurs when 32-bit -; alignment of structure members is specified. -; -; The move is allowed to be odd byte aligned, because that's still faster -; than an odd byte aligned bit field instruction. -; -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o") - (match_operand:SI 1 "immediate_operand" "i") - (match_operand:SI 2 "immediate_operand" "i")) - (match_operand:SI 3 "general_operand" "rmi"))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 32) - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[0], 0))" - "* -{ - operands[0] - = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); - - return \"move%.l %3,%0\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do") - (match_operand:SI 1 "immediate_operand" "i") - (match_operand:SI 2 "immediate_operand" "i")) - (match_operand:SI 3 "general_operand" "d"))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) - && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 - && (GET_CODE (operands[0]) == REG - || ! mode_dependent_address_p (XEXP (operands[0], 0)))" - "* -{ - if (REG_P (operands[0])) - { - if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) - return \"bfins %3,%0{%b2:%b1}\"; - } - else - operands[0] - = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); - - if (GET_CODE (operands[3]) == MEM) - operands[3] = adj_offsettable_operand (operands[3], - (32 - INTVAL (operands[1])) / 8); - if (INTVAL (operands[1]) == 8) - return \"move%.b %3,%0\"; - return \"move%.w %3,%0\"; -}") - - -; -; Special case for 32-bit field in memory. This only occurs when 32-bit -; alignment of structure members is specified. -; -; The move is allowed to be odd byte aligned, because that's still faster -; than an odd byte aligned bit field instruction. -; -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 32) - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))" - "* -{ - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - return \"move%.l %1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&d") - (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && GET_CODE (operands[3]) == CONST_INT - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" - "* -{ - cc_status.flags |= CC_NOT_NEGATIVE; - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return \"bfextu %1{%b3:%b2},%0\"; - } - else - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - output_asm_insn (\"clr%.l %0\", operands); - if (GET_CODE (operands[0]) == MEM) - operands[0] = adj_offsettable_operand (operands[0], - (32 - INTVAL (operands[1])) / 8); - if (INTVAL (operands[2]) == 8) - return \"move%.b %1,%0\"; - return \"move%.w %1,%0\"; -}") - -; -; Special case for 32-bit field in memory. This only occurs when 32-bit -; alignment of structure members is specified. -; -; The move is allowed to be odd byte aligned, because that's still faster -; than an odd byte aligned bit field instruction. -; -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 32) - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))" - "* -{ - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - return \"move%.l %1,%0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && GET_CODE (operands[3]) == CONST_INT - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" - "* -{ - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return \"bfexts %1{%b3:%b2},%0\"; - } - else - operands[1] - = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); - - if (INTVAL (operands[2]) == 8) - return \"move%.b %1,%0\;extb%.l %0\"; - return \"move%.w %1,%0\;ext%.l %0\"; -}") - -;; Bit field instructions, general cases. -;; "o,d" constraint causes a nonoffsettable memref to match the "o" -;; so that its address is reloaded. - -(define_insn "extv" - [(set (match_operand:SI 0 "general_operand" "=d,d") - (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") - (match_operand:SI 2 "general_operand" "di,di") - (match_operand:SI 3 "general_operand" "di,di")))] - "TARGET_68020 && TARGET_BITFIELD" - "bfexts %1{%b3:%b2},%0") - -(define_insn "extzv" - [(set (match_operand:SI 0 "general_operand" "=d,d") - (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") - (match_operand:SI 2 "general_operand" "di,di") - (match_operand:SI 3 "general_operand" "di,di")))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - cc_status.flags |= CC_NOT_NEGATIVE; - return \"bfextu %1{%b3:%b2},%0\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") - (match_operand:SI 1 "general_operand" "di,di") - (match_operand:SI 2 "general_operand" "di,di")) - (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) - (match_operand 3 "immediate_operand" "i,i")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[3]) == CONST_INT - && (INTVAL (operands[3]) == -1 - || (GET_CODE (operands[1]) == CONST_INT - && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" - "* -{ - CC_STATUS_INIT; - return \"bfchg %0{%b2:%b1}\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") - (match_operand:SI 1 "general_operand" "di,di") - (match_operand:SI 2 "general_operand" "di,di")) - (const_int 0))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - CC_STATUS_INIT; - return \"bfclr %0{%b2:%b1}\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") - (match_operand:SI 1 "general_operand" "di,di") - (match_operand:SI 2 "general_operand" "di,di")) - (const_int -1))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - CC_STATUS_INIT; - return \"bfset %0{%b2:%b1}\"; -}") - -(define_insn "insv" - [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") - (match_operand:SI 1 "general_operand" "di,di") - (match_operand:SI 2 "general_operand" "di,di")) - (match_operand:SI 3 "general_operand" "d,d"))] - "TARGET_68020 && TARGET_BITFIELD" - "bfins %3,%0{%b2:%b1}") - -;; Now recognize bit field insns that operate on registers -;; (or at least were intended to do so). - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") - (match_operand:SI 2 "general_operand" "di") - (match_operand:SI 3 "general_operand" "di")))] - "TARGET_68020 && TARGET_BITFIELD" - "bfexts %1{%b3:%b2},%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") - (match_operand:SI 2 "general_operand" "di") - (match_operand:SI 3 "general_operand" "di")))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - cc_status.flags |= CC_NOT_NEGATIVE; - return \"bfextu %1{%b3:%b2},%0\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") - (match_operand:SI 1 "general_operand" "di") - (match_operand:SI 2 "general_operand" "di")) - (const_int 0))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - CC_STATUS_INIT; - return \"bfclr %0{%b2:%b1}\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") - (match_operand:SI 1 "general_operand" "di") - (match_operand:SI 2 "general_operand" "di")) - (const_int -1))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ - CC_STATUS_INIT; - return \"bfset %0{%b2:%b1}\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") - (match_operand:SI 1 "general_operand" "di") - (match_operand:SI 2 "general_operand" "di")) - (match_operand:SI 3 "general_operand" "d"))] - "TARGET_68020 && TARGET_BITFIELD" - "* -{ -#if 0 - /* These special cases are now recognized by a specific pattern. */ - if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) - return \"move%.w %3,%0\"; - if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) - return \"move%.b %3,%0\"; -#endif - return \"bfins %3,%0{%b2:%b1}\"; -}") - -;; Special patterns for optimizing bit-field instructions. - -(define_insn "" - [(set (cc0) - (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "general_operand" "di") - (match_operand:SI 2 "general_operand" "di")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT" - "* -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, - gen_rtx (CONST_INT, VOIDmode, - width - INTVAL (operands[2])), - operands[0], - insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return \"bftst %0{%b2:%b1}\"; -}") - - -;;; now handle the register cases -(define_insn "" - [(set (cc0) - (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d") - (match_operand:SI 1 "general_operand" "di") - (match_operand:SI 2 "general_operand" "di")))] - "TARGET_68020 && TARGET_BITFIELD - && GET_CODE (operands[1]) == CONST_INT" - "* -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, - gen_rtx (CONST_INT, VOIDmode, - width - INTVAL (operands[2])), - operands[0], - insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return \"bftst %0{%b2:%b1}\"; -}") - -(define_insn "seq" - [(set (match_operand:QI 0 "general_operand" "=d") - (eq:QI (cc0) (const_int 0)))] - "" - "* - cc_status = cc_prev_status; - OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\"); -") - -(define_insn "sne" - [(set (match_operand:QI 0 "general_operand" "=d") - (ne:QI (cc0) (const_int 0)))] - "" - "* - cc_status = cc_prev_status; - OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\"); -") - -(define_insn "sgt" - [(set (match_operand:QI 0 "general_operand" "=d") - (gt:QI (cc0) (const_int 0)))] - "" - "* - cc_status = cc_prev_status; - OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0); -") - -(define_insn "sgtu" - [(set (match_operand:QI 0 "general_operand" "=d") - (gtu:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - return \"shi %0\"; ") - -(define_insn "slt" - [(set (match_operand:QI 0 "general_operand" "=d") - (lt:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ") - -(define_insn "sltu" - [(set (match_operand:QI 0 "general_operand" "=d") - (ltu:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - return \"scs %0\"; ") - -(define_insn "sge" - [(set (match_operand:QI 0 "general_operand" "=d") - (ge:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ") - -(define_insn "sgeu" - [(set (match_operand:QI 0 "general_operand" "=d") - (geu:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - return \"scc %0\"; ") - -(define_insn "sle" - [(set (match_operand:QI 0 "general_operand" "=d") - (le:QI (cc0) (const_int 0)))] - "" - "* - cc_status = cc_prev_status; - OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0); -") - -(define_insn "sleu" - [(set (match_operand:QI 0 "general_operand" "=d") - (leu:QI (cc0) (const_int 0)))] - "" - "* cc_status = cc_prev_status; - return \"sls %0\"; ") - -;; Basic conditional jump instructions. - -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); -#else - OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); -#endif -}") - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); -#else - OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); -#endif -}") - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0); -#else - OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0); -#endif -") - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - return \"jbhi %l0\"; -#else - return \"jhi %l0\"; -#endif -") - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\"); -#else - OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\"); -#endif -") - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - return \"jbcs %l0\"; -#else - return \"jcs %l0\"; -#endif -") - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\"); -#else - OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\"); -#endif -") - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - return \"jbcc %l0\"; -#else - return \"jcc %l0\"; -#endif -") - -(define_insn "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0); -#else - OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0); -#endif -") - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -#ifdef MOTOROLA - return \"jbls %l0\"; -#else - return \"jls %l0\"; -#endif -") - -;; Negated conditional jump instructions. - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); -#else - OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); -#endif -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); -#else - OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); -#endif -}") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0); -#else - OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0); -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - return \"jbls %l0\"; -#else - return \"jls %l0\"; -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\"); -#else - OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\"); -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - return \"jbcc %l0\"; -#else - return \"jcc %l0\"; -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\"); -#else - OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\"); -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - return \"jbcs %l0\"; -#else - return \"jcs %l0\"; -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0); -#else - OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0); -#endif -") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -#ifdef MOTOROLA - return \"jbhi %l0\"; -#else - return \"jhi %l0\"; -#endif -") - -;; Unconditional and other jump instructions -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "* -#ifdef MOTOROLA - return \"jbra %l0\"; -#else - return \"jra %l0\"; -#endif -") - -;; We support two different ways of handling dispatch tables. -;; The NeXT uses absolute tables, and other machines use relative. -;; This define_expand can generate either kind. -(define_expand "tablejump" - [(parallel [(set (pc) (match_operand 0 "" "")) - (use (label_ref (match_operand 1 "" "")))])] - "" - " -{ -#ifdef CASE_VECTOR_PC_RELATIVE - operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]); -#endif -}") - -;; Jump to variable address from dispatch table of absolute addresses. -(define_insn "" - [(set (pc) (match_operand:SI 0 "register_operand" "a")) - (use (label_ref (match_operand 1 "" "")))] - "" - "* -#ifdef MOTOROLA - return \"jmp (%0)\"; -#else - return \"jmp %0@\"; -#endif -") - -;; Jump to variable address from dispatch table of relative addresses. -(define_insn "" - [(set (pc) - (plus:SI (pc) (match_operand:HI 0 "register_operand" "r"))) - (use (label_ref (match_operand 1 "" "")))] - "" - "* -#ifdef ASM_RETURN_CASE_JUMP - ASM_RETURN_CASE_JUMP; -#else -#ifdef SGS -#ifdef ASM_OUTPUT_CASE_LABEL - return \"jmp 6(%%pc,%0.w)\"; -#else -#ifdef CRDS - return \"jmp 2(pc,%0.w)\"; -#else - return \"jmp 2(%%pc,%0.w)\"; -#endif /* end !CRDS */ -#endif -#else /* not SGS */ -#ifdef MOTOROLA - return \"jmp (2,pc,%0.w)\"; -#else - return \"jmp pc@(2,%0:w)\"; -#endif -#endif -#endif -") - -;; Decrement-and-branch insns. -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:HI 0 "general_operand" "+g") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:HI (match_dup 0) - (const_int -1)))] - "" - "* -{ - CC_STATUS_INIT; - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\"; - if (GET_CODE (operands[0]) == MEM) - { -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - return \"sub%.w %#1,%0\;jbcc %l1\"; -#else - return \"subq%.w %#1,%0\;jbcc %l1\"; -#endif -#else /* not MOTOROLA */ - return \"subqw %#1,%0\;jcc %l1\"; -#endif - } -#ifdef MOTOROLA -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; -#else - return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; -#endif -#else /* not SGS_CMP_ORDER */ - return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\"; -#endif -#else /* not MOTOROLA */ - return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; -#endif -}") - -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:SI 0 "general_operand" "+g") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))] - "" - "* -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"sub%.l %#1,%0\;jbcc %l1\"; -#else - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subq%.l %#1,%0\;jbcc %l1\"; -#endif /* NO_ADDSUB_Q */ -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; -#else - return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; -#endif -#else /* not SGS_CMP_ORDER */ - return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subql %#1,%0\;jcc %l1\"; - return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; -#endif /* not MOTOROLA */ -}") - -;; Two dbra patterns that use REG_NOTES info generated by strength_reduce. - -(define_insn "" - [(set (pc) - (if_then_else - (ge (plus:HI (match_operand:HI 0 "general_operand" "+g") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:HI (match_dup 0) - (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "* -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"sub%.w %#1,%0\;jbcc %l1\"; -#else - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subq%.w %#1,%0\;jbcc %l1\"; -#endif -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; -#else - return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; -#endif -#else /* not SGS_CMP_ORDER */ - return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subqw %#1,%0\;jcc %l1\"; - return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; -#endif /* not MOTOROLA */ -}") - -(define_insn "decrement_and_branch_until_zero" - [(set (pc) - (if_then_else - (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))] - "find_reg_note (insn, REG_NONNEG, 0)" - "* -{ - CC_STATUS_INIT; -#ifdef MOTOROLA -#ifdef NO_ADDSUB_Q - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"sub%.l %#1,%0\;jbcc %l1\"; -#else - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subq%.l %#1,%0\;jbcc %l1\"; -#endif -#ifdef SGS_CMP_ORDER -#ifdef NO_ADDSUB_Q - return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; -#else - return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; -#endif -#else /* not SGS_CMP_ORDER */ - return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; -#endif /* not SGS_CMP_ORDER */ -#else /* not MOTOROLA */ - if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; - if (GET_CODE (operands[0]) == MEM) - return \"subql %#1,%0\;jcc %l1\"; - return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; -#endif /* not MOTOROLA */ -}") - - -;; For PIC calls, in order to be able to support -;; dynamic linker LAZY BINDING, all the procedure calls need to go -;; through the PLT (Procedure Linkage Table) section in PIC mode. -;; -;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra -;; operand to the jbsr statement to indicate that this call should -;; go through the PLT (why? because this is the way that Sun does it). -;; -;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it -;; will create the correct relocation entry (R_68K_PLT32) for `FUNC', -;; that tells the linker editor to create an entry for `FUNC' in PLT -;; section at link time. However, all global objects reference are still -;; done by using `OBJ@GOT'. So, the goal here is to output the function -;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'. -;; We need to have a way to differentiate these two different operands. -;; -;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate -;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs -;; to be changed to recognize function calls symbol_ref operand as a legal -;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will -;; avoid the compiler to load this symbol_ref operand into a register. -;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly -;; since the value is a PC relative offset, not a real address. -;; -;; All global objects are treated in the similar way as in SUN3. The only -;; difference is: on m68k svr4, the reference of such global object needs -;; to end with a suffix "@GOT" so the assembler and linker know to create -;; an entry for it in GOT (Global Offset Table) section. This is done in -;; m68k.c. - -;; Call subroutine with no return value. -(define_expand "call" - [(call (match_operand:QI 0 "memory_operand" "") - (match_operand:SI 1 "general_operand" ""))] - ;; Operand 1 not really used on the m68000. - - "" - " -{ - if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1; -}") - -;; This is a normal call sequence. -(define_insn "" - [(call (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "general_operand" "g"))] - ;; Operand 1 not really used on the m68000. - - "! flag_pic" - "* -#ifdef MOTOROLA - return \"jsr %0\"; -#else - return \"jbsr %0\"; -#endif -") - -;; This is a PIC call sequence. -(define_insn "" - [(call (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "general_operand" "g"))] - ;; Operand 1 not really used on the m68000. - - "flag_pic" - "* - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) -#ifdef MOTOROLA - return \"bsr %0@PLTPC\"; -#else - return \"jbsr %0,a1\"; -#endif - return \"jsr %0\"; -") - -;; Call subroutine, returning value in operand 0 -;; (which must be a hard register). -;; See comments before "call" regarding PIC calls. -(define_expand "call_value" - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "memory_operand" "") - (match_operand:SI 2 "general_operand" "")))] - ;; Operand 2 not really used on the m68000. - "" - " -{ - if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1; -}") - -;; This is a normal call_value -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "o") - (match_operand:SI 2 "general_operand" "g")))] - ;; Operand 2 not really used on the m68000. - "! flag_pic" - "* -#ifdef MOTOROLA - return \"jsr %1\"; -#else - return \"jbsr %1\"; -#endif -") - -;; This is a PIC call_value -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "o") - (match_operand:SI 2 "general_operand" "g")))] - ;; Operand 2 not really used on the m68000. - "flag_pic" - "* - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) -#ifdef MOTOROLA - return \"bsr %1@PLTPC\"; -#else - return \"jbsr %1,a1\"; -#endif - return \"jsr %1\"; -") - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "NEEDS_UNTYPED_CALL" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "") - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_insn "probe" - [(reg:SI 15)] - "NEED_PROBE" - "* -{ - operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx, - gen_rtx (CONST_INT, VOIDmode, NEED_PROBE)); - return \"tstl %a0\"; -}") - -;; Used for frameless functions which save no regs and allocate no locals. -(define_insn "return" - [(return)] - "USE_RETURN_INSN" - "* -{ - if (current_function_pops_args == 0) - return \"rts\"; - operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args); - return \"rtd %0\"; -}") - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "address_operand" "p"))] - "" - "jmp %a0") - -;; This should not be used unless the add/sub insns can't be. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=a") - (match_operand:QI 1 "address_operand" "p"))] - "" - "lea %a1,%0") - -;; This is the first machine-dependent peephole optimization. -;; It is useful when a floating value is returned from a function call -;; and then is moved into an FP register. -;; But it is mainly intended to test the support for these optimizations. - -(define_peephole - [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4))) - (set (match_operand:DF 0 "register_operand" "=f") - (match_operand:DF 1 "register_operand" "ad"))] - "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "* -{ - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"move%.l %1,%@\", xoperands); - output_asm_insn (\"move%.l %1,%-\", operands); - return \"fmove%.d %+,%0\"; -} -") - -;; Optimize a stack-adjust followed by a push of an argument. -;; This is said to happen frequently with -msoft-float -;; when there are consecutive library calls. - -(define_peephole - [(set (reg:SI 15) (plus:SI (reg:SI 15) - (match_operand:SI 0 "immediate_operand" "n"))) - (set (match_operand:SF 1 "push_operand" "=m") - (match_operand:SF 2 "general_operand" "rmfF"))] - "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" - "* -{ - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); -#ifndef NO_ADDSUB_Q - if (INTVAL (xoperands[1]) <= 8) - output_asm_insn (\"addq%.w %1,%0\", xoperands); - else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) - { - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (xoperands[1]) - 8); - output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); - } - else -#endif - if (INTVAL (xoperands[1]) <= 0x7FFF) - output_asm_insn (\"add%.w %1,%0\", xoperands); - else - output_asm_insn (\"add%.l %1,%0\", xoperands); - } - if (FP_REG_P (operands[2])) - return \"fmove%.s %2,%@\"; - return \"move%.l %2,%@\"; -}") - -;; Speed up stack adjust followed by a fullword fixedpoint push. - -(define_peephole - [(set (reg:SI 15) (plus:SI (reg:SI 15) - (match_operand:SI 0 "immediate_operand" "n"))) - (set (match_operand:SI 1 "push_operand" "=m") - (match_operand:SI 2 "general_operand" "g"))] - "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" - "* -{ - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); -#ifndef NO_ADDSUB_Q - if (INTVAL (xoperands[1]) <= 8) - output_asm_insn (\"addq%.w %1,%0\", xoperands); - else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) - { - xoperands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (xoperands[1]) - 8); - output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); - } - else -#endif - if (INTVAL (xoperands[1]) <= 0x7FFF) - output_asm_insn (\"add%.w %1,%0\", xoperands); - else - output_asm_insn (\"add%.l %1,%0\", xoperands); - } - if (operands[2] == const0_rtx) - return \"clr%.l %@\"; - return \"move%.l %2,%@\"; -}") - -;; Speed up pushing a single byte but leaving four bytes of space. - -(define_peephole - [(set (mem:QI (pre_dec:SI (reg:SI 15))) - (match_operand:QI 1 "general_operand" "dami")) - (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - rtx xoperands[4]; - - if (GET_CODE (operands[1]) == REG) - return \"move%.l %1,%-\"; - - xoperands[1] = operands[1]; - xoperands[2] - = gen_rtx (MEM, QImode, - gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, - gen_rtx (CONST_INT, VOIDmode, 3))); - xoperands[3] = stack_pointer_rtx; - output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands); - return \"\"; -}") - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") - (const_int 0)) - (set (strict_low_part (subreg:HI (match_dup 0) 0)) - (match_operand:HI 1 "general_operand" "rmn"))] - "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. - This isn't so on the 68010, but we have no alternative for it. */ - && (TARGET_68020 - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return \"clr%.w %0\"; - } - return \"move%.w %1,%0\"; -}") - -;; dbCC peepholes -;; -;; Turns -;; loop: -;; [ ... ] -;; jCC label ; abnormal loop termination -;; dbra dN, loop ; normal loop termination -;; -;; Into -;; loop: -;; [ ... ] -;; dbCC dN, loop -;; jCC label -;; -;; Which moves the jCC condition outside the inner loop for free. -;; -(define_peephole - [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" - [(cc0) (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc))) - (parallel - [(set (pc) - (if_then_else - (ge (plus:HI (match_operand:HI 0 "register_operand" "+d") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:HI (match_dup 0) - (const_int -1)))])] - "DATA_REG_P (operands[0])" - "* -{ - CC_STATUS_INIT; - output_dbcc_and_branch (operands); - return \"\"; -}") - -(define_peephole - [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" - [(cc0) (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc))) - (parallel - [(set (pc) - (if_then_else - (ge (plus:SI (match_operand:SI 0 "register_operand" "+d") - (const_int -1)) - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int -1)))])] - "DATA_REG_P (operands[0])" - "* -{ - CC_STATUS_INIT; - output_dbcc_and_branch (operands); - return \"\"; -}") - - -;; FPA multiply and add. -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y") - (match_operand:DF 2 "general_operand" "xH,y,y")) - (match_operand:DF 3 "general_operand" "xH,y,dmF")))] - "TARGET_FPA" - "@ - fpma%.d %1,%w2,%w3,%0 - fpma%.d %x1,%x2,%x3,%0 - fpma%.d %x1,%x2,%x3,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y") - (match_operand:SF 2 "general_operand" "xH,y,ydmF")) - (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))] - "TARGET_FPA" - "@ - fpma%.s %1,%w2,%w3,%0 - fpma%.s %1,%2,%3,%0 - fpma%.s %1,%2,%3,%0") - -;; FPA Multiply and subtract -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") - (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y") - (match_operand:DF 3 "general_operand" "x,y,rmF"))))] - "TARGET_FPA" - "@ - fpms%.d %3,%w2,%w1,%0 - fpms%.d %x3,%2,%x1,%0 - fpms%.d %x3,%2,%x1,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") - (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y") - (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] - "TARGET_FPA" - "@ - fpms%.s %3,%w2,%w1,%0 - fpms%.s %3,%2,%1,%0 - fpms%.s %3,%2,%1,%0") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y") - (match_operand:DF 2 "general_operand" "x,y,rmF")) - (match_operand:DF 3 "general_operand" "xH,rmF,y")))] - "TARGET_FPA" - "@ - fpmr%.d %2,%w1,%w3,%0 - fpmr%.d %x2,%1,%x3,%0 - fpmr%.d %x2,%1,%x3,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") - (match_operand:SF 2 "general_operand" "x,y,yrmF")) - (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] - "TARGET_FPA" - "@ - fpmr%.s %2,%w1,%w3,%0 - fpmr%.s %x2,%1,%x3,%0 - fpmr%.s %x2,%1,%x3,%0") - -;; FPA Add and multiply -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y") - (match_operand:DF 2 "general_operand" "x,y,rmF")) - (match_operand:DF 3 "general_operand" "xH,rmF,y")))] - "TARGET_FPA" - "@ - fpam%.d %2,%w1,%w3,%0 - fpam%.d %x2,%1,%x3,%0 - fpam%.d %x2,%1,%x3,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") - (match_operand:SF 2 "general_operand" "x,y,yrmF")) - (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] - "TARGET_FPA" - "@ - fpam%.s %2,%w1,%w3,%0 - fpam%.s %x2,%1,%x3,%0 - fpam%.s %x2,%1,%x3,%0") - -;;FPA Subtract and multiply -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y") - (match_operand:DF 2 "general_operand" "x,y,rmF")) - (match_operand:DF 3 "general_operand" "xH,rmF,y")))] - "TARGET_FPA" - "@ - fpsm%.d %2,%w1,%w3,%0 - fpsm%.d %x2,%1,%x3,%0 - fpsm%.d %x2,%1,%x3,%0") - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=x,y,y") - (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") - (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y") - (match_operand:DF 3 "general_operand" "x,y,rmF"))))] - "TARGET_FPA" - "@ - fpsm%.d %3,%w2,%w1,%0 - fpsm%.d %x3,%2,%x1,%0 - fpsm%.d %x3,%2,%x1,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y") - (match_operand:SF 2 "general_operand" "x,y,yrmF")) - (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] - "TARGET_FPA" - "@ - fpsm%.s %2,%w1,%w3,%0 - fpsm%.s %x2,%1,%x3,%0 - fpsm%.s %x2,%1,%x3,%0") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=x,y,y") - (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") - (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y") - (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] - "TARGET_FPA" - "@ - fpsm%.s %3,%w2,%w1,%0 - fpsm%.s %x3,%2,%x1,%0 - fpsm%.s %x3,%2,%x1,%0") - -(define_insn "tstxf" - [(set (cc0) - (match_operand:XF 0 "nonimmediate_operand" "fm"))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; - return \"ftst%.x %0\"; -}") - - -(define_expand "cmpxf" - [(set (cc0) - (compare (match_operand:XF 0 "general_operand" "f,mG") - (match_operand:XF 1 "general_operand" "fmG,f")))] - "TARGET_68881" - " -{ - if (CONSTANT_P (operands[0])) - operands[0] = force_const_mem (XFmode, operands[0]); - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); -}") - -(define_insn "" - [(set (cc0) - (compare (match_operand:XF 0 "nonimmediate_operand" "f,mG") - (match_operand:XF 1 "nonimmediate_operand" "fmG,f")))] - "TARGET_68881" - "* -{ - cc_status.flags = CC_IN_68881; -#ifdef SGS_CMP_ORDER - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return \"fcmp%.x %0,%1\"; - else - return \"fcmp%.x %0,%f1\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.x %1,%f0\"; -#else - if (REG_P (operands[0])) - { - if (REG_P (operands[1])) - return \"fcmp%.x %1,%0\"; - else - return \"fcmp%.x %f1,%0\"; - } - cc_status.flags |= CC_REVERSED; - return \"fcmp%.x %f0,%1\"; -#endif -}") - -(define_insn "extendsfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f") - (float_extend:XF (match_operand:SF 1 "general_operand" "f,m")))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return \"\"; - } - return \"f%$move%.x %1,%0\"; - } - if (FP_REG_P (operands[0])) - return \"f%$move%.s %f1,%0\"; - return \"fmove%.x %f1,%0\"; -}") - - -(define_insn "extenddfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f") - (float_extend:XF - (match_operand:DF 1 "general_operand" "f,m")))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - /* Extending float to double in an fp-reg is a no-op. - NOTICE_UPDATE_CC has already assumed that the - cc will be set. So cancel what it did. */ - cc_status = cc_prev_status; - return \"\"; - } - return \"fmove%.x %1,%0\"; - } - if (FP_REG_P (operands[0])) - return \"f%&move%.d %f1,%0\"; - return \"fmove%.x %f1,%0\"; -}") - -(define_insn "truncxfdf2" - [(set (match_operand:DF 0 "general_operand" "=m,!r") - (float_truncate:DF - (match_operand:XF 1 "general_operand" "f,f")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[0])) - { - output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"move%.l %+,%0\"; - } - return \"fmove%.d %f1,%0\"; -}") - -(define_insn "truncxfsf2" - [(set (match_operand:SF 0 "general_operand" "=dm") - (float_truncate:SF - (match_operand:XF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.s %f1,%0") - -(define_insn "floatsixf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (float:XF (match_operand:SI 1 "general_operand" "dmi")))] - "TARGET_68881" - "fmove%.l %1,%0") - -(define_insn "floathixf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (float:XF (match_operand:HI 1 "general_operand" "dmn")))] - "TARGET_68881" - "fmove%.w %1,%0") - -(define_insn "floatqixf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (float:XF (match_operand:QI 1 "general_operand" "dmn")))] - "TARGET_68881" - "fmove%.b %1,%0") - -(define_insn "ftruncxf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (fix:XF (match_operand:XF 1 "general_operand" "fFm")))] - "TARGET_68881" - "* -{ - if (FP_REG_P (operands[1])) - return \"fintrz%.x %f1,%0\"; - return \"fintrz%.x %f1,%0\"; -}") - -(define_insn "fixxfqi2" - [(set (match_operand:QI 0 "general_operand" "=dm") - (fix:QI (match_operand:XF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.b %1,%0") - -(define_insn "fixxfhi2" - [(set (match_operand:HI 0 "general_operand" "=dm") - (fix:HI (match_operand:XF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.w %1,%0") - -(define_insn "fixxfsi2" - [(set (match_operand:SI 0 "general_operand" "=dm") - (fix:SI (match_operand:XF 1 "general_operand" "f")))] - "TARGET_68881" - "fmove%.l %1,%0") - -(define_expand "addxf3" - [(set (match_operand:XF 0 "general_operand" "") - (plus:XF (match_operand:XF 1 "general_operand" "") - (match_operand:XF 2 "general_operand" "")))] - "TARGET_68881" - " -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -}") - -(define_insn "" - [(set (match_operand:XF 0 "general_operand" "=f") - (plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0") - (match_operand:XF 2 "nonimmediate_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"fadd%.x %2,%0\"; - return \"fadd%.x %f2,%0\"; -}") - -(define_expand "subxf3" - [(set (match_operand:XF 0 "general_operand" "") - (minus:XF (match_operand:XF 1 "general_operand" "") - (match_operand:XF 2 "general_operand" "")))] - "TARGET_68881" - " -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -}") - -(define_insn "" - [(set (match_operand:XF 0 "general_operand" "=f") - (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0") - (match_operand:XF 2 "nonimmediate_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"fsub%.x %2,%0\"; - return \"fsub%.x %f2,%0\"; -}") - -(define_expand "mulxf3" - [(set (match_operand:XF 0 "general_operand" "") - (mult:XF (match_operand:XF 1 "general_operand" "") - (match_operand:XF 2 "general_operand" "")))] - "TARGET_68881" - " -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -}") - -(define_insn "" - [(set (match_operand:XF 0 "general_operand" "=f") - (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0") - (match_operand:XF 2 "nonimmediate_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"fmul%.x %2,%0\"; - return \"fmul%.x %f2,%0\"; -}") - -(define_expand "divxf3" - [(set (match_operand:XF 0 "general_operand" "") - (div:XF (match_operand:XF 1 "general_operand" "") - (match_operand:XF 2 "general_operand" "")))] - "TARGET_68881" - " -{ - if (CONSTANT_P (operands[1])) - operands[1] = force_const_mem (XFmode, operands[1]); - if (CONSTANT_P (operands[2])) - operands[2] = force_const_mem (XFmode, operands[2]); -}") - -(define_insn "" - [(set (match_operand:XF 0 "general_operand" "=f") - (div:XF (match_operand:XF 1 "nonimmediate_operand" "0") - (match_operand:XF 2 "nonimmediate_operand" "fmG")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[2])) - return \"fdiv%.x %2,%0\"; - return \"fdiv%.x %f2,%0\"; -}") - -(define_insn "negxf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"fneg%.x %1,%0\"; - return \"fneg%.x %f1,%0\"; -}") - -(define_insn "absxf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))] - "TARGET_68881" - "* -{ - if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) - return \"fabs%.x %1,%0\"; - return \"fabs%.x %f1,%0\"; -}") - -(define_insn "sqrtxf2" - [(set (match_operand:XF 0 "general_operand" "=f") - (sqrt:XF (match_operand:DF 1 "nonimmediate_operand" "fm")))] - "TARGET_68881" - "* -{ - return \"fsqrt%.x %1,%0\"; -}") diff --git a/gnu/usr.bin/gcc2/arch/m68k/tconfig.h b/gnu/usr.bin/gcc2/arch/m68k/tconfig.h deleted file mode 100644 index 851a73871a5..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/tconfig.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Configuration for GNU C-compiler for Motorola 68000 family. - Copyright (C) 1987 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: tconfig.h,v 1.1.1.1 1995/10/18 08:39:21 deraadt Exp $ -*/ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -#define HOST_WORDS_BIG_ENDIAN - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If compiled with GNU C, use the built-in alloca */ -#ifdef __GNUC__ -/* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ -#define alloca(x) __builtin_alloca(x) -#endif diff --git a/gnu/usr.bin/gcc2/arch/m68k/tm.h b/gnu/usr.bin/gcc2/arch/m68k/tm.h deleted file mode 100644 index 32d591de8f6..00000000000 --- a/gnu/usr.bin/gcc2/arch/m68k/tm.h +++ /dev/null @@ -1,170 +0,0 @@ -/* $Id: tm.h,v 1.1.1.1 1995/10/18 08:39:21 deraadt Exp $ */ - -#include -#include "m68k/m68k.h" - -/* See m68k.h. 7 means 68020 with 68881. */ - -#define TARGET_DEFAULT 7 - -/* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified. - This will control the use of inline 68881 insns in certain macros. */ - -#define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__ -D__HAVE_FPU__} %{posix:-D_POSIX_SOURCE}" - -/* Names to predefine in the preprocessor for this target machine. */ - -#define CPP_PREDEFINES "-Dm68k -Dmc68000 -Dmc68020 -Dunix -D__NetBSD__ -D__m68k__" - -/* Specify -k to assembler for PIC code generation. */ - -#define ASM_SPEC "%{fpic:-k} %{fPIC:-k}" - -/* Support -static, -symbolic and -shared options (at least minimally). - Also use -dp when doing dynamic linking. Don't include a startup - file when linking a shared library. */ - -#define LINK_SPEC \ - "%{static:-Bstatic} %{shared:-Bshareable} %{symbolic:-Bsymbolic} \ - %{!static:%{!shared:-dp}}" - -#define STARTFILE_SPEC \ - "%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}\ - %{!p:%{static:scrt0.o%s}%{!static:crt0.o%s}}}}" - -/* No more libg.a; no libraries if making shared object */ - -#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" - -/* Make gcc agree with */ - -#define SIZE_TYPE "unsigned int" -#define PTRDIFF_TYPE "int" -#undef WCHAR_TYPE -#define WCHAR_TYPE "short unsigned int" -#define WCHAR_UNSIGNED 1 -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 16 - -/* NetBSD does have atexit. */ - -#define HAVE_ATEXIT - -/* Every structure or union's size must be a multiple of 2 bytes. */ - -#define STRUCTURE_SIZE_BOUNDARY 16 - -/* This is BSD, so it wants DBX format. */ - -#define DBX_DEBUGGING_INFO - -/* Do not break .stabs pseudos into continuations. */ - -#define DBX_CONTIN_LENGTH 0 - -/* This is the char to use for continuation (in case we need to turn - continuation back on). */ - -#define DBX_CONTIN_CHAR '?' - -/* Don't use the `xsfoo;' construct in DBX output; this system - doesn't support it. */ - -#define DBX_NO_XREFS - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* - * Some imports from svr4.h in support of shared libraries. - */ - -#define HANDLE_SYSV_PRAGMA - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" -#define WEAK_ASM_OP ".weak" -#define SET_ASM_OP ".set" - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - if (!flag_inhibit_size_directive) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) - diff --git a/gnu/usr.bin/gcc2/arch/move-if-change b/gnu/usr.bin/gcc2/arch/move-if-change deleted file mode 100644 index df1258fe36f..00000000000 --- a/gnu/usr.bin/gcc2/arch/move-if-change +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# Like mv $1 $2, but if the files are the same, just delete $1. -# Status is 0 if $2 is changed, 1 otherwise. -# $Id: move-if-change,v 1.1.1.1 1995/10/18 08:39:16 deraadt Exp $ -if -test -r $2 -then -if -cmp -s $1 $2 -then -echo $2 is unchanged -rm -f $1 -else -mv -f $1 $2 -fi -else -mv -f $1 $2 -fi diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/README b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/README deleted file mode 100644 index a189ca500fd..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/README +++ /dev/null @@ -1,19 +0,0 @@ -These are the files that I used to make cc1 and cc1plus from gcc-2.5.8 -for NetBSD/pc532. They are included to allow you to build a compiler -yourself. - -The files netbsd.h, ns32k.c, ns32k.md, and xm-netbsd.h should be put -in the directory gcc-2.5.8/config/ns32k. The file configure should be -put in the directory gcc-2.5.8. - -You may have to change the files glimits.h, gstddef.h, gvarargs.h, and -gstdarg.h. In file gxxxx.h adding an "#include " and a "#if 0" -at the beginning of the file and a "#endif" at the end of the file. - -To build: - - a) "configure .... ns32k-pc532-netbsd" - - b) make cc1 cc1plus - - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/configure b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/configure deleted file mode 100644 index 2cc90d19ccc..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/configure +++ /dev/null @@ -1,1929 +0,0 @@ -#!/bin/sh -# Configuration script for GNU CC -# Copyright (C) 1988, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - -# -# Shell script to create proper links to machine-dependent files in -# preparation for compiling gcc. -# -# Options: --srcdir=DIR specifies directory where sources are. -# --host=HOST specifies host configuration. -# --target=TARGET specifies target configuration. -# --build=TARGET specifies configuration of machine you are -# using to compile GCC. -# --prefix=DIR specifies directory to install in. -# --local-prefix=DIR specifies directory to put local ./include in. -# --exec-prefix=DIR specifies directory to install executables in. -# --with-gnu-ld arrange to work with GNU ld. -# --with-gnu-as arrange to work with GAS. -# --with-stabs arrange to use stabs instead of host debug format. -# --with-elf arrange to use elf instead of host debug format. -# --nfp assume system has no FPU. -# -# If configure succeeds, it leaves its status in config.status. -# If configure fails after disturbing the status quo, -# config.status is removed. -# - -progname=$0 - -# Default --srcdir to the directory where the script is found, -# if a directory was specified. -# The second sed call is to convert `.//configure' to `./configure'. -srcdir=`echo $0 | sed 's|//|/|' | sed 's|/[^/]*$||'` -if [ x$srcdir = x$0 ] -then -srcdir= -fi - -host= - -# Default prefix to /usr/local. -prefix=/usr/local - -# local_prefix specifies where to find the directory /usr/local/include -# We don't use $(prefix) for this -# because we always want GCC to search /usr/local/include -# even if GCC is installed somewhere other than /usr/local. -# Think THREE TIMES before specifying any other value for this! -# DO NOT make this use $prefix! -local_prefix=/usr/local -# Default is to let the Makefile set exec_prefix from $(prefix) -exec_prefix='$(prefix)' - -remove=rm -hard_link=ln -symbolic_link='ln -s' -copy=cp - -# Record all the arguments, to write them in config.status. -arguments=$* - -#for Test -#remove="echo rm" -#hard_link="echo ln" -#symbolic_link="echo ln -s" - -target= -host= -build= - -for arg in $*; -do - case $next_arg in - --srcdir) - srcdir=$arg - next_arg= - ;; - --host) - host=$arg - next_arg= - ;; - --target) - target=$arg - next_arg= - ;; - --build) - build=$arg - next_arg= - ;; - --prefix) - prefix=$arg - next_arg= - ;; - --local-prefix) - local_prefix=$arg - next_arg= - ;; - --exec-prefix) - exec_prefix=$arg - next_arg= - ;; - *) - case $arg in - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) - next_arg=--srcdir - ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) - srcdir=`echo $arg | sed 's/-*s[a-z]*=//'` - ;; - -host | --host | --hos | --ho | --h) - next_arg=--host - ;; - -host=* | --host=* | --hos=* | --ho=* | --h=*) - host=`echo $arg | sed 's/-*h[a-z]*=//'` - ;; - -target | --target | --targe | --targ | --tar | --ta | --t) - next_arg=--target - ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target=`echo $arg | sed 's/-*t[a-z]*=//'` - ;; - -build | --build | --buil | --bui | --bu | --b) - next_arg=--build - ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) - build=`echo $arg | sed 's/-*b[a-z]*=//'` - ;; - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - next_arg=--prefix - ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=`echo $arg | sed 's/-*p[a-z]*=//'` - ;; - -local-prefix | --local-prefix | --local-prefi | --local-pref | --local-pre \ - | --local-pr | --local-p | --local- | --local | --loc | --lo | --l) - next_arg=--local-prefix - ;; - -local-prefix=* | --local-prefix=* | --local-prefi=* | --local-pref=* \ - | --local-pre=* | --local-pr=* | --local-p=* | --local-=* | --local=* \ - | --loc=* | --lo=* | --l=*) - local_prefix=`echo $arg | sed 's/-*l[-a-z]*=//'` - ;; - -exec-prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre \ - | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) - next_arg=--exec-prefix - ;; - -exec-prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* \ - | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* \ - | --exe=* | --ex=* | --e=*) - exec_prefix=`echo $arg | sed 's/-*e[-a-z]*=//'` - ;; - -with-gnu-ld | --with-gnu-ld | --with-gnu-l) - gnu_ld=yes - ;; - -gas | --gas | --ga | --g | -with-gnu-as | --with-gnu-as | -with-gnu-a) - gas=yes - ;; - -nfp | --nfp | --nf | --n) - nfp=yes - ;; - -with-stabs | -with-stab | -with-sta | -with-st | -with-s \ - | --with-stabs | --with-stab | --with-sta | --with-st | --with-s \ - | -stabs | -stab | -sta | -st \ - | --stabs | --stab | --sta | --st) - stabs=yes - ;; - -with-elf | -with-el | -with-se \ - | --with-elf | --with-el | --with-e \ - | -elf | -el | -e \ - |--elf | --el | --e) - elf=yes - ;; - -with-* | --with-*) ;; #ignored - -enable-* | --enable-*) ;; #ignored - -x | --x) ;; # ignored - --verbose) ;; # ignored for now - -*) - echo "Invalid option \`$arg'" 1>&2 - exit 1 - ;; - *) -# Allow configure HOST TARGET - if [ x$host = x ] - then - host=$target - fi - target=$arg - ;; - esac - esac -done - -# Find the source files, if location was not specified. -if [ x$srcdir = x ] -then - srcdirdefaulted=1 - srcdir=. - if [ ! -r tree.c ] - then - srcdir=.. - fi -fi - -if [ ! -r ${srcdir}/tree.c ] -then - if [ x$srcdirdefaulted = x ] - then - echo "$progname: Can't find compiler sources in \`${srcdir}'" 1>&2 - else - echo "$progname: Can't find compiler sources in \`.' or \`..'" 1>&2 - fi - exit 1 -fi - -if [ -r ${srcdir}/config.status ] && [ x$srcdir != x. ] -then - echo "$progname: \`configure' has been run in \`${srcdir}'" 1>&2 - exit 1 -fi - -# Complain if an arg is missing -if [ x$target = x ] -then - # This way of testing the result of a command substitution is - # defined by Posix.2 (section 3.9.1) as well as traditional shells. - if target=`${srcdir}/config.guess` ; then - echo "Configuring for a ${target} host." 1>&2 - else - echo 'Config.guess failed to determine the host type. You need to specify one.' 1>&2 - echo "\ -Usage: `basename $progname` [--host=HOST] [--build=BUILD] - [--prefix=DIR] [--local-pref=DIR] [--exec-pref=DIR] - [--with-gnu-as] [--with-gnu-ld] [--with-stabs] [--with-elf] [--nfp] TARGET" 1>&2 - echo "Where HOST, TARGET and BUILD are three-part configuration names " 1>&2 - if [ -r config.status ] - then - tail +2 config.status 1>&2 - fi - exit 1 - fi -fi - -# Default other arg -if [ x$host = x ] -then - host=$target -fi -# If $build was not specified, use $host. -if [ x$build = x ] -then - build=$host -fi - -build_xm_file= -host_xm_file= -host_xmake_file= -host_broken_install= -host_install_headers_dir=install-headers-tar -host_truncate_target= - -# Validate the specs, and canonicalize them. -canon_build=`/bin/sh $srcdir/config.sub $build` || exit 1 -canon_host=`/bin/sh $srcdir/config.sub $host` || exit 1 -canon_target=`/bin/sh $srcdir/config.sub $target` || exit 1 - -# Decode the host machine, then the target machine. -# For the host machine, we save the xm_file variable as host_xm_file; -# then we decode the target machine and forget everything else -# that came from the host machine. -for machine in $canon_build $canon_host $canon_target; do - - cpu_type= - xm_file= - tm_file= - out_file= - xmake_file= - tmake_file= - header_files= - extra_passes= - # Set this to force installation and use of collect2. - use_collect2= - # Set this to override the default target model. - target_cpu_default= - # Set this to force use of install.sh. - broken_install= - # Set this to control which fixincludes program to use. - fixincludes=fixincludes - # Set this to control how the header file directory is installed. - install_headers_dir=install-headers-tar - # Set this to a non-empty list of args to pass to cpp if the target - # wants its .md file passed through cpp. - cpp_md_flags= - # Set this if directory names should be truncated to 14 characters. - truncate_target= - - case $machine in - # Support site-specific machine types. - *local*) - cpu_type=`echo $machine | sed -e 's/-.*//'` - rest=`echo $machine | sed -e "s/$cpu_type-//"` - xm_file=${cpu_type}/xm-$rest.h - tm_file=${cpu_type}/$rest.h - if [ -f $srcdir/config/${cpu_type}/x-$rest ] ; \ - then xmake_file=${cpu_type}/x-$rest; \ - else true; \ - fi - if [ -f $srcdir/config/${cpu_type}/t-$rest ] ; \ - then tmake_file=${cpu_type}/t-$rest; \ - else true; \ - fi - ;; - vax-*-bsd*) # vaxen running BSD - use_collect2=yes - ;; - vax-*-ultrix*) # vaxen running ultrix - tm_file=vax/ultrix.h - use_collect2=yes - ;; - vax-*-vms*) # vaxen running VMS - xm_file=vax/xm-vms.h - tm_file=vax/vms.h - ;; - vax-*-sysv*) # vaxen running system V - xm_file=vax/xm-vaxv.h - tm_file=vax/vaxv.h - ;; -# This hasn't been upgraded to GCC 2. -# tahoe-harris-*) # Harris tahoe, using COFF. -# tm_file=tahoe/harris.h -# ;; -# tahoe-*-bsd*) # tahoe running BSD -# ;; - i370-*-mvs*) - cpu_type=i370 - tm_file=i370/mvs.h - xm_file=i370/xm-mvs.h - out_file=i370/mvs370.c - ;; - i[34]86-*-osfrose*) # 386 using OSF/rose -# The following line (and similar below) is not redundant since this can -# be used for i486 or i386. - cpu_type=i386 - if [ x$elf = xyes ] - then - tm_file=i386/osfelf.h - use_collect2= - else - tm_file=i386/osfrose.h - use_collect2=yes - fi - xmake_file=i386/x-osfrose - tmake_file=i386/t-osfrose - ;; - i[34]86-sequent-bsd*) # 80386 from Sequent - cpu_type=i386 - use_collect2=yes - if [ x$gas = xyes ] - then - tm_file=i386/seq-gas.h - else - tm_file=i386/sequent.h - fi - ;; - i[34]86-next-*) - cpu_type=i386 - tm_file=i386/next.h - out_file=i386/next.c - xm_file=i386/xm-next.h - tmake_file=i386/t-next - xmake_file=i386/x-next - ;; - i[34]86-*-bsd*) - cpu_type=i386 - tm_file=i386/386bsd.h -# tmake_file=t-libc-ok -# Next line turned off because both 386BSD and BSD/386 use GNU ld. -# use_collect2=yes - ;; - i[34]86-*-mach*) - cpu_type=i386 - tm_file=i386/mach.h -# tmake_file=t-libc-ok - use_collect2=yes - ;; - i[34]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system - cpu_type=i386 - xm_file=i386/xm-sco.h - xmake_file=i386/x-sco4 - fixincludes=fixinc.sco - broken_install=yes - install_headers_dir=install-headers-cpio - if [ x$stabs = xyes ] - then - tm_file=i386/sco4dbx.h - tmake_file=i386/t-svr3dbx - else - tm_file=i386/sco4.h - tmake_file=i386/t-sco - fi - ;; - i[34]86-*-sco*) # 80386 running SCO system - cpu_type=i386 - xm_file=i386/xm-sco.h - xmake_file=i386/x-sco - broken_install=yes - install_headers_dir=install-headers-cpio - if [ x$stabs = xyes ] - then - tm_file=i386/scodbx.h - tmake_file=i386/t-svr3dbx - else - tm_file=i386/sco.h - tmake_file=i386/t-sco - fi - truncate_target=yes - ;; - i[34]86-*-isc*) # 80386 running ISC system - cpu_type=i386 - xm_file=i386/xm-isc.h - case $machine in - i[34]86-*-isc3*) - xmake_file=i386/x-isc3 - ;; - *) - xmake_file=i386/x-isc - ;; - esac - echo $xmake_file - if [ x$gas = xyes ] - then - if [ x$stabs = xyes ] - then - tm_file=i386/iscdbx.h - tmake_file=i386/t-svr3dbx - else - # iscgas.h, a nonexistent file, was used here. - tm_file=i386/isccoff.h - tmake_file=i386/t-isc - fi - else - tm_file=i386/isccoff.h - tmake_file=i386/t-isc - fi - install_headers_dir=install-headers-cpio - broken_install=yes - ;; - i[34]86-ibm-aix*) # IBM PS/2 running AIX - cpu_type=i386 - if [ x$gas = xyes ] - then - tm_file=i386/aix386.h - tmake_file=i386/t-aix - else - tm_file=i386/aix386ng.h - use_collect2=yes - fi - xm_file=i386/xm-aix.h - xmake_file=i386/x-aix - broken_install=yes - fixincludes=fixinc.ps2 - ;; - i386-sun-sunos*) # Sun i386 roadrunner - xm_file=i386/xm-sun.h - tm_file=i386/sun.h - use_collect2=yes - ;; - i[34]86-*-linux*) # Intel 80386's running Linux - cpu_type=i386 - xm_file=i386/xm-linux.h - xmake_file=i386/x-linux - if [ x$elf = xyes ] - then - tm_file=i386/linuxelf.h - else - tm_file=i386/linux.h - fi - fixincludes=Makefile.in #On Linux, the headers are ok already. - broken_install=yes - ;; - i486-ncr-sysv4*) # NCR 3000 - i486 running system V.4 - cpu_type=i386 - xm_file=i386/xm-sysv4.h - xmake_file=i386/x-ncr3000 - tm_file=i386/sysv4.h - tmake_file=t-svr4 - ;; - i[34]86-*-sysv4*) # Intel 80386's running system V.4 - cpu_type=i386 - xm_file=i386/xm-sysv4.h - tm_file=i386/sysv4.h - tmake_file=t-svr4 - xmake_file=x-svr4 - ;; - i[34]86-sequent-sysv*) # Sequent 80386's running system V - cpu_type=i386 - xm_file=i386/xm-sysv3.h - xmake_file=i386/x-sysv3 - tm_file=i386/seq-sysv3.h - tmake_file=t-svr3 - fixincludes=fixinc.svr4 - broken_install=yes - ;; - i[34]86-*-sysv*) # Intel 80386's running system V - cpu_type=i386 - xm_file=i386/xm-sysv3.h - xmake_file=i386/x-sysv3 - if [ x$gas = xyes ] - then - if [ x$stabs = xyes ] - then - tm_file=i386/svr3dbx.h - tmake_file=i386/t-svr3dbx - else - tm_file=i386/svr3gas.h - tmake_file=t-svr3 - fi - else - tm_file=i386/sysv3.h - tmake_file=t-svr3 - fi - ;; - i[34]86-*-solaris2* | i[34]86-*-sunos5*) - cpu_type=i386 - xm_file=i386/xm-sysv4.h - tm_file=i386/sol2.h - tmake_file=i386/t-sol2 - xmake_file=x-svr4 - fixincludes=fixinc.svr4 - broken_install=yes - ;; - i[34]86-*-lynxos) - cpu_type=i386 - tm_file=i386/lynx.h - xm_file=xm-lynx.h - xmake_file=x-lynx - # ??? Due to bugs in /bin/sh, it is too much trouble to get - # the fixincludes script to run correctly, so just don't do it. - # There are only a very few very minor things that need fixing - # anyways. Also, a number of headers files do not have final - # newlines, which causes them to be incorrectly editted by sed. - fixincludes=Makefile.in - ;; - i860-*-osf*) # Intel Paragon XP/S, OSF/1AD - xm_file=i860/xm-paragon.h - tm_file=i860/paragon.h - tmake_file=t-osf - broken_install=yes - ;; - i860-*-mach*) - xm_file=i860/xm-i860.h - tm_file=i860/mach.h - tmake_file=t-libc-ok - ;; - i860-*-sysv3*) - xm_file=i860/xm-sysv3.h - xmake_file=i860/x-sysv3 - tm_file=i860/sysv3.h - tmake_file=t-svr3 - ;; - i860-*-sysv4*) - xm_file=i860/xm-sysv4.h - xmake_file=i860/x-sysv4 - tm_file=i860/sysv4.h - tmake_file=t-svr4 - ;; - i860-alliant-*) # Alliant FX/2800 - xm_file=i860/xm-fx2800.h - xmake_file=i860/x-fx2800 - tm_file=i860/fx2800.h - tmake_file=i860/t-fx2800 - ;; - i860-*-bsd*) - if [ x$gas = xyes ] - then - tm_file=i860/bsd-gas.h - else - tm_file=i860/bsd.h - fi - use_collect2=yes - ;; - elxsi-elxsi-*) - use_collect2=yes - ;; - sparc-tti-*) - tm_file=sparc/pbd.h - xm_file=sparc/xm-pbd.h - ;; - sparc-*-sunos4*) - tm_file=sparc/sparc.h - use_collect2=yes - ;; - sparc-*-sunos3*) - tm_file=sparc/sun4o3.h - use_collect2=yes - ;; - sparc-*-bsd*) - tm_file=sparc/bsd.h - ;; - sparc-*-sysv4*) - xm_file=sparc/xm-sysv4.h - tm_file=sparc/sysv4.h - tmake_file=t-svr4 - xmake_file=sparc/x-sysv4 - ;; - sparc-*-solaris2* | sparc-*-sunos5*) - xm_file=sparc/xm-sol2.h - tm_file=sparc/sol2.h - tmake_file=sparc/t-sol2 - xmake_file=sparc/x-sysv4 - fixincludes=fixinc.svr4 - broken_install=yes - ;; - sparc-*-lynxos) - tm_file=sparc/lynx.h - xm_file=xm-lynx.h - xmake_file=x-lynx - # ??? Due to bugs in /bin/sh, it is too much trouble to get - # the fixincludes script to run correctly, so just don't do it. - # There are only a very few very minor things that need fixing - # anyways. Also, a number of headers files do not have final - # newlines, which causes them to be incorrectly editted by sed. - fixincludes=Makefile.in - ;; - sparclite-*-*) - cpu_type=sparc - tm_file=sparc/lite.h - use_collect2=yes - ;; - m68k-cbm-sysv4*) # Commodore variant of V.4. - tm_file=m68k/amix.h - xm_file=m68k/xm-amix.h - xmake_file=m68k/x-amix - tmake_file=t-svr4 - header_files=math-68881.h - ;; - m68k-*-sysv4*) # Motorola m68k's running system V.4 - tm_file=m68k/m68kv4.h - xm_file=m68k/xm-m68kv.h - tmake_file=t-svr4 - header_files=math-68881.h - ;; - m68k-bull-sysv*) # Bull DPX/2 - if [ x$gas = xyes ] - then - if [ x$stabs = xyes ] - then - tm_file=m68k/dpx2cdbx.h - else - tm_file=m68k/dpx2g.h - fi - else - tm_file=m68k/dpx2.h - fi - xm_file=m68k/xm-m68kv.h - xmake_file=m68k/x-dpx2 - use_collect2=yes - header_files=math-68881.h - ;; - m68k-next-*) - tm_file=m68k/next.h - out_file=m68k/next.c - xm_file=m68k/xm-next.h - tmake_file=m68k/t-next - xmake_file=m68k/x-next - header_files=math-68881.h - ;; - m68k-sun-sunos3*) - if [ x$nfp = xyes ] - then - tm_file=m68k/sun3n3.h - else - tm_file=m68k/sun3o3.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-sun-sunos*) # For SunOS 4 (the default). - if [ x$nfp = xyes ] - then - tm_file=m68k/sun3n.h - else - tm_file=m68k/sun3.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-sun-mach*) - tm_file=m68k/sun3mach.h - use_collect2=yes - header_files=math-68881.h - ;; - m68k-tti-*) - tm_file=m68k/pbb.h - xm_file=m68k/xm-m68kv.h - header_files=math-68881.h - ;; - m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7. - xm_file=m68k/xm-hp320.h - if [ x$gas = xyes ] - then - xmake_file=m68k/x-hp320g - tmake_file=m68k/t-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hpux7.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - header_files=math-68881.h - ;; - m68k-hp-hpux*) # HP 9000 series 300 - xm_file=m68k/xm-hp320.h - if [ x$gas = xyes ] - then - xmake_file=m68k/x-hp320g - tmake_file=m68k/t-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp320.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - header_files=math-68881.h - ;; - m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd - tm_file=m68k/hp3bsd44.h - xmake_file=m68k/x-hp3bsd44 - use_collect2=yes - header_files=math-68881.h - ;; - m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix - tm_file=m68k/hp3bsd.h - use_collect2=yes - header_files=math-68881.h - ;; - m68k-isi-bsd*) - if [ x$nfp = xyes ] - then - tm_file=m68k/isi-nfp.h - else - tm_file=m68k/isi.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-sony-newsos3*) - if [ x$gas = xyes ] - then - tm_file=m68k/news3gas.h - else - tm_file=m68k/news3.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-sony-bsd* | m68k-sony-newsos*) - if [ x$gas = xyes ] - then - tm_file=m68k/newsgas.h - else - tm_file=m68k/news.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-altos-sysv*) # Altos 3068 - if [ x$gas = xyes ] - then - xm_file=m68k/xm-altos3068.h - tm_file=m68k/altos3068.h - else - echo "The Altos is supported only with the GNU assembler" 1>&2 - exit 1 - fi - header_files=math-68881.h - ;; - m68k-motorola-sysv*) - tm_file=m68k/mot3300.h - xm_file=m68k/xm-mot3300.h - xmake_file=m68k/x-alloca-c - use_collect2=yes - header_files=math-68881.h - ;; - m68k-crds-unos*) - xm_file=m68k/xm-crds.h - xmake_file=m68k/x-crds - tm_file=m68k/crds.h - broken_install=yes - use_collect2=yes - header_files=math-68881.h - ;; - m68k-apollo-*) - xmake_file=m68k/x-apollo68 - tm_file=m68k/apollo68.h - use_collect2=yes - header_files=math-68881.h - ;; - m68k-plexus-sysv*) - tm_file=m68k/plexus.h - xm_file=m68k/xm-plexus.h - use_collect2=yes - header_files=math-68881.h - ;; - m68k-ncr-sysv*) # NCR Tower 32 SVR3 - tm_file=m68k/tower-as.h - xm_file=m68k/xm-tower.h - xmake_file=m68k/x-tower - tmake_file=t-svr3 - header_files=math-68881.h - ;; - m68k-*-sysv3*) # Motorola m68k's running system V.3 - xm_file=m68k/xm-m68kv.h - xmake_file=m68k/x-m68kv - tmake_file=t-svr3 - header_files=math-68881.h - ;; - m68000-sun-sunos3*) - cpu_type=m68k - tm_file=m68k/sun2.h - use_collect2=yes - header_files=math-68881.h - ;; - m68000-sun-sunos4*) - cpu_type=m68k - tm_file=m68k/sun2o4.h - use_collect2=yes - header_files=math-68881.h - ;; - m68000-hp-hpux*) # HP 9000 series 300 - cpu_type=m68k - xm_file=m68k/xm-hp320.h - if [ x$gas = xyes ] - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp310g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp310.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - header_files=math-68881.h - ;; - m68000-hp-bsd*) # HP 9000/200 running BSD - cpu_type=m68k - tm_file=m68k/hp2bsd.h - xmake_file=m68k/x-hp2bsd - use_collect2=yes - header_files=math-68881.h - ;; - m68000-att-sysv*) - cpu_type=m68k - xm_file=m68k/xm-3b1.h - if [ x$gas = xyes ] - then - tm_file=m68k/3b1g.h - else - tm_file=m68k/3b1.h - fi - use_collect2=yes - header_files=math-68881.h - ;; - m68k-*-lynxos) - tm_file=m68k/lynx.h - xm_file=xm-lynx.h - xmake_file=x-lynx - # ??? Due to bugs in /bin/sh, it is too much trouble to get - # the fixincludes script to run correctly, so just don't do it. - # There are only a very few very minor things that need fixing - # anyways. Also, a number of headers files do not have final - # newlines, which causes them to be incorrectly editted by sed. - fixincludes=Makefile.in - header_files=math-68881.h - ;; - m68000-convergent-sysv*) - cpu_type=m68k - xm_file=m68k/xm-3b1.h - tm_file=m68k/ctix.h - use_collect2=yes - header_files=math-68881.h - ;; - ns32k-sequent-bsd*) - tm_file=ns32k/sequent.h - use_collect2=yes - ;; - ns32k-encore-bsd*) - tm_file=ns32k/encore.h - use_collect2=yes - ;; -# This has not been updated to GCC 2. -# ns32k-ns-genix*) -# xm_file=ns32k/xm-genix.h -# xmake_file=ns32k/x-genix -# tm_file=ns32k/genix.h -# broken_install=yes -# use_collect2=yes -# ;; - ns32k-merlin-*) - tm_file=ns32k/merlin.h - use_collect2=yes - ;; - ns32k-tek6100-bsd*) - tm_file=ns32k/tek6100.h - broken_install=yes - use_collect2=yes - ;; - ns32k-tek6200-bsd*) - tm_file=ns32k/tek6200.h - broken_install=yes - use_collect2=yes - ;; - ns32k-pc532-mach*) - tm_file=ns32k/pc532-mach.h - use_collect2=yes - ;; - ns32k-pc532-minix*) - tm_file=ns32k/pc532-min.h - xm_file=ns32k/xm-pc532-min.h - use_collect2=yes - ;; - ns32k-pc532-netbsd*) -# was tm_file=ns32k/pc532-bsd.h - tm_file=ns32k/netbsd.h -# was no xm_file - xm_file=ns32k/xm-netbsd.h - host_xmake_file=ns32k/x-bsd - use_collect2=no - fixincludes= - ;; - m88k-*-luna*) - tm_file=m88k/luna.h - if [ x$gas = xyes ] - then - tmake_file=m88k/t-luna-gas - else - tmake_file=m88k/t-luna - fi - ;; - m88k-dg-dgux*) - tm_file=m88k/dgux.h - xmake_file=m88k/x-dgux - broken_install=yes - if [ x$gas = xyes ] - then - tmake_file=m88k/t-dgux-gas - else - tmake_file=m88k/t-dgux - fi - fixincludes=fixinc.dgux - ;; - m88k-mot*-sysv4*) #added by kev for Motorola delta machines - tm_file=m88k/mot-sysv4.h #added by kev - xmake_file=m88k/x-sysv4 #added by kev - tmake_file=m88k/t-sysv4 #added by kev - ;; #added by kev - m88k-*-sysv4*) - tm_file=m88k/sysv4.h - xmake_file=m88k/x-sysv4 - tmake_file=m88k/t-sysv4 - ;; - m88k-dolphin-sysv3*) - tm_file=m88k/dolph.h - xm_file=m88k/xm-sysv3.h - xmake_file=m88k/x-dolph - if [ x$gas = xyes ] - then - tmake_file=m88k/t-m88k-gas - fi - ;; - - m88k-tektronix-sysv3) - tm_file=m88k/tekXD88.h - xm_file=m88k/xm-sysv3.h - xmake_file=m88k/x-tekXD88 - if [ x$gas = xyes ] - then - tmake_file=m88k/t-m88k-gas - fi - ;; - - m88k-*-sysv3*) - tm_file=m88k/sysv3.h - xm_file=m88k/xm-sysv3.h - xmake_file=m88k/x-sysv3 - if [ x$gas = xyes ] - then - tmake_file=m88k/t-m88k-gas - fi - ;; -# This hasn't been upgraded to GCC 2. -# fx80-alliant-*) # Alliant FX/80 -# ;; - arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) - tm_file=arm/riscix1-1.h - use_collect2=yes - ;; - arm-*-riscix*) # Acorn RISC machine - if [ x$gas = xyes ] - then - tm_file=arm/rix-gas.h - else - tm_file=arm/riscix.h - fi - use_collect2=yes - ;; - arm-*-*) # generic version - ;; - c1-convex-*) # Convex C1 - cpu_type=convex - tm_file=convex/convex1.h - use_collect2=yes - ;; - c2-convex-*) # Convex C2 - cpu_type=convex - tm_file=convex/convex2.h - use_collect2=yes - ;; - c32-convex-*) - cpu_type=convex - tm_file=convex/convex32.h # Convex C32xx - use_collect2=yes - ;; - c34-convex-*) - cpu_type=convex - tm_file=convex/convex34.h # Convex C34xx - use_collect2=yes - ;; - c38-convex-*) - cpu_type=convex - tm_file=convex/convex38.h # Convex C38xx - use_collect2=yes - ;; - mips-sgi-irix5*) # SGI System V.4., IRIX 5 - tm_file=mips/iris5.h - xm_file=mips/xm-iris5.h - broken_install=yes - fixincludes=Makefile.in - xmake_file=mips/x-iris - # mips-tfile doesn't work yet - tmake_file=mips/t-mips-gas - ;; - mips-sgi-irix4loser*) # Mostly like a MIPS. - if [ x$stabs = xyes ]; then - tm_file=mips/iris4gl.h - else - tm_file=mips/iris4loser.h - fi - xm_file=mips/xm-iris4.h - broken_install=yes - xmake_file=mips/x-iris - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-sgi-irix4*) # Mostly like a MIPS. - if [ x$stabs = xyes ]; then - tm_file=mips/iris4-gdb.h - else - tm_file=mips/iris4.h - fi - xm_file=mips/xm-iris4.h - broken_install=yes - xmake_file=mips/x-iris - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-sgi-*) # Mostly like a MIPS. - if [ x$stabs = xyes ]; then - tm_file=mips/iris3-gdb.h - else - tm_file=mips/iris3.h - fi - xm_file=mips/xm-iris3.h - broken_install=yes - xmake_file=mips/x-iris3 - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-*-ultrix*) # Decstation. - if [ x$stabs = xyes ]; then - tm_file=mips/ultrix-gdb.h - else - tm_file=mips/ultrix.h - fi - xmake_file=mips/x-ultrix - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-dec-osfrose*) # Decstation running OSF/1 reference port with OSF/rose. - tm_file=mips/osfrose.h - xmake_file=mips/x-osfrose - tmake_file=mips/t-osfrose - use_collect2=yes - ;; - mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL - if [ x$stabs = xyes ]; then - tm_file=mips/dec-gosf1.h - else - tm_file=mips/dec-osf1.h - fi - xmake_file=mips/x-dec-osf1 - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-dec-bsd*) # Decstation running 4.4 BSD - tm_file=mips/dec-bsd.h - xmake_file= - tmake_file= - fixincludes= - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. - if [ x$stabs = xyes ]; then - tm_file=mips/news4-gdb.h - else - tm_file=mips/news4.h - fi - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - xmake_file=mips/x-sony - ;; - mips-sony-sysv*) # Sony NEWS 3800 with NEWSOS5.0. - # That is based on svr4. - # t-svr4 is not right because this system doesn't use ELF. - if [ x$stabs = xyes ]; then - tm_file=mips/news5-gdb.h - else - tm_file=mips/news5.h - fi - xm_file=mips/xm-news.h - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips-*-riscos[56789]bsd* | mips-*-riscos[56789]-bsd*) - if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 5.0 - tm_file=mips/bsd-5-gdb.h - else - tm_file=mips/bsd-5.h - fi - if [ x$gas = xyes ] - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - fixincludes=fixinc.mips - broken_install=yes - ;; - mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd* \ - | mips-*-riscos-bsd* | mips-*-riscos[1234]-bsd*) - if [ x$stabs = xyes ]; then # MIPS BSD 4.3, RISC-OS 4.0 - tm_file=mips/bsd-4-gdb.h - else - tm_file=mips/bsd-4.h - fi - if [ x$gas = xyes ] - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - broken_install=yes - ;; - mips-*-riscos[56789]sysv4* | mips-*-riscos[56789]-sysv4*) - if [ x$stabs = xyes ]; then # MIPS System V.4., RISC-OS 5.0 - tm_file=mips/svr4-5-gdb.h - else - tm_file=mips/svr4-5.h - fi - xm_file=mips/xm-sysv4.h - xmake_file=mips/x-sysv - if [ x$gas = xyes ] - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - fixincludes=fixinc.mips - broken_install=yes - ;; - mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4* \ - | mips-*-riscos[1234]-sysv4* | mips-*-riscos-sysv4*) - if [ x$stabs = xyes ]; then # MIPS System V.4. RISC-OS 4.0 - tm_file=mips/svr4-4-gdb.h - else - tm_file=mips/svr4-4.h - fi - xm_file=mips/xm-sysv.h - xmake_file=mips/x-sysv - if [ x$gas = xyes ] - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - broken_install=yes - ;; - mips-*-riscos[56789]sysv* | mips-*-riscos[56788]-sysv*) - if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 5.0 - tm_file=mips/svr3-5-gdb.h - else - tm_file=mips/svr3-5.h - fi - xm_file=mips/xm-sysv.h - xmake_file=mips/x-sysv - if [ x$gas = xyes ] - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - fixincludes=fixinc.mips - broken_install=yes - ;; - mips-*-sysv* | mips-*riscos*sysv*) - if [ x$stabs = xyes ]; then # MIPS System V.3, RISC-OS 4.0 - tm_file=mips/svr3-4-gdb.h - else - tm_file=mips/svr3-4.h - fi - xm_file=mips/xm-sysv.h - xmake_file=mips/x-sysv - if [ x$gas = xyes ] - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - broken_install=yes - ;; - mips-*riscos[56789]*) # Default MIPS RISC-OS 5.0. - if [ x$stabs = xyes ]; then - tm_file=mips/mips-5-gdb.h - else - tm_file=mips/mips-5.h - fi - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - fixincludes=fixinc.mips - broken_install=yes - ;; - mips-*-*) # Default MIPS RISC-OS 4.0. - if [ x$stabs = xyes ]; then - tm_file=mips/mips-4-gdb.h - else - tm_file=mips/mips.h - fi - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - pyramid-*-*) - cpu_type=pyr - xmake_file=pyr/x-pyr - use_collect2=yes - ;; -# This hasn't been upgraded to GCC 2. -# tron-*-*) -# cpu_type=gmicro -# use_collect2=yes -# ;; - a29k-*-bsd*) - tm_file=a29k/unix.h - xm_file=a29k/xm-unix.h - xmake_file=a29k/x-unix - use_collect2=yes - ;; - a29k-*-*) # Default a29k environment. - use_collect2=yes - ;; - romp-*-aos*) - use_collect2=yes - ;; - romp-*-mach*) - xmake_file=romp/x-mach - use_collect2=yes - ;; - rs6000-*-mach*) - xm_file=rs6000/xm-mach.h - tm_file=rs6000/mach.h - xmake_file=rs6000/x-mach - use_collect2=yes - ;; - rs6000-ibm-aix3.[01]*) - tm_file=rs6000/aix31.h - xmake_file=rs6000/x-aix31 - use_collect2=yes - ;; - rs6000-ibm-aix*) - use_collect2=yes - ;; - powerpc-ibm-aix*) - cpu_type=rs6000 - tm_file=rs6000/powerpc.h - use_collect2=yes - ;; - hppa1.1-*-mach*) - cpu_type=pa - tm_file=pa/pa1-utahmach.h - use_collect2=yes - ;; - hppa1.0-*-mach*) - cpu_type=pa - tm_file=pa/pa-utahmach.h - use_collect2=yes - ;; - hppa1.1-*-bsd*) - cpu_type=pa - tm_file=pa/pa1.h - use_collect2=yes - ;; - hppa1.0-*-bsd*) - cpu_type=pa - use_collect2=yes - ;; - hppa1.0-*-hpux7*) - cpu_type=pa - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa-gux7.h - else - tm_file=pa/pa-hpux7.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux8.0[0-2]*) - cpu_type=pa - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa-ghpux.h - else - tm_file=pa/pa-oldas.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux8.0[0-2]*) - cpu_type=pa - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa1-ghpux.h - else - tm_file=pa/pa1-oldas.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux*) - cpu_type=pa - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa1-ghpux.h - else - tm_file=pa/pa1-hpux.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux*) - cpu_type=pa - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa-ghpux.h - else - tm_file=pa/pa-hpux.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hiux*) - cpu_type=pa - xm_file=pa/xm-pahiux.h - xmake_file=pa/x-pa-hiux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa1-ghiux.h - else - tm_file=pa/pa1-hiux.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hiux*) - cpu_type=pa - xm_file=pa/xm-pahiux.h - xmake_file=pa/x-pa-hiux - tmake_file=t-libc-ok - if [ x$gas = xyes ] - then - tm_file=pa/pa-ghiux.h - else - tm_file=pa/pa-hiux.h - fi - broken_install=yes - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - we32k-att-sysv*) - cpu_type=we32k - use_collect2=yes - ;; - h8300-*-*) - cpu_type=h8300 - ;; - sh-*-*) - cpu_type=sh - ;; - alpha-dec-osf1.2) - extra_passes="mips-tfile mips-tdump" - tm_file=alpha/osf12.h - broken_install=yes - use_collect2=yes - ;; - alpha-*-osf*) - if [ x$stabs = xyes ] - then - tm_file=alpha/alpha-gdb.h - fi - if [ x$gas != xyes ] - then - extra_passes="mips-tfile mips-tdump" - fi - broken_install=yes - use_collect2=yes - ;; - i960-*-*) # Default i960 environment. - use_collect2=yes - ;; - clipper-intergraph-clix*) - broken_install=yes - cpu_type=clipper - xm_file=clipper/xm-clix.h - tm_file=clipper/clix.h - tmake_file=clipper/t-clix - xmake_file=clipper/x-clix - install_headers_dir=install-headers-cpio - ;; - *) - echo "Configuration $machine not supported" 1>&2 - exit 1 - ;; - esac - - case $machine in - *-*-sysv4*) - fixincludes=fixinc.svr4 - xmake_try_sysv=x-sysv - broken_install=yes - install_headers_dir=install-headers-cpio - ;; - *-*-sysv*) - broken_install=yes - install_headers_dir=install-headers-cpio - ;; - esac - - # Distinguish i386 from i486. - # Also, do not run mips-tfile on MIPS if using gas. - case $machine in - i486-*-*) - target_cpu_default=2 - ;; - mips-*-*) - if [ x$gas = xyes ] - then - target_cpu_default=16 - fi - ;; - esac - - # No need for collect2 if we have the GNU linker. - case x$gnu_ld in - xyes) - use_collect2= - ;; - esac - -# Default certain vars that apply to both host and target in turn. - if [ x$cpu_type = x ] - then cpu_type=`echo $machine | sed 's/-.*$//'` - fi - -# Save data on machine being used to compile GCC in build_xm_file. -# Save data on host machine in vars host_xm_file and host_xmake_file. - if [ x$pass1done = x ] - then - if [ x$xm_file = x ] - then build_xm_file=$cpu_type/xm-$cpu_type.h - else build_xm_file=$xm_file - fi - pass1done=yes - else - if [ x$pass2done = x ] - then - if [ x$xm_file = x ] - then host_xm_file=$cpu_type/xm-$cpu_type.h - else host_xm_file=$xm_file - fi - if [ x$xmake_file = x ] - then xmake_file=$cpu_type/x-$cpu_type - fi - host_xmake_file=$xmake_file - host_broken_install=$broken_install - host_install_headers_dir=$install_headers_dir - host_truncate_target=$truncate_target - pass2done=yes - fi - fi -done - -# Default the target-machine variables that were not explicitly set. -if [ x$tm_file = x ] -then tm_file=$cpu_type/$cpu_type.h; fi - -if [ x$header_files = x ] -then header_files=; fi - -if [ x$xm_file = x ] -then xm_file=$cpu_type/xm-$cpu_type.h; fi - -md_file=$cpu_type/$cpu_type.md - -if [ x$out_file = x ] -then out_file=$cpu_type/$cpu_type.c; fi - -if [ x$tmake_file = x ] -then tmake_file=$cpu_type/t-$cpu_type -fi - -# Set up the list of links to be made. -# $links is the list of link names, and $files is the list of names to link to. -files="$host_xm_file $tm_file $out_file $xm_file $build_xm_file $md_file" -links="config.h tm.h aux-output.c tconfig.h hconfig.h" - -if [ -n "${cpp_md_flags}" ] ; then - links="$links md.pre-cpp" -else - links="$links md" -fi - -rm -f config.bak -if [ -f config.status ]; then mv -f config.status config.bak; fi - -# Make the links. -while [ -n "$files" ] -do - # set file to car of files, files to cdr of files - set $files; file=$1; shift; files=$* - set $links; link=$1; shift; links=$* - - if [ ! -r ${srcdir}/config/$file ] - then - echo "$progname: cannot create a link \`$link'," 1>&2 - echo "since the file \`config/$file' does not exist" 1>&2 - exit 1 - fi - - $remove -f $link - # Make a symlink if possible, otherwise try a hard link - $symbolic_link ${srcdir}/config/$file $link 2>/dev/null || $hard_link ${srcdir}/config/$file $link || $copy ${srcdir}/config/$file $link - - if [ ! -r $link ] - then - echo "$progname: unable to link \`$link' to \`${srcdir}/config/$file'" 1>&2 - exit 1 - fi - echo "Linked \`$link' to \`${srcdir}/config/$file'" -done - -# Truncate the target if necessary -if [ x$host_truncate_target != x ]; then - target=`echo $target | sed -e 's/\(..............\).*/\1/'` -fi - -# Create Makefile.tem from Makefile.in. -# Make it set VPATH if necessary so that the sources are found. -# Also change its value of srcdir. -# Also create a .gdbinit file which runs the one in srcdir -# and tells GDB to look there for source files. -case $srcdir in -.) - rm -f Makefile.tem - cp Makefile.in Makefile.tem - chmod +w Makefile.tem - ;; -*) - rm -f Makefile.tem - echo "VPATH = ${srcdir}" \ - | cat - ${srcdir}/Makefile.in \ - | sed "s@^srcdir = \.@srcdir = ${srcdir}@" > Makefile.tem - rm -f .gdbinit - echo "dir ." > .gdbinit - echo "dir ${srcdir}" >> .gdbinit - echo "source ${srcdir}/.gdbinit" >> .gdbinit - ;; -esac - -# Conditionalize the makefile for this host machine. -if [ -f ${srcdir}/config/${host_xmake_file} ] -then - rm -f Makefile.xx - sed -e "/####host/ r ${srcdir}/config/${host_xmake_file}" Makefile.tem > Makefile.xx - echo "Merged ${host_xmake_file}." - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -else -# Say in the makefile that there is no host_xmake_file, -# by using a name which (when interpreted relative to $srcdir/config) -# will duplicate another dependency: $srcdir/Makefile.in. - host_xmake_file=../Makefile.in -fi - -# Add a definition for INSTALL if system wants one. -# This substitutes for lots of x-* files. -if [ x$host_broken_install = x ] -then true -else - rm -f Makefile.xx - abssrcdir=`cd ${srcdir}; pwd` - sed "s|^INSTALL = .*|INSTALL = ${abssrcdir}/install.sh -c|" Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Set EXTRA_HEADERS according to header_files. -# This substitutes for lots of t-* files. -if [ "x$header_files" = x ] -then true -else - rm -f Makefile.xx - sed "s/^EXTRA_HEADERS =/EXTRA_HEADERS = $header_files/" Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Set EXTRA_PASSES according to extra_passes. -# This substitutes for lots of t-* files. -if [ "x$extra_passes" = x ] -then true -else - rm -f Makefile.xx - sed "s/^EXTRA_PASSES =/EXTRA_PASSES = $extra_passes/" Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Add a definition of USE_COLLECT2 if system wants one. -# Also tell toplev.c what to do. -# This substitutes for lots of t-* files. -if [ x$use_collect2 = x ] -then true -else - rm -f Makefile.xx - (echo "USE_COLLECT2 = ld"; echo "MAYBE_USE_COLLECT2 = -DUSE_COLLECT2")\ - | cat - Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Add -DTARGET_CPU_DEFAULT for toplev.c if system wants one. -# This substitutes for lots of *.h files. -if [ x$target_cpu_default = x ] -then true -else - rm -f Makefile.xx -# This used cat, but rfg@netcom.com said that ran into NFS bugs. - sed -e "/^# Makefile for GNU C compiler./c\\ -MAYBE_TARGET_DEFAULT = -DTARGET_CPU_DEFAULT=$target_cpu_default\\ -\# Makefile for GNU C compiler." Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Add a CPP_MD dependence if the real md file is in md.pre-cpp. -if [ -n "${cpp_md_flags}" ] ; then - rm -f Makefile.xx - (echo "CPP_MD = md.pre-cpp cpp" ; echo "CPP_MD_FLAGS = $cpp_md_flags" ; echo "MD_FILE = md") \ - | cat - Makefile.tem > Makefile.xx - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -fi - -# Conditionalize the makefile for this target machine. -if [ -f ${srcdir}/config/${tmake_file} ] -then - rm -f Makefile.xx - sed -e "/####target/ r ${srcdir}/config/${tmake_file}" Makefile.tem > Makefile.xx - echo "Merged ${tmake_file}." - rm -f Makefile.tem - mv Makefile.xx Makefile.tem -else -# Say in the makefile that there is no tmake_file, -# by using a name which (when interpreted relative to $srcdir/config) -# will duplicate another dependency: $srcdir/Makefile.in. - tmake_file=../Makefile.in -fi - -# Get the version number. -version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${srcdir}/version.c` - -# Remove all formfeeds, since some Makes get confused by them. -# Also arrange to give the variables `target', `host_xmake_file', -# `tmake_file', `prefix', `local_prefix', `exec_prefix', `FIXINCLUDES' -# and `INSTALL_HEADERS_DIR' values in the Makefile from the values -# they have in this script. -rm -f Makefile.xx -sed -e "s/ //" -e "s/^target=.*$/target=${target}/" \ - -e "s|^xmake_file=.*$|xmake_file=${host_xmake_file}|" \ - -e "s|^tmake_file=.*$|tmake_file=${tmake_file}|" \ - -e "s|^version=.*$|version=${version}|" \ - -e "s|^prefix[ ]*=.*|prefix = $prefix|" \ - -e "s|^local_prefix[ ]*=.*|local_prefix = $local_prefix|" \ - -e "s|^exec_prefix[ ]*=.*|exec_prefix = $exec_prefix|" \ - -e "s|^FIXINCLUDES[ ]*=.*|FIXINCLUDES = $fixincludes|" \ - -e "s|^INSTALL_HEADERS_DIR[ ]*=.*$|INSTALL_HEADERS_DIR = ${host_install_headers_dir}|" \ - Makefile.tem > Makefile.xx -rm -f Makefile.tem -mv Makefile.xx Makefile.tem - -# Install Makefile for real, after making final changes. -# Define macro CROSS_COMPILE in compilation if this is a cross-compiler. -# Also use all.cross instead of all.internal, and add cross-make to Makefile. -if [ x$host = x$target ] -then - rm -f Makefile - if [ x$host = x$build ] - then - mv Makefile.tem Makefile - else -# When build gcc with cross-compiler, we need to fix a -# few things. - echo "build= $build" > Makefile - sed -e "/####build/ r ${srcdir}/build-make" Makefile.tem >> Makefile - rm -f Makefile.tem Makefile.xx - fi -else - rm -f Makefile - echo "CROSS=-DCROSS_COMPILE" > Makefile - sed -e "/####cross/ r ${srcdir}/cross-make" Makefile.tem >> Makefile - rm -f Makefile.tem Makefile.xx -fi - -echo "Created \`Makefile'." - -if [ xx${vint} != xx ] -then - vintmsg=" (vint)" -fi - -# Describe the chosen configuration in config.status. -# Make that file a shellscript which will reestablish the same configuration. -echo "#!/bin/sh -# GCC was configured as follows: -${srcdir}/configure" $arguments > config.new -echo echo host=$canon_host target=$canon_target build=$canon_build >> config.new -chmod a+x config.new -if [ -f config.bak ] && cmp config.bak config.new >/dev/null 2>/dev/null; -then - mv -f config.bak config.status - rm -f config.new -else - mv -f config.new config.status - rm -f config.bak -fi - -if [ x$canon_host = x$canon_target ] -then - echo "Links are now set up for target $canon_target." -else - echo "Links are now set up for host $canon_host and target $canon_target." -fi - -exit 0 diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/netbsd.h b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/netbsd.h deleted file mode 100644 index c7ff97c5e65..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/netbsd.h +++ /dev/null @@ -1,239 +0,0 @@ -/* Configuration for a ns32532 running NetBSD as the target machine. - Copyright (C) 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: netbsd.h,v 1.1.1.1 1995/10/18 08:39:23 deraadt Exp $ -*/ - -#include -#include "ns32k/ns32k.h" - -/* Compile for the floating point unit & 32532 by default; - Don't assume SB is zero */ - -#define TARGET_DEFAULT 57 - -/* 32-bit alignment for efficiency */ - -#undef POINTER_BOUNDARY -#define POINTER_BOUNDARY 32 - -/* 32-bit alignment for efficiency */ - -#undef FUNCTION_BOUNDARY -#define FUNCTION_BOUNDARY 32 - -/* 32532 spec says it can handle any alignment. Rumor from tm-ns32k.h - tells this might not be actually true (but it's for 32032, perhaps - National has fixed the bug for 32532). You might have to change this - if the bug still exists. */ - -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT 0 - -/* Use pc relative addressing whenever possible, - it's more efficient than absolute (ns32k.c) - You have to fix a bug in gas 1.38.1 to make this work with gas, - patch available from jkp@cs.hut.fi. - (NetBSD's gas version has this patch already applied) */ - -#define PC_RELATIVE - -/* Operand of bsr or jsr should be just the address. */ - -#define CALL_MEMREF_IMPLICIT - -/* movd insns may have floating point constant operands. */ - -#define MOVD_FLOAT_OK - -/* Every address needs to use a base reg. */ - -#define BASE_REG_NEEDED - -/* Names to predefine in the preprocessor for this target machine. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dns32532 -Dns32000 -Dns32k -Dpc532 -Dunix -D__NetBSD__ -D__ns32k__" - - -/* Specify -k to assembler for pic generation. PIC needs -K too. */ - -#define ASM_SPEC "%{fpic:-k} %{fPIC:-k -K}" - -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -#define STARTFILE_SPEC \ - "%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}" - -/* No more libg.a; no libraries if making shared object */ - -#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" - -/* Make gcc agree with */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "int" - -#define WCHAR_UNSIGNED 0 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -/* This is BSD, so it wants DBX format. */ - -#define DBX_DEBUGGING_INFO - -/* Do not break .stabs pseudos into continuations. */ - -#define DBX_CONTIN_LENGTH 0 - -/* This is the char to use for continuation (in case we need to turn - continuation back on). */ - -#define DBX_CONTIN_CHAR '?' - -/* Don't use the `xsfoo;' construct in DBX output; this system - doesn't support it. */ - -#define DBX_NO_XREFS - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ - -#undef PCC_STATIC_STRUCT_RETURN -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* - * Some imports from svr4.h in support of shared libraries. - */ - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" -#define WEAK_ASM_OP ".weak" - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - size_directive_output = 0; \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ - { \ - size_directive_output = 1; \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Output the size directive for a decl in rest_of_decl_compilation - in the case where we did not do so before the initializer. - Once we find the error_mark_node, we know that the value of - size_directive_output was set - by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ - -#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ -do { \ - char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - if (!flag_inhibit_size_directive \ - && !size_directive_output \ - && DECL_SIZE (DECL) \ - && ! AT_END && TOP_LEVEL \ - && DECL_INITIAL (DECL) == error_mark_node) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, name); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - } while (0) - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.c b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.c deleted file mode 100644 index 1bce6f92733..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.c +++ /dev/null @@ -1,900 +0,0 @@ -/* Subroutines for assembler code output on the NS32000. - Copyright (C) 1988 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Some output-actions in ns32k.md need these. */ -#include -#include "assert.h" -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" - -#ifdef OSF_OS -int ns32k_num_files = 0; -#endif - -void -trace (s, s1, s2) - char *s, *s1, *s2; -{ - fprintf (stderr, s, s1, s2); -} - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ - -int -hard_regno_mode_ok (regno, mode) - int regno; - enum machine_mode mode; -{ - switch (mode) - { - case QImode: - case HImode: - case PSImode: - case SImode: - case PDImode: - case VOIDmode: - case BLKmode: - if (regno < 8 || regno == 16 || regno == 17) - return 1; - else - return 0; - - case DImode: - if (regno < 8 && (regno & 1) == 0) - return 1; - else - return 0; - - case SFmode: - case SCmode: - if (TARGET_32081) - { - if (regno < 16) - return 1; - else - return 0; - } - else - { - if (regno < 8) - return 1; - else - return 0; - } - - case DFmode: - case DCmode: - if ((regno & 1) == 0) - { - if (TARGET_32081) - { - if (regno < 16) - return 1; - else - return 0; - } - else - { - if (regno < 8) - return 1; - else - return 0; - } - } - else - return 0; - } - - /* Used to abort here, but simply saying "no" handles TImode - much better. */ - return 0; -} - -/* ADDRESS_COST calls this. This function is not optimal - for the 32032 & 32332, but it probably is better than - the default. */ - -int -calc_address_cost (operand) - rtx operand; -{ - int i; - int cost = 0; - - if (GET_CODE (operand) == MEM) - cost += 3; - if (GET_CODE (operand) == MULT) - cost += 2; -#if 0 - if (GET_CODE (operand) == REG) - cost += 1; /* not really, but the documentation - says different amount of registers - shouldn't return the same costs */ -#endif - switch (GET_CODE (operand)) - { - case REG: - case CONST: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case LABEL_REF: - case POST_DEC: - case PRE_DEC: - break; - case MULT: - case MEM: - case PLUS: - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++) - { - cost += calc_address_cost (XEXP (operand, i)); - } - default: - break; - } - return cost; -} - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -enum reg_class -secondary_reload_class (class, mode, in) - enum reg_class class; - enum machine_mode mode; - rtx in; -{ - int regno = true_regnum (in); - - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - - /* We can place anything into GENERAL_REGS and can put GENERAL_REGS - into anything. */ - if (class == GENERAL_REGS || (regno >= 0 && regno < 8)) - return NO_REGS; - - /* Constants, memory, and FP registers can go into FP registers. */ - if ((regno == -1 || (regno >= 8 && regno < 16)) && (class == FLOAT_REGS)) - return NO_REGS; - -#if 0 /* This isn't strictly true (can't move fp to sp or vice versa), - so it's cleaner to use PREFERRED_RELOAD_CLASS - to make the right things happen. */ - if (regno >= 16 && class == GEN_AND_MEM_REGS) - return NO_REGS; -#endif - - /* Otherwise, we need GENERAL_REGS. */ - return GENERAL_REGS; -} -/* Generate the rtx that comes from an address expression in the md file */ -/* The expression to be build is BASE[INDEX:SCALE]. To recognize this, - scale must be converted from an exponent (from ASHIFT) to a - multiplier (for MULT). */ -rtx -gen_indexed_expr (base, index, scale) - rtx base, index, scale; -{ - rtx addr; - - /* This generates an illegal addressing mode, if BASE is - fp or sp. This is handled by PRINT_OPERAND_ADDRESS. */ - if (GET_CODE (base) != REG && GET_CODE (base) != CONST_INT) - base = gen_rtx (MEM, SImode, base); - addr = gen_rtx (MULT, SImode, index, - gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (scale))); - addr = gen_rtx (PLUS, SImode, base, addr); - return addr; -} - -/* Return 1 if OP is a valid operand of mode MODE. This - predicate rejects operands which do not have a mode - (such as CONST_INT which are VOIDmode). */ -int -reg_or_mem_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (GET_MODE (op) == mode - && (GET_CODE (op) == REG - || GET_CODE (op) == SUBREG - || GET_CODE (op) == MEM)); -} - -/* Return the best assembler insn template - for moving operands[1] into operands[0] as a fullword. */ - -static char * -singlemove_string (operands) - rtx *operands; -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) <= 7 - && INTVAL (operands[1]) >= -8) - return "movqd %1,%0"; - return "movd %1,%0"; -} - -char * -output_move_double (operands) - rtx *operands; -{ - enum anon1 { REGOP, OFFSOP, PUSHOP, CNSTOP, RNDOP } optype0, optype1; - rtx latehalf[2]; - - /* First classify both operands. */ - - if (REG_P (operands[0])) - optype0 = REGOP; - else if (offsettable_memref_p (operands[0])) - optype0 = OFFSOP; - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - optype0 = PUSHOP; - else - optype0 = RNDOP; - - if (REG_P (operands[1])) - optype1 = REGOP; - else if (CONSTANT_P (operands[1]) -/* || GET_CODE (operands[1]) == CONST_DOUBLE*/) - optype1 = CNSTOP; - else if (offsettable_memref_p (operands[1])) - optype1 = OFFSOP; - else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) - optype1 = PUSHOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP) - abort (); - - /* Ok, we can do one word at a time. - Normally we do the low-numbered word first, - but if either operand is autodecrementing then we - do the high-numbered word first. - - In either case, set up in LATEHALF the operands to use - for the high-numbered word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ - - if (optype0 == REGOP) - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (operands[0], 4); - else - latehalf[0] = operands[0]; - - if (optype1 == REGOP) - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (operands[1], 4); - else if (optype1 == CNSTOP) - { -/* if (GET_CODE (operands[1]) == CONST_DOUBLE) */ - split_double (operands[1], &operands[1], &latehalf[1]); -/* else - latehalf[1] = const0_rtx; */ - } - else - latehalf[1] = operands[1]; - - /* If insn is effectively movd N(sp),tos then we will do the - high word first. We should use the adjusted operand 1 (which is N+4(sp)) - for the low word as well, to compensate for the first decrement of sp. - Given this, it doesn't matter which half we do "first". */ - if (optype0 == PUSHOP - && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM - && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) - operands[1] = latehalf[1]; - - /* If one or both operands autodecrementing, - do the two words, high-numbered first. */ - else if (optype0 == PUSHOP || optype1 == PUSHOP) - { - output_asm_insn (singlemove_string (latehalf), latehalf); - return singlemove_string (operands); - } - - /* If the first move would clobber the source of the second one, - do them in the other order. */ - - /* Overlapping registers. */ - if (optype0 == REGOP && optype1 == REGOP - && REGNO (operands[0]) == REGNO (latehalf[1])) - { - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Do low-numbered word. */ - return singlemove_string (operands); - } - /* Loading into a register which overlaps a register used in the address. */ - else if (optype0 == REGOP && optype1 != REGOP - && reg_overlap_mentioned_p (operands[0], operands[1])) - { - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) - && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) - { - /* If both halves of dest are used in the src memory address, - load the destination address into the low reg (operands[0]). - Then it works to load latehalf first. */ - rtx xops[2]; - xops[0] = XEXP (operands[1], 0); - xops[1] = operands[0]; - output_asm_insn ("addr %a0,%1", xops); - operands[1] = gen_rtx (MEM, DImode, operands[0]); - latehalf[1] = adj_offsettable_operand (operands[1], 4); - /* The first half has the overlap, Do the late half first. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Then clobber. */ - return singlemove_string (operands); - } - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) - { - /* The first half has the overlap, Do the late half first. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Then clobber. */ - return singlemove_string (operands); - } - } - - /* Normal case. Do the two words, low-numbered first. */ - - output_asm_insn (singlemove_string (operands), operands); - - operands[0] = latehalf[0]; - operands[1] = latehalf[1]; - return singlemove_string (operands); -} - -int -check_reg (oper, reg) - rtx oper; - int reg; -{ - register int i; - - if (oper == 0) - return 0; - switch (GET_CODE(oper)) - { - case REG: - return (REGNO(oper) == reg) ? 1 : 0; - case MEM: - return check_reg(XEXP(oper, 0), reg); - case PLUS: - case MULT: - return check_reg(XEXP(oper, 0), reg) || check_reg(XEXP(oper, 1), reg); - } - return 0; -} - -/* Returns 1 if OP contains a global symbol reference */ - -int -global_symbolic_reference_mentioned_p (op, f) - rtx op; - int f; -{ - register char *fmt; - register int i; - - if (GET_CODE (op) == SYMBOL_REF) - { - if (! SYMBOL_REF_FLAG (op)) - return 1; - else - return 0; - } - else if (f && GET_CODE (op) != CONST) - return 0; - - fmt = GET_RTX_FORMAT (GET_CODE (op)); - for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) - { - if (fmt[i] == 'E') - { - register int j; - - for (j = XVECLEN (op, i) - 1; j >= 0; j--) - if (global_symbolic_reference_mentioned_p (XVECEXP (op, i, j), 0)) - return 1; - } - else if (fmt[i] == 'e' - && global_symbolic_reference_mentioned_p (XEXP (op, i), 0)) - return 1; - } - - return 0; -} - - -/* PRINT_OPERAND is defined to call this function, - which is easier to debug than putting all the code in - a macro definition in ns32k.h. */ - -void -print_operand (file, x, code) - FILE *file; - rtx x; - char code; -{ - if (code == '$') - PUT_IMMEDIATE_PREFIX (file); - else if (code == '?') - PUT_EXTERNAL_PREFIX (file); - else if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (GET_CODE (x) == MEM) - { - rtx tmp = XEXP (x, 0); -#if ! (defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)) - if (GET_CODE (tmp) != CONST_INT) - { - char *out = XSTR (tmp, 0); - if (out[0] == '*') - { - PUT_ABSOLUTE_PREFIX (file); - fprintf (file, "%s", &out[1]); - } - else - ASM_OUTPUT_LABELREF (file, out); - } - else -#endif - output_address (XEXP (x, 0)); - } - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) - { - if (GET_MODE (x) == DFmode) - { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX(file); -#ifdef SEQUENT_ASM - /* Sequent likes it's floating point constants as integers */ - fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]); -#else -#ifdef ENCORE_ASM - fprintf (file, "0f%.20e", u.d); -#else - fprintf (file, "0d%.20e", u.d); -#endif -#endif - } - else - { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX (file); -#ifdef SEQUENT_ASM - /* We have no way of winning if we can't get the bits - for a sequent floating point number. */ -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - abort (); -#endif - { - union { float f; long l; } uu; - uu.f = u.d; - fprintf (file, "0Fx%08x", uu.l); - } -#else - fprintf (file, "0f%.20e", u.d); -#endif - } - } - else - { -#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC - if (GET_CODE (x) == CONST_INT) -#endif - PUT_IMMEDIATE_PREFIX (file); - output_addr_const (file, x); - } -} - -/* PRINT_OPERAND_ADDRESS is defined to call this function, - which is easier to debug than putting all the code in - a macro definition in ns32k.h . */ - -/* Completely rewritten to get this to work with Gas for PC532 Mach. - This function didn't work and I just wasn't able (nor very willing) to - figure out how it worked. - 90-11-25 Tatu Yl|nen */ - -print_operand_address (file, addr) - register FILE *file; - register rtx addr; -{ - static char scales[] = { 'b', 'w', 'd', 0, 'q', }; - rtx offset, base, indexexp, tmp; - int scale; - extern int flag_pic; - - if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC) - { - fprintf (file, "tos"); - return; - } - - offset = NULL; - base = NULL; - indexexp = NULL; - while (addr != NULL) - { - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == PLUS) - { - tmp = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else - { - tmp = XEXP (addr,0); - addr = XEXP (addr,1); - } - } - else - { - tmp = addr; - addr = NULL; - } - switch (GET_CODE (tmp)) - { - case PLUS: - abort (); - case MEM: - if (base) - { - indexexp = base; - base = tmp; - } - else - base = tmp; - break; - case REG: - if (REGNO (tmp) < 8) - if (base) - { - indexexp = tmp; - } - else - base = tmp; - else - if (base) - { - indexexp = base; - base = tmp; - } - else - base = tmp; - break; - case MULT: - indexexp = tmp; - break; - case SYMBOL_REF: - if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp) - && ! SYMBOL_REF_FLAG (tmp)) - { - if (base) - { - assert (!indexexp); - indexexp = base; - } - base = tmp; - break; - } - case CONST: - if (flag_pic && GET_CODE (tmp) == CONST) - { - rtx sym, off, tmp1; - tmp1 = XEXP (tmp,0); - assert (GET_CODE (tmp1) == PLUS); - - sym = XEXP (tmp1,0); - if (GET_CODE (sym) != SYMBOL_REF) - { - off = sym; - sym = XEXP (tmp1,1); - } - else - off = XEXP (tmp1,1); - if (GET_CODE (sym) == SYMBOL_REF) - { - assert (GET_CODE (off) == CONST_INT); - if (CONSTANT_POOL_ADDRESS_P (sym) - || SYMBOL_REF_FLAG (sym)) - { - SYMBOL_REF_FLAG (tmp) = 1; - } - else - { - if (base) - { - assert (!indexexp); - indexexp = base; - } - assert (!offset); - base = sym; - offset = off; - break; - } - } - } - case CONST_INT: - case LABEL_REF: - if (offset) - offset = gen_rtx (PLUS, SImode, tmp, offset); - else - offset = tmp; - break; - default: - abort (); - } - } - if (! offset) - offset = const0_rtx; - - if (base -#ifndef INDEX_RATHER_THAN_BASE - && flag_pic - && GET_CODE (base) != SYMBOL_REF - && GET_CODE (offset) != CONST_INT -#else - /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix. */ -#endif - && !indexexp && GET_CODE (base) == REG - && REG_OK_FOR_INDEX_P (base)) - { - indexexp = base; - base = NULL; - } - - /* now, offset, base and indexexp are set */ - if (! base) - { -#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC) - if (GET_CODE (offset) == CONST_INT) -/* if (! (GET_CODE (offset) == LABEL_REF - || GET_CODE (offset) == SYMBOL_REF)) */ -#endif - PUT_ABSOLUTE_PREFIX (file); - } - - output_addr_const (file, offset); - if (base) /* base can be (REG ...) or (MEM ...) */ - switch (GET_CODE (base)) - { - /* now we must output base. Possible alternatives are: - (rN) (REG ...) - (sp) (REG ...) - (fp) (REG ...) - (pc) (REG ...) used for SYMBOL_REF and LABEL_REF, output - (disp(fp)) (MEM ...) just before possible [rX:y] - (disp(sp)) (MEM ...) - (disp(sb)) (MEM ...) - */ - case REG: - fprintf (file, "(%s)", reg_names[REGNO (base)]); - break; - case SYMBOL_REF: - assert (flag_pic); - fprintf (file, "("); - output_addr_const (file, base); - fprintf (file, "(sb))"); - break; - case MEM: - addr = XEXP(base,0); - base = NULL; - offset = NULL; - while (addr != NULL) - { - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == PLUS) - { - tmp = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else - { - tmp = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - } - else - { - tmp = addr; - addr = NULL; - } - switch (GET_CODE (tmp)) - { - case REG: - base = tmp; - break; - case CONST: - case CONST_INT: - case SYMBOL_REF: - case LABEL_REF: - if (offset) - offset = gen_rtx (PLUS, SImode, tmp, offset); - else - offset = tmp; - break; - default: - abort (); - } - } - if (! offset) - offset = const0_rtx; - fprintf (file, "("); - output_addr_const (file, offset); - if (base) - fprintf (file, "(%s)", reg_names[REGNO (base)]); -#ifdef BASE_REG_NEEDED - else if (TARGET_SB) - fprintf (file, "(sb)"); - else - assert (TARGET_SB); -#endif - fprintf (file, ")"); - break; - - default: - abort (); - } -#ifdef PC_RELATIVE - else if (GET_CODE (offset) == LABEL_REF - || GET_CODE (offset) == SYMBOL_REF - || GET_CODE (offset) == CONST - || GET_CODE (offset) == PLUS) - fprintf (file, "(pc)"); -#endif -#ifdef BASE_REG_NEEDED /* this is defined if the assembler always - needs a base register */ - else - { - /* Abs. addresses don't need a base (I think). */ - if (GET_CODE (offset) != CONST_INT -#ifndef PC_RELATIVE - && GET_CODE (offset) != LABEL_REF - && GET_CODE (offset) != SYMBOL_REF - && GET_CODE (offset) != CONST - && GET_CODE (offset) != PLUS -#endif - ) - { - if (TARGET_SB) - fprintf (file, "(sb)"); - else - assert (TARGET_SB); - } - } -#endif - /* now print index if we have one */ - if (indexexp) - { - if (GET_CODE (indexexp) == MULT) - { - scale = INTVAL (XEXP (indexexp, 1)) >> 1; - indexexp = XEXP (indexexp, 0); - } - else - scale = 0; - if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8) - abort (); - -#ifdef UTEK_ASM - fprintf (file, "[%c`%s]", - scales[scale], - reg_names[REGNO (indexexp)]); -#else - fprintf (file, "[%s:%c]", - reg_names[REGNO (indexexp)], - scales[scale]); -#endif - } -} - -/* National 32032 shifting is so bad that we can get - better performance in many common cases by using other - techniques. */ -char * -output_shift_insn (operands) - rtx *operands; -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 3) - if (GET_CODE (operands[0]) == REG) - { - if (GET_CODE (operands[1]) == REG) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - if (operands[2] == const1_rtx) - return "addd %0,%0"; - else if (INTVAL (operands[2]) == 2) - return "addd %0,%0\n\taddd %0,%0"; - } - if (operands[2] == const1_rtx) - return "movd %1,%0\n\taddd %0,%0"; - - operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); - return "addr %a1,%0"; - } - if (operands[2] == const1_rtx) - return "movd %1,%0\n\taddd %0,%0"; - } - else if (GET_CODE (operands[1]) == REG) - { - operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); - return "addr %a1,%0"; - } - else if (INTVAL (operands[2]) == 1 - && GET_CODE (operands[1]) == MEM - && rtx_equal_p (operands [0], operands[1])) - { - rtx temp = XEXP (operands[1], 0); - - if (GET_CODE (temp) == REG - || (GET_CODE (temp) == PLUS - && GET_CODE (XEXP (temp, 0)) == REG - && GET_CODE (XEXP (temp, 1)) == CONST_INT)) - return "addd %0,%0"; - } - else return "ashd %2,%0"; - return "ashd %2,%0"; -} - -char * -output_move_dconst (n, s) - int n; char *s; -{ - static char r[32]; - - if (n > -9 && n < 8) - strcpy(r, "movqd "); - else if (n > 0 && n < 256) - strcpy(r, "movzbd "); - else if (n > 0 && n < 65536) - strcpy(r, "movzwd "); - else if (n < 0 && n > -129) - strcpy(r, "movxbd "); - else if (n < 0 && n > -32769) - strcpy(r, "movxwd "); - else - strcpy(r, "movd "); - strcat(r, s); - return(r); -} diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.md b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.md deleted file mode 100644 index 8511a52c231..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/ns32k.md +++ /dev/null @@ -1,2753 +0,0 @@ -; BUGS: -;; Insert no-op between an insn with memory read-write operands -;; following by a scale-indexing operation. -;; The Sequent assembler does not allow addresses to be used -;; except in insns which explicitly compute an effective address. -;; I.e., one cannot say "cmpd _p,@_x" -;; Implement unsigned multiplication?? - -;;- Machine description for GNU compiler -;;- ns32000 Version -;; Copyright (C) 1988 Free Software Foundation, Inc. -;; Contributed by Michael Tiemann (tiemann@mcc.com) - -;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - -;;- Instruction patterns. When multiple patterns apply, -;;- the first one in the file is chosen. -;;- -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. -;;- -;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code -;;- updates for most instructions. - -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. - -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "rm"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqd %1,%0\"; }") - -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "g"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqw %1,%0\"; }") - -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "g"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqb %1,%0\"; }") - -(define_insn "tstdf" - [(set (cc0) - (match_operand:DF 0 "general_operand" "fmF"))] - "TARGET_32081" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (DFmode); - return \"cmpl %1,%0\"; }") - -(define_insn "tstsf" - [(set (cc0) - (match_operand:SF 0 "general_operand" "fmF"))] - "TARGET_32081" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (SFmode); - return \"cmpf %1,%0\"; }") - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "rmn") - (match_operand:SI 1 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - return \"cmpqd %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - int i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - return \"cmpqd %0,%1\"; - } - return \"cmpd %0,%1\"; -}") - -(define_insn "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "g") - (match_operand:HI 1 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqw %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - short i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqw %0,%1\"; - } - } - return \"cmpw %0,%1\"; -}") - -(define_insn "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "g") - (match_operand:QI 1 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - char i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqb %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - char i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqb %0,%1\"; - } - } - return \"cmpb %0,%1\"; -}") - -(define_insn "cmpdf" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "fmF") - (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "cmpl %0,%1") - -(define_insn "cmpsf" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "fmF") - (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "cmpf %0,%1") - -(define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=fg<") - (match_operand:DF 1 "general_operand" "fFg"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movl %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"movd %1,tos\", xoperands); - output_asm_insn (\"movd %1,tos\", operands); - return \"movl tos,%0\"; - } - return \"movl %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"movd tos,%0\"; - } - else - return \"movl %1,%0\"; - } - return output_move_double (operands); -}") - -(define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=fg<") - (match_operand:SF 1 "general_operand" "fFg"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movd %1,tos\;movf tos,%0\"; - else - return \"movf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } -#if 0 /* Someone suggested this for the Sequent. Is it needed? */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movf %1,%0\"; -#endif -/* There was a #if 0 around this, but that was erroneous - for many machines -- rms. */ -#ifndef MOVD_FLOAT_OK - /* GAS understands floating constants in ordinary movd instructions - but other assemblers might object. */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - union {int i[2]; float f; double d;} convrt; - convrt.i[0] = CONST_DOUBLE_LOW (operands[1]); - convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]); - convrt.f = convrt.d; - - /* Is there a better machine-independent way to to this? */ - operands[1] = gen_rtx (CONST_INT, VOIDmode, convrt.i[0]); - return \"movd %1,%0\"; - } -#endif - else return \"movd %1,%0\"; -}") - -(define_insn "" - [(set (match_operand:TI 0 "memory_operand" "=m") - (match_operand:TI 1 "memory_operand" "m"))] - "" - "movmd %1,%0,4") - -(define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=g<,*f,g") - (match_operand:DI 1 "general_operand" "gF,g,*f"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movl %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"movd %1,tos\", xoperands); - output_asm_insn (\"movd %1,tos\", operands); - return \"movl tos,%0\"; - } - return \"movl %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"movd tos,%0\"; - } - else - return \"movl %1,%0\"; - } - return output_move_double (operands); -}") - -;; This special case must precede movsi. -(define_insn "" - [(set (reg:SI 17) - (match_operand:SI 0 "general_operand" "rmn"))] - "" - "lprd sp,%0") - -(define_insn "movsi" - [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g,x") - (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movd %1,tos\;movf tos,%0\"; - else - return \"movf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - if (GET_CODE (operands[0]) == REG - && REGNO (operands[0]) == FRAME_POINTER_REGNUM) - return \"lprd fp,%1\"; - if (GET_CODE (operands[1]) == CONST_DOUBLE) - operands[1] - = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (! TARGET_32532) - { - if (i <= 7 && i >= -8) - return \"movqd %1,%0\"; - if (i < 0x4000 && i >= -0x4000) -#if defined (GNX_V3) || defined (UTEK_ASM) - return \"addr %c1,%0\"; -#else - return \"addr @%c1,%0\"; -#endif - } - else - return output_move_dconst(i, \"%$%1,%0\"); - } - else if (GET_CODE (operands[1]) == REG) - { - if (REGNO (operands[1]) < 16) - return \"movd %1,%0\"; - else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return \"sprd fp,%0\"; - else - return \"addr 0(fp),%0\" ; - } - else if (REGNO (operands[1]) == STACK_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return \"sprd sp,%0\"; - else - return \"addr 0(sp),%0\" ; - } - else abort (); - } - else if (GET_CODE (operands[1]) == MEM) - return \"movd %1,%0\"; - - /* Check if this effective address can be - calculated faster by pulling it apart. */ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return \"addr %a1,%0\"; -}") - -(define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=g<,*f,g") - (match_operand:HI 1 "general_operand" "g,g,*f"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, i); - return \"movqw %1,%0\"; - } - return \"movw %1,%0\"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movwf %1,tos\;movf tos,%0\"; - else - return \"movwf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - else - return \"movw %1,%0\"; -}") - -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+r")) - (match_operand:HI 1 "general_operand" "g"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8) - return \"movqw %1,%0\"; - return \"movw %1,%0\"; -}") - -(define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=g<,*f,g") - (match_operand:QI 1 "general_operand" "g,g,*f"))] - "" - "* -{ if (GET_CODE (operands[1]) == CONST_INT) - { - char char_val = (char)INTVAL (operands[1]); - if (char_val <= 7 && char_val >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, char_val); - return \"movqb %1,%0\"; - } - return \"movb %1,%0\"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movbf %1,tos\;movf tos,%0\"; - else - return \"movbf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - else - return \"movb %1,%0\"; -}") - -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+r")) - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9) - return \"movqb %1,%0\"; - return \"movb %1,%0\"; -}") - -;; This is here to accept 4 arguments and pass the first 3 along -;; to the movstrsi1 pattern that really does the work. -(define_expand "movstrsi" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:SI 2 "general_operand" "rmn")) - (match_operand 3 "" "")] - "" - " - emit_insn (gen_movstrsi1 (operands[0], operands[1], operands[2])); - DONE; -") - -;; The definition of this insn does not really explain what it does, -;; but it should suffice -;; that anything generated as this insn will be recognized as one -;; and that it won't successfully combine with anything. -(define_insn "movstrsi1" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:SI 2 "general_operand" "rmn")) - (clobber (reg:SI 0)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2))] - "" - "* -{ - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - abort (); - operands[0] = XEXP (operands[0], 0); - operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[0]) == MEM) - if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"movd %0,r2\;movd %1,r1\", operands); - else - output_asm_insn (\"movd %0,r2\;addr %a1,r1\", operands); - else if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"addr %a0,r2\;movd %1,r1\", operands); - else - output_asm_insn (\"addr %a0,r2\;addr %a1,r1\", operands); - -#ifdef UTEK_ASM - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return \"movqd %2,r0\;movsd $0\"; - else - return \"movd %2,r0\;movsd $0\"; - } - else - { - return \"movd %2,r0\;movsb $0\"; - } -#else - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return \"movqd %2,r0\;movsd\"; - else - return \"movd %2,r0\;movsd\"; - } - else - { - return \"movd %2,r0\;movsb\"; - } -#endif -}") - -;; Extension and truncation insns. -;; Those for integer source operand -;; are ordered widest source type first. - -(define_insn "truncsiqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rmn")))] - "" - "movb %1,%0") - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rmn")))] - "" - "movw %1,%0") - -(define_insn "trunchiqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movb %1,%0") - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movxwd %1,%0") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movxbw %1,%0") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movxbd %1,%0") - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "movfl %1,%0") - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float_truncate:SF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "movlf %1,%0") - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movzwd %1,%0") - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movzbw %1,%0") - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movzbd %1,%0") - -;; Fix-to-float conversion insns. -;; Note that the ones that start with SImode come first. -;; That is so that an operand that is a CONST_INT -;; (and therefore lacks a specific machine mode). -;; will be recognized as SImode (which is always valid) -;; rather than as QImode or HImode. - -;; Rumor has it that the National part does not correctly convert -;; constant ints to floats. This conversion is therefore disabled. -;; A register must be used to perform the conversion. - -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:SI 1 "general_operand" "rm")))] - "TARGET_32081" - "movdf %1,%0") - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float:DF (match_operand:SI 1 "general_operand" "rm")))] - "TARGET_32081" - "movdl %1,%0") - -(define_insn "floathisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:HI 1 "general_operand" "rm")))] - "TARGET_32081" - "movwf %1,%0") - -(define_insn "floathidf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float:DF (match_operand:HI 1 "general_operand" "rm")))] - "TARGET_32081" - "movwl %1,%0") - -(define_insn "floatqisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:QI 1 "general_operand" "rm")))] - "TARGET_32081" - "movbf %1,%0") - -; Some assemblers warn that this insn doesn't work. -; Maybe they know something we don't. -;(define_insn "floatqidf2" -; [(set (match_operand:DF 0 "general_operand" "=fm<") -; (float:DF (match_operand:QI 1 "general_operand" "rm")))] -; "TARGET_32081" -; "movbl %1,%0") - -;; Float-to-fix conversion insns. -;; The sequent compiler always generates "trunc" insns. - -(define_insn "fixsfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fixsfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fixsfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fixdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fixdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fixdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncld %1,%0") - -;; Unsigned - -(define_insn "fixunssfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (unsigned_fix:QI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fixunssfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (unsigned_fix:HI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fixunssfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (unsigned_fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fixunsdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (unsigned_fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fixunsdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (unsigned_fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fixunsdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (unsigned_fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncld %1,%0") - -;;; These are not yet used by GCC -(define_insn "fix_truncsfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fix_truncsfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fix_truncdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fix_truncdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncld %1,%0") - -;;- All kinds of add instructions. - -(define_insn "adddf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (plus:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "addl %2,%0") - - -(define_insn "addsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (plus:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "addf %2,%0") - -(define_insn "" - [(set (reg:SI 17) - (plus:SI (reg:SI 17) - (match_operand:SI 0 "immediate_operand" "i")))] - "GET_CODE (operands[0]) == CONST_INT" - "* -{ -#ifndef SEQUENT_ADJUST_STACK - if (TARGET_32532) - if (INTVAL (operands[0]) == 8) - return \"cmpd tos,tos\"; - if (TARGET_32532 || TARGET_32332) - if (INTVAL (operands[0]) == 4) - return \"cmpqd %$0,tos\"; -#endif - if (! TARGET_32532) - { - if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64) - return \"adjspb %$%n0\"; - else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192) - return \"adjspw %$%n0\"; - } - return \"adjspd %$%n0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (plus:SI (reg:SI 16) - (match_operand:SI 1 "immediate_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT" - "addr %c1(fp),%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (plus:SI (reg:SI 17) - (match_operand:SI 1 "immediate_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT" - "addr %c1(sp),%0") - -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=g,=g&<") - (plus:SI (match_operand:SI 1 "general_operand" "%0,r") - (match_operand:SI 2 "general_operand" "rmn,n")))] - "" - "* -{ - if (which_alternative == 1) - { - int i = INTVAL (operands[2]); - if (NS32K_DISPLACEMENT_P (i)) - return \"addr %c2(%1),%0\"; - else - return \"movd %1,%0\;addd %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 7 && i >= -8) - return \"addqd %2,%0\"; - else if (GET_CODE (operands[0]) == REG - && i < 0x4000 && i >= -0x4000 && ! TARGET_32532) - return \"addr %c2(%0),%0\"; - } - return \"addd %2,%0\"; -}") - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (plus:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return \"addqw %2,%0\"; - } - return \"addw %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "=r")) - (plus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqw %2,%0\"; - return \"addw %2,%0\"; -}") - -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (plus:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return \"addqb %2,%0\"; - } - return \"addb %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "=r")) - (plus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqb %2,%0\"; - return \"addb %2,%0\"; -}") - -;;- All kinds of subtract instructions. - -(define_insn "subdf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (minus:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "subl %2,%0") - -(define_insn "subsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (minus:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "subf %2,%0") - -(define_insn "" - [(set (reg:SI 17) - (minus:SI (reg:SI 17) - (match_operand:SI 0 "immediate_operand" "i")))] - "GET_CODE (operands[0]) == CONST_INT" - "* -{ - if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 - && INTVAL(operands[0]) > -64 && ! TARGET_32532) - return \"adjspb %$%0\"; - return \"adjspd %$%0\"; -}") - -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqd %$%n2,%0\"; - } - return \"subd %2,%0\"; -}") - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqw %$%n2,%0\"; - } - return \"subw %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "=r")) - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqw %$%n2,%0\"; - return \"subw %2,%0\"; -}") - -(define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (minus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqb %$%n2,%0\"; - } - return \"subb %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "=r")) - (minus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqb %$%n2,%0\"; - return \"subb %2,%0\"; -}") - -;;- Multiply instructions. - -(define_insn "muldf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (mult:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "mull %2,%0") - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (mult:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "mulf %2,%0") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "muld %2,%0") - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "mulw %2,%0") - -(define_insn "mulqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (mult:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "mulb %2,%0") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "general_operand" "=g") - (mult:DI (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "0")) - (zero_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "rmn"))))] - "" - "meid %2,%0") - -;;- Divide instructions. - -(define_insn "divdf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (div:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "divl %2,%0") - -(define_insn "divsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (div:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "divf %2,%0") - -(define_insn "divsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (div:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "quod %2,%0") - -(define_insn "divhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (div:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "quow %2,%0") - -(define_insn "divqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (div:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "quob %2,%0") - -(define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"deid %2,%0\;movd %1,%0\"; -}") - -(define_insn "udivhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (udiv:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]) + 1); - return \"deiw %2,%0\;movw %1,%0\"; -}") - -(define_insn "udivqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (udiv:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - operands[1] = gen_rtx (REG, QImode, REGNO (operands[0]) + 1); - return \"deib %2,%0\;movb %1,%0\"; -}") - -;; Remainder instructions. - -(define_insn "modsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (mod:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "remd %2,%0") - -(define_insn "modhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (mod:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "remw %2,%0") - -(define_insn "modqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (mod:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "remb %2,%0") - -(define_insn "umodsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (umod:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "deid %2,%0") - -(define_insn "umodhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (umod:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:HI 2 "general_operand" "g")))] - "" - "deiw %2,%0") - -(define_insn "umodqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (umod:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:QI 2 "general_operand" "g")))] - "" - "deib %2,%0") - -; This isn't be usable in its current form. -;(define_insn "udivmoddisi4" -; [(set (subreg:SI (match_operand:DI 0 "general_operand" "=r") 1) -; (udiv:SI (match_operand:DI 1 "general_operand" "0") -; (match_operand:SI 2 "general_operand" "rmn"))) -; (set (subreg:SI (match_dup 0) 0) -; (umod:SI (match_dup 1) (match_dup 2)))] -; "" -; "deid %2,%0") - -;;- Logical Instructions: AND - -(define_insn "andsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (and:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if ((INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return \"movqb %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return \"andb %2,%0\"; - } - } - if ((INTVAL (operands[2]) | 0xffff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffff0000) - return \"movqw %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - return \"andw %2,%0\"; - } - } - } - return \"andd %2,%0\"; -}") - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (and:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return \"movqb %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return \"andb %2,%0\"; - } - } - return \"andw %2,%0\"; -}") - -(define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (and:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "andb %2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (and:SI (not:SI (match_operand:SI 1 "general_operand" "rmn")) - (match_operand:SI 2 "general_operand" "0")))] - "" - "bicd %1,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (and:HI (not:HI (match_operand:HI 1 "general_operand" "g")) - (match_operand:HI 2 "general_operand" "0")))] - "" - "bicw %1,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "g")) - (match_operand:QI 2 "general_operand" "0")))] - "" - "bicb %1,%0") - -;;- Bit set instructions. - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (ior:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return \"orb %2,%0\"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return \"orw %2,%0\"; - } - return \"ord %2,%0\"; -}") - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ior:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return \"orb %2,%0\"; - return \"orw %2,%0\"; -}") - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ior:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "orb %2,%0") - -;;- xor instructions. - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (xor:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return \"xorb %2,%0\"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return \"xorw %2,%0\"; - } - return \"xord %2,%0\"; -}") - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return \"xorb %2,%0\"; - return \"xorw %2,%0\"; -}") - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (xor:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "xorb %2,%0") - -(define_insn "negdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (neg:DF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "negl %1,%0") - -(define_insn "negsf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (neg:SF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "negf %1,%0") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (neg:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "negd %1,%0") - -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (neg:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "negw %1,%0") - -(define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (neg:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "negb %1,%0") - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (not:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "comd %1,%0") - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (not:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "comw %1,%0") - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (not:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "comb %1,%0") - -;; arithmetic left and right shift operations -;; on the 32532 we will always use lshd for arithmetic left shifts, -;; because it is three times faster. Broken programs which -;; use negative shift counts are probably broken differently -;; than elsewhere. - -;; alternative 0 never matches on the 32532 -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g") - (ashift:SI (match_operand:SI 1 "general_operand" "r,0") - (match_operand:SI 2 "general_operand" "I,rmn")))] - "" - "* -{ if (TARGET_32532) - return \"lshd %2,%0\"; - else - return output_shift_insn (operands); -}") - -(define_insn "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return \"addw %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return \"addw %0,%0\;addw %0,%0\"; - } - if (TARGET_32532) - return \"lshw %2,%0\"; - else - return \"ashw %2,%0\"; -}") - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return \"addb %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return \"addb %0,%0\;addb %0,%0\"; - } - if (TARGET_32532) - return \"lshb %2,%0\"; - else - return \"ashb %2,%0\"; -}") - -;; Arithmetic right shift on the 32k works by negating the shift count. -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashd %2,%0") - -(define_expand "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashw %2,%0") - -(define_expand "ashrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashb %2,%0") - -;; logical shift instructions - -(define_insn "lshlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshift:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshd %2,%0") - -(define_insn "lshlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshw %2,%0") - -(define_insn "lshlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshb %2,%0") - -;; Logical right shift on the 32k works by negating the shift count. -(define_expand "lshrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshd %2,%0") - -(define_expand "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshw %2,%0") - -(define_expand "lshrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshb %2,%0") - -;; Rotate instructions - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotate:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotd %2,%0") - -(define_insn "rotlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotate:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotw %2,%0") - -(define_insn "rotlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotate:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotb %2,%0") - -;; Right rotate on the 32k works by negating the shift count. -(define_expand "rotrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotd %2,%0") - -(define_expand "rotrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotw %2,%0") - -(define_expand "rotrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotb %2,%0") - -;;- load or push effective address -;; These come after the move, add, and multiply patterns -;; because we don't want pushl $1 turned into pushad 1. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (match_operand:QI 1 "address_operand" "p"))] - "" - "* -{ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return \"addr %a1,%0\"; -}") - -;;; Index insns. These are about the same speed as multiply-add counterparts. -;;; but slower then using power-of-2 shifts if we can use them -; -;(define_insn "" -; [(set (match_operand:SI 0 "register_operand" "=r") -; (plus:SI (match_operand:SI 1 "general_operand" "rmn") -; (mult:SI (match_operand:SI 2 "register_operand" "0") -; (plus:SI (match_operand:SI 3 "general_operand" "rmn") (const_int 1)))))] -; "GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) > 8" -; "indexd %0,%3,%1") -; -;(define_insn "" -; [(set (match_operand:SI 0 "register_operand" "=r") -; (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0") -; (plus:SI (match_operand:SI 2 "general_operand" "rmn") (const_int 1))) -; (match_operand:SI 3 "general_operand" "rmn")))] -; "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 8" -; "indexd %0,%2,%3") - -;; Set, Clear, and Invert bit - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g") - (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (const_int 1))] - "" - "sbitd %1,%0") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g") - (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (const_int 0))] - "" - "cbitd %1,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "+g") - (xor:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (match_dup 0)))] - "" - "ibitd %1,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (xor:QI (subreg:QI - (ashift:SI (const_int 1) - (match_operand:QI 1 "general_operand" "rmn")) 0) - (match_dup 0)))] - "" - "ibitb %1,%0") - -;; Recognize jbs and jbc instructions. - -(define_insn "" - [(set (cc0) - (zero_extract (match_operand:SI 0 "general_operand" "rm") - (const_int 1) - (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ cc_status.flags = CC_Z_IN_F; - return \"tbitd %1,%0\"; -}") - -;; extract(base, width, offset) -;; Signed bitfield extraction is not supported in hardware on the -;; NS 32032. It is therefore better to let GCC figure out a -;; good strategy for generating the proper instruction sequence -;; and represent it as rtl. - -;; Optimize the case of extracting a byte or word from a register. -;; Otherwise we must load a register with the offset of the -;; chunk we want, and perform an extract insn (each of which -;; is very expensive). Since we use the stack to do our bit-twiddling -;; we cannot use it for a destination. Perhaps things are fast -;; enough on the 32532 that such hacks are not needed. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=ro") - (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && (INTVAL (operands[3]) == 8 || INTVAL (operands[3]) == 16 || INTVAL (operands[3]) == 24)" - "* -{ - output_asm_insn (\"movd %1,tos\", operands); - if (INTVAL (operands[2]) == 16) - { - if (INTVAL (operands[3]) == 8) - output_asm_insn (\"movzwd 1(sp),%0\", operands); - else - output_asm_insn (\"movzwd 2(sp),%0\", operands); - } - else - { - if (INTVAL (operands[3]) == 8) - output_asm_insn (\"movzbd 1(sp),%0\", operands); - else if (INTVAL (operands[3]) == 16) - output_asm_insn (\"movzbd 2(sp),%0\", operands); - else - output_asm_insn (\"movzbd 3(sp),%0\", operands); - } - if (TARGET_32532 || TARGET_32332) - return \"cmpqd %$0,tos\"; - else - return \"adjspb %$-4\"; -}") - -;; The extsd/extd isntructions have the problem that they always access -;; 32 bits even if the bitfield is smaller. For example the instruction -;; extsd 7(r1),r0,2,5 -;; would read not only at address 7(r1) but also at 8(r1) to 10(r1). -;; If these addresses are in a different (unmapped) page a memory fault -;; is the result. -;; -;; Timing considerations: -;; movd 0(r1),r0 3 bytes -;; lshd -26,r0 4 -;; andd 0x1f,r0 5 -;; takes about 13 cycles on the 532 while -;; extsd 7(r1),r0,2,5 5 bytes -;; takes about 21 cycles. -;; -;; So lets forget about extsd/extd on the 532. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extract:SI (match_operand:SI 1 "register_operand" "g") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "general_operand" "rK")))] - "! TARGET_32532" - "* -{ if (GET_CODE (operands[3]) == CONST_INT) - return \"extsd %1,%0,%3,%2\"; - else return \"extd %3,%1,%0,%2\"; -}") - -(define_insn "extzv" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extract:SI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "general_operand" "rK")))] - "! TARGET_32532" - "* -{ if (GET_CODE (operands[3]) == CONST_INT) - return \"extsd %1,%0,%3,%2\"; - else return \"extd %3,%1,%0,%2\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+o") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rn")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 8) - { - operands[0] = adj_offsettable_operand (operands[0], - INTVAL (operands[2]) / 8); - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8); - } - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - } - return \"insd %2,%3,%0,%1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rK")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - return \"insd %2,%3,%0,%1\"; -}") - -(define_insn "insv" - [(set (zero_extract:SI (match_operand:QI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rK")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - return \"insd %2,%3,%0,%1\"; -}") - - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "br %l0") - -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfc %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfs %l0\"; - else return \"beq %l0\"; -}") - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfs %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfc %l0\"; - else return \"bne %l0\"; -}") - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bgt %l0") - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bhi %l0") - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blt %l0") - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blo %l0") - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bge %l0") - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bhs %l0") - -(define_insn "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "ble %l0") - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bls %l0") - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfs %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfc %l0\"; - else return \"bne %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfc %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfs %l0\"; - else return \"beq %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "ble %l0") - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bls %l0") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bge %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bhs %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "blt %l0") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "blo %l0") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bgt %l0") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bhi %l0") - -;; Subtract-and-jump and Add-and-jump insns. -;; These can actually be used for adding numbers in the range -8 to 7 - -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:SI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i")) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (match_dup 0) - (minus:SI (match_dup 0) - (match_dup 1)))] - "INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8" - "acbd %$%n1,%0,%l2") - -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:SI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i")) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (match_operand:SI 3 "const_int_operand" "i")))] - "INTVAL (operands[1]) == - INTVAL (operands[3]) - && INTVAL (operands[3]) >= -8 && INTVAL (operands[3]) < 8" - "acbd %3,%0,%l2") - -(define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[0]) == MEM) - { - rtx temp = XEXP (operands[0], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return \"bsr %?%0\"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[0] = temp; - return \"bsr %0\"; -#else -#ifdef GNX_V3 - return \"bsr %0\"; -#else - return \"bsr %?%a0\"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[0], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return \"jsr %0\"; -#else - return \"jsr %a0\"; -#endif - } -#endif /* not JSR_ALWAYS */ - return \"jsr %0\"; -}") - -(define_insn "call_value" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[1]) == MEM) - { - rtx temp = XEXP (operands[1], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return \"bsr %?%1\"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[1] = temp; - return \"bsr %1\"; -#else -#ifdef GNX_V3 - return \"bsr %1\"; -#else - return \"bsr %?%a1\"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[1], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return \"jsr %1\"; -#else - return \"jsr %a1\"; -#endif - } -#endif /* not JSR_ALWAYS */ - return \"jsr %1\"; -}") - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "") - -(define_insn "return" - [(return)] - "0" - "ret 0") - -(define_insn "abssf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (abs:SF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "absf %1,%0") - -(define_insn "absdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "absl %1,%0") - -(define_insn "abssi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (abs:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "absd %1,%0") - -(define_insn "abshi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (abs:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "absw %1,%0") - -(define_insn "absqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (abs:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "absb %1,%0") - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "r"))] - "" - "jump %0") - -(define_insn "tablejump" - [(set (pc) - (plus:SI (pc) (match_operand:SI 0 "general_operand" "g"))) - (use (label_ref (match_operand 1 "" "")))] - "" - "* -{ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", - CODE_LABEL_NUMBER (operands[1])); - return \"cased %0\"; -}") - -;; Scondi instructions -(define_insn "seq" - [(set (match_operand:SI 0 "general_operand" "=g<") - (eq:SI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcd %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsd %0\"; - else return \"seqd %0\"; -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (eq:HI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcw %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsw %0\"; - else return \"seqw %0\"; -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (eq:QI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcb %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsb %0\"; - else return \"seqb %0\"; -}") - -(define_insn "sne" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ne:SI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsd %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcd %0\"; - else return \"sned %0\"; -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ne:HI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsw %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcw %0\"; - else return \"snew %0\"; -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ne:QI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsb %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcb %0\"; - else return \"sneb %0\"; -}") - -(define_insn "sgt" - [(set (match_operand:SI 0 "general_operand" "=g<") - (gt:SI (cc0) (const_int 0)))] - "" - "sgtd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (gt:HI (cc0) (const_int 0)))] - "" - "sgtw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (gt:QI (cc0) (const_int 0)))] - "" - "sgtb %0") - -(define_insn "sgtu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (gtu:SI (cc0) (const_int 0)))] - "" - "shid %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (gtu:HI (cc0) (const_int 0)))] - "" - "shiw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (gtu:QI (cc0) (const_int 0)))] - "" - "shib %0") - -(define_insn "slt" - [(set (match_operand:SI 0 "general_operand" "=g<") - (lt:SI (cc0) (const_int 0)))] - "" - "sltd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (lt:HI (cc0) (const_int 0)))] - "" - "sltw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (lt:QI (cc0) (const_int 0)))] - "" - "sltb %0") - -(define_insn "sltu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ltu:SI (cc0) (const_int 0)))] - "" - "slod %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ltu:HI (cc0) (const_int 0)))] - "" - "slow %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ltu:QI (cc0) (const_int 0)))] - "" - "slob %0") - -(define_insn "sge" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ge:SI (cc0) (const_int 0)))] - "" - "sged %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ge:HI (cc0) (const_int 0)))] - "" - "sgew %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ge:QI (cc0) (const_int 0)))] - "" - "sgeb %0") - -(define_insn "sgeu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (geu:SI (cc0) (const_int 0)))] - "" - "shsd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (geu:HI (cc0) (const_int 0)))] - "" - "shsw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (geu:QI (cc0) (const_int 0)))] - "" - "shsb %0") - -(define_insn "sle" - [(set (match_operand:SI 0 "general_operand" "=g<") - (le:SI (cc0) (const_int 0)))] - "" - "sled %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (le:HI (cc0) (const_int 0)))] - "" - "slew %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (le:QI (cc0) (const_int 0)))] - "" - "sleb %0") - -(define_insn "sleu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (leu:SI (cc0) (const_int 0)))] - "" - "slsd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (leu:HI (cc0) (const_int 0)))] - "" - "slsw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (leu:QI (cc0) (const_int 0)))] - "" - "slsb %0") - -;; ffs instructions - -(define_insn "ffsqi2" - [(set (match_operand:QI 0 "general_operand" "=g") - (ffs:QI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqb 0,%0; ffsd %1,%0; bfs 1f; addqb 1,%0; 1:\"; -}") - -(define_insn "ffshi2" - [(set (match_operand:HI 0 "general_operand" "=g") - (ffs:HI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqw 0,%0; ffsd %1,%0; bfs 1f; addqw 1,%0; 1:\"; -}") - -(define_insn "ffssi2" - [(set (match_operand:SI 0 "general_operand" "=g") - (ffs:SI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqd 0,%0; ffsd %1,%0; bfs 1f; addqd 1,%0; 1:\"; -}") - -;; Speed up stack adjust followed by a HI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (match_operand:HI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzwd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movxbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a QI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -3))) - (set (match_operand:QI 0 "push_operand" "=m") - (match_operand:QI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a SI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 4))) - (set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,0(sp)\"), - operands); - else - output_asm_insn (\"movd %1,0(sp)\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by two fullword fixedpoint pushes. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 8))) - (set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "general_operand" "g")) - (set (match_operand:SI 2 "push_operand" "=m") - (match_operand:SI 3 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1]) - && ! reg_mentioned_p (stack_pointer_rtx, operands[3])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,4(sp)\"), - operands); - else - output_asm_insn (\"movd %1,4(sp)\", operands); - - if (GET_CODE (operands[3]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%$%3,0(sp)\"), - operands); - else - output_asm_insn (\"movd %3,0(sp)\", operands); - return \"\"; -}") diff --git a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/xm-netbsd.h b/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/xm-netbsd.h deleted file mode 100644 index 481926a2672..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/2.5.8/xm-netbsd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Configuration for GNU C-compiler for the ns32532. - Copyright (C) 1987, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: xm-netbsd.h,v 1.1.1.1 1995/10/18 08:39:23 deraadt Exp $ -*/ - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* NetBSD does have atexit. */ - -#define HAVE_ATEXIT - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/Makefile b/gnu/usr.bin/gcc2/arch/ns32k/Makefile deleted file mode 100644 index 56a7ac8e3cc..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:21 deraadt Exp $ - -.include diff --git a/gnu/usr.bin/gcc2/arch/ns32k/aux-output.c b/gnu/usr.bin/gcc2/arch/ns32k/aux-output.c deleted file mode 100644 index 6d7d085df9c..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/aux-output.c +++ /dev/null @@ -1,904 +0,0 @@ -/* Subroutines for assembler code output on the NS32000. - Copyright (C) 1988 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Some output-actions in ns32k.md need these. */ -#include -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" - -#ifdef OSF_OS -int ns32k_num_files = 0; -#endif - -void -trace (s, s1, s2) - char *s, *s1, *s2; -{ - fprintf (stderr, s, s1, s2); -} - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ - -int -hard_regno_mode_ok (regno, mode) - int regno; - enum machine_mode mode; -{ - switch (mode) - { - case QImode: - case HImode: - case PSImode: - case SImode: - case PDImode: - case VOIDmode: - case BLKmode: - if (regno < 8 || regno == 16 || regno == 17) - return 1; - else - return 0; - - case DImode: - if (regno < 8 && (regno & 1) == 0) - return 1; - else - return 0; - - case SFmode: - case SCmode: - if (TARGET_32081) - { - if (regno < 16) - return 1; - else - return 0; - } - else - { - if (regno < 8) - return 1; - else - return 0; - } - - case DFmode: - case DCmode: - if ((regno & 1) == 0) - { - if (TARGET_32081) - { - if (regno < 16) - return 1; - else - return 0; - } - else - { - if (regno < 8) - return 1; - else - return 0; - } - } - else - return 0; - } - - /* Used to abort here, but simply saying "no" handles TImode - much better. */ - return 0; -} - -/* ADDRESS_COST calls this. This function is not optimal - for the 32032 & 32332, but it probably is better than - the default. */ - -int -calc_address_cost (operand) - rtx operand; -{ - int i; - int cost = 0; - - if (GET_CODE (operand) == MEM) - cost += 3; - if (GET_CODE (operand) == MULT) - cost += 2; -#if 0 - if (GET_CODE (operand) == REG) - cost += 1; /* not really, but the documentation - says different amount of registers - shouldn't return the same costs */ -#endif - switch (GET_CODE (operand)) - { - case REG: - case CONST: - case CONST_INT: - case CONST_DOUBLE: - case SYMBOL_REF: - case LABEL_REF: - case POST_DEC: - case PRE_DEC: - break; - case MULT: - case MEM: - case PLUS: - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++) - { - cost += calc_address_cost (XEXP (operand, i)); - } - default: - break; - } - return cost; -} - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -enum reg_class -secondary_reload_class (class, mode, in) - enum reg_class class; - enum machine_mode mode; - rtx in; -{ - int regno = true_regnum (in); - - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - - /* We can place anything into GENERAL_REGS and can put GENERAL_REGS - into anything. */ - if (class == GENERAL_REGS || (regno >= 0 && regno < 8)) - return NO_REGS; - - /* Constants, memory, and FP registers can go into FP registers. */ - if ((regno == -1 || (regno >= 8 && regno < 16)) && (class == FLOAT_REGS)) - return NO_REGS; - -#if 0 /* This isn't strictly true (can't move fp to sp or vice versa), - so it's cleaner to use PREFERRED_RELOAD_CLASS - to make the right things happen. */ - if (regno >= 16 && class == GEN_AND_MEM_REGS) - return NO_REGS; -#endif - - /* Otherwise, we need GENERAL_REGS. */ - return GENERAL_REGS; -} -/* Generate the rtx that comes from an address expression in the md file */ -/* The expression to be build is BASE[INDEX:SCALE]. To recognize this, - scale must be converted from an exponent (from ASHIFT) to a - multiplier (for MULT). */ -rtx -gen_indexed_expr (base, index, scale) - rtx base, index, scale; -{ - rtx addr; - - /* This generates an illegal addressing mode, if BASE is - fp or sp. This is handled by PRINT_OPERAND_ADDRESS. */ - if (GET_CODE (base) != REG && GET_CODE (base) != CONST_INT) - base = gen_rtx (MEM, SImode, base); - addr = gen_rtx (MULT, SImode, index, - gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (scale))); - addr = gen_rtx (PLUS, SImode, base, addr); - return addr; -} - -/* Return 1 if OP is a valid operand of mode MODE. This - predicate rejects operands which do not have a mode - (such as CONST_INT which are VOIDmode). */ -int -reg_or_mem_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - return (GET_MODE (op) == mode - && (GET_CODE (op) == REG - || GET_CODE (op) == SUBREG - || GET_CODE (op) == MEM)); -} - -/* Return the best assembler insn template - for moving operands[1] into operands[0] as a fullword. */ - -static char * -singlemove_string (operands) - rtx *operands; -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) <= 7 - && INTVAL (operands[1]) >= -8) - return "movqd %1,%0"; - return "movd %1,%0"; -} - -char * -output_move_double (operands) - rtx *operands; -{ - enum anon1 { REGOP, OFFSOP, PUSHOP, CNSTOP, RNDOP } optype0, optype1; - rtx latehalf[2]; - - /* First classify both operands. */ - - if (REG_P (operands[0])) - optype0 = REGOP; - else if (offsettable_memref_p (operands[0])) - optype0 = OFFSOP; - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - optype0 = PUSHOP; - else - optype0 = RNDOP; - - if (REG_P (operands[1])) - optype1 = REGOP; - else if (CONSTANT_P (operands[1])) - optype1 = CNSTOP; - else if (offsettable_memref_p (operands[1])) - optype1 = OFFSOP; - else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) - optype1 = PUSHOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP) - abort (); - - /* Ok, we can do one word at a time. - Normally we do the low-numbered word first, - but if either operand is autodecrementing then we - do the high-numbered word first. - - In either case, set up in LATEHALF the operands to use - for the high-numbered word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ - - if (optype0 == REGOP) - latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (operands[0], 4); - else - latehalf[0] = operands[0]; - - if (optype1 == REGOP) - latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (operands[1], 4); - else if (optype1 == CNSTOP) - { - if (GET_CODE (operands[1]) == CONST_DOUBLE) - split_double (operands[1], &operands[1], &latehalf[1]); - else - latehalf[1] = const0_rtx; - } - else - latehalf[1] = operands[1]; - - /* If insn is effectively movd N(sp),tos then we will do the - high word first. We should use the adjusted operand 1 (which is N+4(sp)) - for the low word as well, to compensate for the first decrement of sp. - Given this, it doesn't matter which half we do "first". */ - if (optype0 == PUSHOP - && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM - && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1])) - operands[1] = latehalf[1]; - - /* If one or both operands autodecrementing, - do the two words, high-numbered first. */ - else if (optype0 == PUSHOP || optype1 == PUSHOP) - { - output_asm_insn (singlemove_string (latehalf), latehalf); - return singlemove_string (operands); - } - - /* If the first move would clobber the source of the second one, - do them in the other order. */ - - /* Overlapping registers. */ - if (optype0 == REGOP && optype1 == REGOP - && REGNO (operands[0]) == REGNO (latehalf[1])) - { - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Do low-numbered word. */ - return singlemove_string (operands); - } - /* Loading into a register which overlaps a register used in the address. */ - else if (optype0 == REGOP && optype1 != REGOP - && reg_overlap_mentioned_p (operands[0], operands[1])) - { - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) - && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) - { - /* If both halves of dest are used in the src memory address, - add the two regs and put them in the low reg (operands[0]). - Then it works to load latehalf first. */ - rtx xops[2]; - xops[0] = latehalf[0]; - xops[1] = operands[0]; - output_asm_insn ("addd %0,%1", xops); - operands[1] = gen_rtx (MEM, DImode, operands[0]); - latehalf[1] = adj_offsettable_operand (operands[1], 4); - /* The first half has the overlap, Do the late half first. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Then clobber. */ - return singlemove_string (operands); - } - if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))) - { - /* The first half has the overlap, Do the late half first. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Then clobber. */ - return singlemove_string (operands); - } - } - - /* Normal case. Do the two words, low-numbered first. */ - - output_asm_insn (singlemove_string (operands), operands); - - operands[0] = latehalf[0]; - operands[1] = latehalf[1]; - return singlemove_string (operands); -} - -int -check_reg (oper, reg) - rtx oper; - int reg; -{ - register int i; - - if (oper == 0) - return 0; - switch (GET_CODE(oper)) - { - case REG: - return (REGNO(oper) == reg) ? 1 : 0; - case MEM: - return check_reg(XEXP(oper, 0), reg); - case PLUS: - case MULT: - return check_reg(XEXP(oper, 0), reg) || check_reg(XEXP(oper, 1), reg); - } - return 0; -} - -/* Returns 1 if OP contains a global symbol reference */ - -int -global_symbolic_reference_mentioned_p (op, f) - rtx op; - int f; -{ - register char *fmt; - register int i; - - if (GET_CODE (op) == SYMBOL_REF) - { - if (! SYMBOL_REF_FLAG (op)) - return 1; - else - return 0; - } - else if (f && GET_CODE (op) != CONST) - return 0; - - fmt = GET_RTX_FORMAT (GET_CODE (op)); - for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) - { - if (fmt[i] == 'E') - { - register int j; - - for (j = XVECLEN (op, i) - 1; j >= 0; j--) - if (global_symbolic_reference_mentioned_p (XVECEXP (op, i, j), 0)) - return 1; - } - else if (fmt[i] == 'e' - && global_symbolic_reference_mentioned_p (XEXP (op, i), 0)) - return 1; - } - - return 0; -} - - -/* PRINT_OPERAND is defined to call this function, - which is easier to debug than putting all the code in - a macro definition in ns32k.h. */ - -void -print_operand (file, x, code) - FILE *file; - rtx x; - char code; -{ - if (code == '$') - PUT_IMMEDIATE_PREFIX (file); - else if (code == '?') - PUT_EXTERNAL_PREFIX (file); - else if (GET_CODE (x) == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (GET_CODE (x) == MEM) - { - rtx tmp = XEXP (x, 0); -#if ! (defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)) - if (GET_CODE (tmp) != CONST_INT) - { - char *out = XSTR (tmp, 0); - if (out[0] == '*') - { - PUT_ABSOLUTE_PREFIX (file); - fprintf (file, "%s", &out[1]); - } - else - ASM_OUTPUT_LABELREF (file, out); - } - else -#endif - output_address (XEXP (x, 0)); - } - else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) - { - if (GET_MODE (x) == DFmode) - { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX(file); -#ifdef SEQUENT_ASM - /* Sequent likes it's floating point constants as integers */ - fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]); -#else -#ifdef ENCORE_ASM - fprintf (file, "0f%.20e", u.d); -#else - fprintf (file, "0d%.20e", u.d); -#endif -#endif - } - else - { - union { double d; int i[2]; } u; - u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x); - PUT_IMMEDIATE_PREFIX (file); -#ifdef SEQUENT_ASM - /* We have no way of winning if we can't get the bits - for a sequent floating point number. */ -#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT - abort (); -#endif - { - union { float f; long l; } uu; - uu.f = u.d; - fprintf (file, "0Fx%08x", uu.l); - } -#else - fprintf (file, "0f%.20e", u.d); -#endif - } - } - else - { -#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC - if (GET_CODE (x) == CONST_INT) -#endif - PUT_IMMEDIATE_PREFIX (file); - output_addr_const (file, x); - } -} - -/* PRINT_OPERAND_ADDRESS is defined to call this function, - which is easier to debug than putting all the code in - a macro definition in ns32k.h . */ - -/* Completely rewritten to get this to work with Gas for PC532 Mach. - This function didn't work and I just wasn't able (nor very willing) to - figure out how it worked. - 90-11-25 Tatu Yl|nen */ - -print_operand_address (file, addr) - register FILE *file; - register rtx addr; -{ - static char scales[] = { 'b', 'w', 'd', 0, 'q', }; - rtx offset, base, indexexp, tmp; - int scale; - extern int flag_pic; - - if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC) - { - fprintf (file, "tos"); - return; - } - - offset = NULL; - base = NULL; - indexexp = NULL; - while (addr != NULL) - { - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == PLUS) - { - tmp = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else - { - tmp = XEXP (addr,0); - addr = XEXP (addr,1); - } - } - else - { - tmp = addr; - addr = NULL; - } - switch (GET_CODE (tmp)) - { - case PLUS: - abort (); - case MEM: - if (base) - { - indexexp = base; - base = tmp; - } - else - base = tmp; - break; - case REG: - if (REGNO (tmp) < 8) - if (base) - { - indexexp = tmp; - } - else - base = tmp; - else - if (base) - { - indexexp = base; - base = tmp; - } - else - base = tmp; - break; - case MULT: - indexexp = tmp; - break; - case SYMBOL_REF: - if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp) - && ! SYMBOL_REF_FLAG (tmp)) - { - if (base) - { - if (indexexp) - abort (); - indexexp = base; - } - base = tmp; - break; - } - case CONST: - if (flag_pic && GET_CODE (tmp) == CONST) - { - rtx sym, off, tmp1; - tmp1 = XEXP (tmp,0); - if (GET_CODE (tmp1) != PLUS) - abort (); - - sym = XEXP (tmp1,0); - if (GET_CODE (sym) != SYMBOL_REF) - { - off = sym; - sym = XEXP (tmp1,1); - } - else - off = XEXP (tmp1,1); - if (GET_CODE (sym) == SYMBOL_REF) - { - if (GET_CODE (off) != CONST_INT) - abort (); - if (CONSTANT_POOL_ADDRESS_P (sym) - || SYMBOL_REF_FLAG (sym)) - { - SYMBOL_REF_FLAG (tmp) = 1; - } - else - { - if (base) - { - if (indexexp) - abort (); - indexexp = base; - } - if (offset) - abort (); - base = sym; - offset = off; - break; - } - } - } - case CONST_INT: - case LABEL_REF: - if (offset) - offset = gen_rtx (PLUS, SImode, tmp, offset); - else - offset = tmp; - break; - default: - abort (); - } - } - if (! offset) - offset = const0_rtx; - - if (base -#ifndef INDEX_RATHER_THAN_BASE - && flag_pic - && GET_CODE (base) != SYMBOL_REF - && GET_CODE (offset) != CONST_INT -#else - /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix. */ -#endif - && !indexexp && GET_CODE (base) == REG - && REG_OK_FOR_INDEX_P (base)) - { - indexexp = base; - base = NULL; - } - - /* now, offset, base and indexexp are set */ - if (! base) - { -#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC) - if (GET_CODE (offset) == CONST_INT) -/* if (! (GET_CODE (offset) == LABEL_REF - || GET_CODE (offset) == SYMBOL_REF)) */ -#endif - PUT_ABSOLUTE_PREFIX (file); - } - - output_addr_const (file, offset); - if (base) /* base can be (REG ...) or (MEM ...) */ - switch (GET_CODE (base)) - { - /* now we must output base. Possible alternatives are: - (rN) (REG ...) - (sp) (REG ...) - (fp) (REG ...) - (pc) (REG ...) used for SYMBOL_REF and LABEL_REF, output - (disp(fp)) (MEM ...) just before possible [rX:y] - (disp(sp)) (MEM ...) - (disp(sb)) (MEM ...) - */ - case REG: - fprintf (file, "(%s)", reg_names[REGNO (base)]); - break; - case SYMBOL_REF: - if (!flag_pic) - abort (); - fprintf (file, "("); - output_addr_const (file, base); - fprintf (file, "(sb))"); - break; - case MEM: - addr = XEXP(base,0); - base = NULL; - offset = NULL; - while (addr != NULL) - { - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == PLUS) - { - tmp = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - else - { - tmp = XEXP (addr, 0); - addr = XEXP (addr, 1); - } - } - else - { - tmp = addr; - addr = NULL; - } - switch (GET_CODE (tmp)) - { - case REG: - base = tmp; - break; - case CONST: - case CONST_INT: - case SYMBOL_REF: - case LABEL_REF: - if (offset) - offset = gen_rtx (PLUS, SImode, tmp, offset); - else - offset = tmp; - break; - default: - abort (); - } - } - if (! offset) - offset = const0_rtx; - fprintf (file, "("); - output_addr_const (file, offset); - if (base) - fprintf (file, "(%s)", reg_names[REGNO (base)]); -#ifdef BASE_REG_NEEDED - else if (TARGET_SB) - fprintf (file, "(sb)"); - else - abort (); -#endif - fprintf (file, ")"); - break; - - default: - abort (); - } -#ifdef PC_RELATIVE - else if (GET_CODE (offset) == LABEL_REF - || GET_CODE (offset) == SYMBOL_REF - || GET_CODE (offset) == CONST - || GET_CODE (offset) == PLUS) - fprintf (file, "(pc)"); -#endif -#ifdef BASE_REG_NEEDED /* this is defined if the assembler always - needs a base register */ - else - { - /* Abs. addresses don't need a base (I think). */ - if (GET_CODE (offset) != CONST_INT -#ifndef PC_RELATIVE - && GET_CODE (offset) != LABEL_REF - && GET_CODE (offset) != SYMBOL_REF - && GET_CODE (offset) != CONST - && GET_CODE (offset) != PLUS -#endif - ) - { - if (TARGET_SB) - fprintf (file, "(sb)"); - else - abort (); - } - } -#endif - /* now print index if we have one */ - if (indexexp) - { - if (GET_CODE (indexexp) == MULT) - { - scale = INTVAL (XEXP (indexexp, 1)) >> 1; - indexexp = XEXP (indexexp, 0); - } - else - scale = 0; - if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8) - abort (); - -#ifdef UTEK_ASM - fprintf (file, "[%c`%s]", - scales[scale], - reg_names[REGNO (indexexp)]); -#else - fprintf (file, "[%s:%c]", - reg_names[REGNO (indexexp)], - scales[scale]); -#endif - } -} - -/* National 32032 shifting is so bad that we can get - better performance in many common cases by using other - techniques. */ -char * -output_shift_insn (operands) - rtx *operands; -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) > 0 - && INTVAL (operands[2]) <= 3) - if (GET_CODE (operands[0]) == REG) - { - if (GET_CODE (operands[1]) == REG) - { - if (REGNO (operands[0]) == REGNO (operands[1])) - { - if (operands[2] == const1_rtx) - return "addd %0,%0"; - else if (INTVAL (operands[2]) == 2) - return "addd %0,%0\n\taddd %0,%0"; - } - if (operands[2] == const1_rtx) - return "movd %1,%0\n\taddd %0,%0"; - - operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); - return "addr %a1,%0"; - } - if (operands[2] == const1_rtx) - return "movd %1,%0\n\taddd %0,%0"; - } - else if (GET_CODE (operands[1]) == REG) - { - operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]); - return "addr %a1,%0"; - } - else if (INTVAL (operands[2]) == 1 - && GET_CODE (operands[1]) == MEM - && rtx_equal_p (operands [0], operands[1])) - { - rtx temp = XEXP (operands[1], 0); - - if (GET_CODE (temp) == REG - || (GET_CODE (temp) == PLUS - && GET_CODE (XEXP (temp, 0)) == REG - && GET_CODE (XEXP (temp, 1)) == CONST_INT)) - return "addd %0,%0"; - } - else return "ashd %2,%0"; - return "ashd %2,%0"; -} - -char * -output_move_dconst (n, s) - int n; char *s; -{ - static char r[32]; - - if (n > -9 && n < 8) - strcpy(r, "movqd "); - else if (n > 0 && n < 256) - strcpy(r, "movzbd "); - else if (n > 0 && n < 65536) - strcpy(r, "movzwd "); - else if (n < 0 && n > -129) - strcpy(r, "movxbd "); - else if (n < 0 && n > -32769) - strcpy(r, "movxwd "); - else - strcpy(r, "movd "); - strcat(r, s); - return(r); -} diff --git a/gnu/usr.bin/gcc2/arch/ns32k/config.h b/gnu/usr.bin/gcc2/arch/ns32k/config.h deleted file mode 100644 index 14ab023b766..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/config.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Configuration for GNU C-compiler for the ns32532. - Copyright (C) 1987, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: config.h,v 1.1.1.1 1995/10/18 08:39:21 deraadt Exp $ -*/ - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* NetBSD does have atexit. */ - -#define HAVE_ATEXIT - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-attr.h b/gnu/usr.bin/gcc2/arch/ns32k/insn-attr.h deleted file mode 100644 index 5fe9a2f8001..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-attr.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Generated automatically by the program `genattr' -from the machine description file `md'. */ - -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif -#define HAVE_ATTR_alternative -#define get_attr_alternative(insn) which_alternative - -#define ATTR_FLAG_forward 0x1 -#define ATTR_FLAG_backward 0x2 -#define ATTR_FLAG_likely 0x4 -#define ATTR_FLAG_very_likely 0x8 -#define ATTR_FLAG_unlikely 0x10 -#define ATTR_FLAG_very_unlikely 0x20 diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-attrtab.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-attrtab.c deleted file mode 100644 index 0e86d1f4c35..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-attrtab.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Generated automatically by the program `genattrtab' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "regs.h" -#include "real.h" -#include "output.h" -#include "insn-attr.h" - -#define operands recog_operand - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-codes.h b/gnu/usr.bin/gcc2/arch/ns32k/insn-codes.h deleted file mode 100644 index 692c1ae8920..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-codes.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Generated automatically by the program `gencodes' -from the machine description file `md'. */ - -#ifndef MAX_INSN_CODE - -enum insn_code { - CODE_FOR_tstsi = 0, - CODE_FOR_tsthi = 1, - CODE_FOR_tstqi = 2, - CODE_FOR_tstdf = 3, - CODE_FOR_tstsf = 4, - CODE_FOR_cmpsi = 5, - CODE_FOR_cmphi = 6, - CODE_FOR_cmpqi = 7, - CODE_FOR_cmpdf = 8, - CODE_FOR_cmpsf = 9, - CODE_FOR_movdf = 10, - CODE_FOR_movsf = 11, - CODE_FOR_movdi = 13, - CODE_FOR_movsi = 15, - CODE_FOR_movhi = 16, - CODE_FOR_movstricthi = 17, - CODE_FOR_movqi = 18, - CODE_FOR_movstrictqi = 19, - CODE_FOR_movstrsi = 20, - CODE_FOR_movstrsi1 = 21, - CODE_FOR_truncsiqi2 = 22, - CODE_FOR_truncsihi2 = 23, - CODE_FOR_trunchiqi2 = 24, - CODE_FOR_extendhisi2 = 25, - CODE_FOR_extendqihi2 = 26, - CODE_FOR_extendqisi2 = 27, - CODE_FOR_extendsfdf2 = 28, - CODE_FOR_truncdfsf2 = 29, - CODE_FOR_zero_extendhisi2 = 30, - CODE_FOR_zero_extendqihi2 = 31, - CODE_FOR_zero_extendqisi2 = 32, - CODE_FOR_floatsisf2 = 33, - CODE_FOR_floatsidf2 = 34, - CODE_FOR_floathisf2 = 35, - CODE_FOR_floathidf2 = 36, - CODE_FOR_floatqisf2 = 37, - CODE_FOR_fixsfqi2 = 38, - CODE_FOR_fixsfhi2 = 39, - CODE_FOR_fixsfsi2 = 40, - CODE_FOR_fixdfqi2 = 41, - CODE_FOR_fixdfhi2 = 42, - CODE_FOR_fixdfsi2 = 43, - CODE_FOR_fixunssfqi2 = 44, - CODE_FOR_fixunssfhi2 = 45, - CODE_FOR_fixunssfsi2 = 46, - CODE_FOR_fixunsdfqi2 = 47, - CODE_FOR_fixunsdfhi2 = 48, - CODE_FOR_fixunsdfsi2 = 49, - CODE_FOR_fix_truncsfqi2 = 50, - CODE_FOR_fix_truncsfhi2 = 51, - CODE_FOR_fix_truncsfsi2 = 52, - CODE_FOR_fix_truncdfqi2 = 53, - CODE_FOR_fix_truncdfhi2 = 54, - CODE_FOR_fix_truncdfsi2 = 55, - CODE_FOR_adddf3 = 56, - CODE_FOR_addsf3 = 57, - CODE_FOR_addsi3 = 61, - CODE_FOR_addhi3 = 62, - CODE_FOR_addqi3 = 64, - CODE_FOR_subdf3 = 66, - CODE_FOR_subsf3 = 67, - CODE_FOR_subsi3 = 69, - CODE_FOR_subhi3 = 70, - CODE_FOR_subqi3 = 72, - CODE_FOR_muldf3 = 74, - CODE_FOR_mulsf3 = 75, - CODE_FOR_mulsi3 = 76, - CODE_FOR_mulhi3 = 77, - CODE_FOR_mulqi3 = 78, - CODE_FOR_umulsidi3 = 79, - CODE_FOR_divdf3 = 80, - CODE_FOR_divsf3 = 81, - CODE_FOR_divsi3 = 82, - CODE_FOR_divhi3 = 83, - CODE_FOR_divqi3 = 84, - CODE_FOR_udivsi3 = 85, - CODE_FOR_udivhi3 = 86, - CODE_FOR_udivqi3 = 87, - CODE_FOR_modsi3 = 88, - CODE_FOR_modhi3 = 89, - CODE_FOR_modqi3 = 90, - CODE_FOR_umodsi3 = 91, - CODE_FOR_umodhi3 = 92, - CODE_FOR_umodqi3 = 93, - CODE_FOR_andsi3 = 94, - CODE_FOR_andhi3 = 95, - CODE_FOR_andqi3 = 96, - CODE_FOR_iorsi3 = 100, - CODE_FOR_iorhi3 = 101, - CODE_FOR_iorqi3 = 102, - CODE_FOR_xorsi3 = 103, - CODE_FOR_xorhi3 = 104, - CODE_FOR_xorqi3 = 105, - CODE_FOR_negdf2 = 106, - CODE_FOR_negsf2 = 107, - CODE_FOR_negsi2 = 108, - CODE_FOR_neghi2 = 109, - CODE_FOR_negqi2 = 110, - CODE_FOR_one_cmplsi2 = 111, - CODE_FOR_one_cmplhi2 = 112, - CODE_FOR_one_cmplqi2 = 113, - CODE_FOR_ashlsi3 = 114, - CODE_FOR_ashlhi3 = 115, - CODE_FOR_ashlqi3 = 116, - CODE_FOR_ashrsi3 = 117, - CODE_FOR_ashrhi3 = 120, - CODE_FOR_ashrqi3 = 123, - CODE_FOR_lshlsi3 = 126, - CODE_FOR_lshlhi3 = 127, - CODE_FOR_lshlqi3 = 128, - CODE_FOR_lshrsi3 = 129, - CODE_FOR_lshrhi3 = 132, - CODE_FOR_lshrqi3 = 135, - CODE_FOR_rotlsi3 = 138, - CODE_FOR_rotlhi3 = 139, - CODE_FOR_rotlqi3 = 140, - CODE_FOR_rotrsi3 = 141, - CODE_FOR_rotrhi3 = 144, - CODE_FOR_rotrqi3 = 147, - CODE_FOR_extzv = 158, - CODE_FOR_insv = 161, - CODE_FOR_jump = 162, - CODE_FOR_beq = 163, - CODE_FOR_bne = 164, - CODE_FOR_bgt = 165, - CODE_FOR_bgtu = 166, - CODE_FOR_blt = 167, - CODE_FOR_bltu = 168, - CODE_FOR_bge = 169, - CODE_FOR_bgeu = 170, - CODE_FOR_ble = 171, - CODE_FOR_bleu = 172, - CODE_FOR_call = 185, - CODE_FOR_call_value = 186, - CODE_FOR_untyped_call = 187, - CODE_FOR_blockage = 188, - CODE_FOR_return = 189, - CODE_FOR_abssf2 = 190, - CODE_FOR_absdf2 = 191, - CODE_FOR_abssi2 = 192, - CODE_FOR_abshi2 = 193, - CODE_FOR_absqi2 = 194, - CODE_FOR_nop = 195, - CODE_FOR_indirect_jump = 196, - CODE_FOR_tablejump = 197, - CODE_FOR_seq = 198, - CODE_FOR_sne = 201, - CODE_FOR_sgt = 204, - CODE_FOR_sgtu = 207, - CODE_FOR_slt = 210, - CODE_FOR_sltu = 213, - CODE_FOR_sge = 216, - CODE_FOR_sgeu = 219, - CODE_FOR_sle = 222, - CODE_FOR_sleu = 225, - CODE_FOR_ffsqi2 = 228, - CODE_FOR_ffshi2 = 229, - CODE_FOR_ffssi2 = 230, - CODE_FOR_nothing }; - -#define MAX_INSN_CODE ((int) CODE_FOR_nothing) -#endif /* MAX_INSN_CODE */ diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-config.h b/gnu/usr.bin/gcc2/arch/ns32k/insn-config.h deleted file mode 100644 index 7dba8866f62..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-config.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Generated automatically by the program `genconfig' -from the machine description file `md'. */ - - -#define MAX_RECOG_OPERANDS 10 - -#define MAX_DUP_OPERANDS 3 -#ifndef MAX_INSNS_PER_SPLIT -#define MAX_INSNS_PER_SPLIT 1 -#endif -#define REGISTER_CONSTRAINTS -#define HAVE_cc0 diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-emit.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-emit.c deleted file mode 100644 index d05df59e584..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-emit.c +++ /dev/null @@ -1,1579 +0,0 @@ -/* Generated automatically by the program `genemit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "expr.h" -#include "real.h" -#include "output.h" -#include "insn-config.h" - -#include "insn-flags.h" - -#include "insn-codes.h" - -extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS]; - -extern rtx recog_operand[]; -#define operands emit_operand - -#define FAIL goto _fail - -#define DONE goto _done - -rtx -gen_tstsi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tsthi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tstqi (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tstdf (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_tstsf (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, operand0); -} - -rtx -gen_cmpsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmphi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmpqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmpdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_cmpsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, operand0, operand1)); -} - -rtx -gen_movdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movdi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movhi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movstricthi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand0), operand1); -} - -rtx -gen_movqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, operand1); -} - -rtx -gen_movstrictqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (STRICT_LOW_PART, VOIDmode, operand0), operand1); -} - -rtx -gen_movstrsi (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - rtx operands[4]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - operands[3] = operand3; - - emit_insn (gen_movstrsi1 (operands[0], operands[1], operands[2])); - DONE; - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - emit_insn (gen_rtx (USE, VOIDmode, operand2)); - emit (operand3); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movstrsi1 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5, - gen_rtx (SET, VOIDmode, operand0, operand1), - gen_rtx (USE, VOIDmode, operand2), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 2)))); -} - -rtx -gen_truncsiqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, QImode, operand1)); -} - -rtx -gen_truncsihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, HImode, operand1)); -} - -rtx -gen_trunchiqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (TRUNCATE, QImode, operand1)); -} - -rtx -gen_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1)); -} - -rtx -gen_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, HImode, operand1)); -} - -rtx -gen_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1)); -} - -rtx -gen_extendsfdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, DFmode, operand1)); -} - -rtx -gen_truncdfsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, SFmode, operand1)); -} - -rtx -gen_zero_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, SImode, operand1)); -} - -rtx -gen_zero_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, HImode, operand1)); -} - -rtx -gen_zero_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, SImode, operand1)); -} - -rtx -gen_floatsisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floatsidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_floathisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floathidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_floatqisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_fixsfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixsfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixsfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixdfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fixdfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fixdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fixunssfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, QImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixunssfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, HImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixunssfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, SImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fixunsdfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, QImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fixunsdfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, HImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fixunsdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UNSIGNED_FIX, SImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fix_truncsfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, operand1)); -} - -rtx -gen_fix_truncsfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, operand1)); -} - -rtx -gen_fix_truncsfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, operand1)); -} - -rtx -gen_fix_truncdfqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, QImode, operand1)); -} - -rtx -gen_fix_truncdfhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, HImode, operand1)); -} - -rtx -gen_fix_truncdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, operand1)); -} - -rtx -gen_adddf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, DFmode, operand1, operand2)); -} - -rtx -gen_addsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SFmode, operand1, operand2)); -} - -rtx -gen_addsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, operand1, operand2)); -} - -rtx -gen_addhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, HImode, operand1, operand2)); -} - -rtx -gen_addqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, QImode, operand1, operand2)); -} - -rtx -gen_subdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, DFmode, operand1, operand2)); -} - -rtx -gen_subsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SFmode, operand1, operand2)); -} - -rtx -gen_subsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SImode, operand1, operand2)); -} - -rtx -gen_subhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, HImode, operand1, operand2)); -} - -rtx -gen_subqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, QImode, operand1, operand2)); -} - -rtx -gen_muldf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DFmode, operand1, operand2)); -} - -rtx -gen_mulsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SFmode, operand1, operand2)); -} - -rtx -gen_mulsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SImode, operand1, operand2)); -} - -rtx -gen_mulhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, HImode, operand1, operand2)); -} - -rtx -gen_mulqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, QImode, operand1, operand2)); -} - -rtx -gen_umulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DImode, gen_rtx (ZERO_EXTEND, DImode, operand1), gen_rtx (ZERO_EXTEND, DImode, operand2))); -} - -rtx -gen_divdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, DFmode, operand1, operand2)); -} - -rtx -gen_divsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SFmode, operand1, operand2)); -} - -rtx -gen_divsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SImode, operand1, operand2)); -} - -rtx -gen_divhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, HImode, operand1, operand2)); -} - -rtx -gen_divqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, QImode, operand1, operand2)); -} - -rtx -gen_udivsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, SImode, gen_rtx (SUBREG, SImode, operand1, 0), operand2)); -} - -rtx -gen_udivhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, HImode, gen_rtx (SUBREG, HImode, operand1, 0), operand2)); -} - -rtx -gen_udivqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, QImode, gen_rtx (SUBREG, QImode, operand1, 0), operand2)); -} - -rtx -gen_modsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MOD, SImode, operand1, operand2)); -} - -rtx -gen_modhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MOD, HImode, operand1, operand2)); -} - -rtx -gen_modqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MOD, QImode, operand1, operand2)); -} - -rtx -gen_umodsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UMOD, SImode, gen_rtx (SUBREG, SImode, operand1, 0), operand2)); -} - -rtx -gen_umodhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UMOD, HImode, gen_rtx (SUBREG, HImode, operand1, 0), operand2)); -} - -rtx -gen_umodqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UMOD, QImode, gen_rtx (SUBREG, QImode, operand1, 0), operand2)); -} - -rtx -gen_andsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, SImode, operand1, operand2)); -} - -rtx -gen_andhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, HImode, operand1, operand2)); -} - -rtx -gen_andqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, QImode, operand1, operand2)); -} - -rtx -gen_iorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, SImode, operand1, operand2)); -} - -rtx -gen_iorhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, HImode, operand1, operand2)); -} - -rtx -gen_iorqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, QImode, operand1, operand2)); -} - -rtx -gen_xorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, SImode, operand1, operand2)); -} - -rtx -gen_xorhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, HImode, operand1, operand2)); -} - -rtx -gen_xorqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, QImode, operand1, operand2)); -} - -rtx -gen_negdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, DFmode, operand1)); -} - -rtx -gen_negsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SFmode, operand1)); -} - -rtx -gen_negsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SImode, operand1)); -} - -rtx -gen_neghi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, HImode, operand1)); -} - -rtx -gen_negqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, QImode, operand1)); -} - -rtx -gen_one_cmplsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, SImode, operand1)); -} - -rtx -gen_one_cmplhi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, HImode, operand1)); -} - -rtx -gen_one_cmplqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, QImode, operand1)); -} - -rtx -gen_ashlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, SImode, operand1, operand2)); -} - -rtx -gen_ashlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, HImode, operand1, operand2)); -} - -rtx -gen_ashlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, QImode, operand1, operand2)); -} - -rtx -gen_ashrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, SImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_ashrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, HImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_ashrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, QImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_lshlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, SImode, operand1, operand2)); -} - -rtx -gen_lshlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, HImode, operand1, operand2)); -} - -rtx -gen_lshlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, QImode, operand1, operand2)); -} - -rtx -gen_lshrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, SImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_lshrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, HImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_lshrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, QImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_rotlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, SImode, operand1, operand2)); -} - -rtx -gen_rotlhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, HImode, operand1, operand2)); -} - -rtx -gen_rotlqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATE, QImode, operand1, operand2)); -} - -rtx -gen_rotrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, SImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_rotrhi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, HImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_rotrqi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ROTATERT, QImode, operand1, operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extzv (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTRACT, SImode, operand1, operand2, operand3)); -} - -rtx -gen_insv (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - return gen_rtx (SET, VOIDmode, gen_rtx (ZERO_EXTRACT, SImode, operand0, operand1, operand2), operand3); -} - -rtx -gen_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, operand0)); -} - -rtx -gen_beq (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (EQ, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bne (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (NE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GT, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgtu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GTU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_blt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LT, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bltu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LTU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bge (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bgeu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GEU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_ble (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LE, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_bleu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LEU, VOIDmode, cc0_rtx, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx)); -} - -rtx -gen_call (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (CALL, VOIDmode, operand0, operand1); -} - -rtx -gen_call_value (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (CALL, VOIDmode, operand1, operand2)); -} - -rtx -gen_untyped_call (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (CALL, VOIDmode, operand0, const0_rtx), - operand1, - operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_blockage () -{ - return gen_rtx (UNSPEC_VOLATILE, VOIDmode, gen_rtvec (1, - const0_rtx), 0); -} - -rtx -gen_return () -{ - return gen_rtx (RETURN, VOIDmode); -} - -rtx -gen_abssf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, SFmode, operand1)); -} - -rtx -gen_absdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, DFmode, operand1)); -} - -rtx -gen_abssi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, SImode, operand1)); -} - -rtx -gen_abshi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, HImode, operand1)); -} - -rtx -gen_absqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, QImode, operand1)); -} - -rtx -gen_nop () -{ - return const0_rtx; -} - -rtx -gen_indirect_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, operand0); -} - -rtx -gen_tablejump (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (PLUS, SImode, pc_rtx, operand0)), - gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, operand1)))); -} - -rtx -gen_seq (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (EQ, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sne (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NE, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GT, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgtu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GTU, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_slt (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LT, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sltu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LTU, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sge (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GE, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sgeu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (GEU, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sle (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LE, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_sleu (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LEU, SImode, cc0_rtx, const0_rtx)); -} - -rtx -gen_ffsqi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FFS, QImode, operand1)); -} - -rtx -gen_ffshi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FFS, HImode, operand1)); -} - -rtx -gen_ffssi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FFS, SImode, operand1)); -} - - - -void -add_clobbers (pattern, insn_code_number) - rtx pattern; - int insn_code_number; -{ - int i; - - switch (insn_code_number) - { - case 21: - XVECEXP (pattern, 0, 2) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)); - XVECEXP (pattern, 0, 3) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 1)); - XVECEXP (pattern, 0, 4) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 2)); - break; - - default: - abort (); - } -} diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-extract.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-extract.c deleted file mode 100644 index bf5ac5a96cb..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-extract.c +++ /dev/null @@ -1,397 +0,0 @@ -/* Generated automatically by the program `genextract' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" - -static rtx junk; -extern rtx recog_operand[]; -extern rtx *recog_operand_loc[]; -extern rtx *recog_dup_loc[]; -extern char recog_dup_num[]; -extern -#ifdef __GNUC__ -__volatile__ -#endif -void fatal_insn_not_found (); - -void -insn_extract (insn) - rtx insn; -{ - register rtx *ro = recog_operand; - register rtx **ro_loc = recog_operand_loc; - rtx pat = PATTERN (insn); - switch (INSN_CODE (insn)) - { - case -1: - fatal_insn_not_found (insn); - - case 236: - case 235: - case 234: - case 233: - case 232: - case 231: -#if __GNUC__ > 1 && !defined (bcopy) -#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#endif - bcopy (&XVECEXP (pat, 0, 0), ro, - sizeof (rtx) * XVECLEN (pat, 0)); - break; - - case 227: - case 226: - case 225: - case 224: - case 223: - case 222: - case 221: - case 220: - case 219: - case 218: - case 217: - case 216: - case 215: - case 214: - case 213: - case 212: - case 211: - case 210: - case 209: - case 208: - case 207: - case 206: - case 205: - case 204: - case 203: - case 202: - case 201: - case 200: - case 199: - case 198: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - break; - - case 197: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0)); - break; - - case 195: - case 189: - case 188: - break; - - case 184: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0); - recog_dup_num[0] = 0; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[1] = 0; - break; - - case 183: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0); - recog_dup_num[0] = 0; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[1] = 0; - recog_dup_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1); - recog_dup_num[2] = 1; - break; - - case 182: - case 181: - case 180: - case 179: - case 178: - case 177: - case 176: - case 175: - case 174: - case 173: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 2), 0)); - break; - - case 172: - case 171: - case 170: - case 169: - case 168: - case 167: - case 166: - case 165: - case 164: - case 163: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 162: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 161: - case 160: - case 159: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 0), 2)); - ro[3] = *(ro_loc[3] = &XEXP (pat, 1)); - break; - - case 158: - case 157: - case 156: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (pat, 1), 2)); - break; - - case 155: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 2)); - break; - - case 154: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 0), 0), 1)); - recog_dup_loc[0] = &XEXP (XEXP (pat, 1), 1); - recog_dup_num[0] = 0; - break; - - case 153: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - recog_dup_loc[0] = &XEXP (XEXP (pat, 1), 1); - recog_dup_num[0] = 0; - break; - - case 152: - case 151: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 0), 2)); - break; - - case 149: - case 146: - case 143: - case 137: - case 134: - case 131: - case 125: - case 122: - case 119: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 99: - case 98: - case 97: - case 93: - case 92: - case 91: - case 87: - case 86: - case 85: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 79: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 73: - case 71: - case 65: - case 63: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 60: - case 59: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 68: - case 58: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 186: - case 148: - case 145: - case 142: - case 140: - case 139: - case 138: - case 136: - case 133: - case 130: - case 128: - case 127: - case 126: - case 124: - case 121: - case 118: - case 116: - case 115: - case 114: - case 105: - case 104: - case 103: - case 102: - case 101: - case 100: - case 96: - case 95: - case 94: - case 90: - case 89: - case 88: - case 84: - case 83: - case 82: - case 81: - case 80: - case 78: - case 77: - case 76: - case 75: - case 74: - case 72: - case 70: - case 69: - case 67: - case 66: - case 64: - case 62: - case 61: - case 57: - case 56: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 49: - case 48: - case 47: - case 46: - case 45: - case 44: - case 43: - case 42: - case 41: - case 40: - case 39: - case 38: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - break; - - case 230: - case 229: - case 228: - case 194: - case 193: - case 192: - case 191: - case 190: - case 113: - case 112: - case 111: - case 110: - case 109: - case 108: - case 107: - case 106: - case 55: - case 54: - case 53: - case 52: - case 51: - case 50: - case 37: - case 36: - case 35: - case 34: - case 33: - case 32: - case 31: - case 30: - case 29: - case 28: - case 27: - case 26: - case 25: - case 24: - case 23: - case 22: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 21: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 19: - case 17: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (pat, 1)); - break; - - case 185: - case 150: - case 18: - case 16: - case 15: - case 13: - case 12: - case 11: - case 10: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (pat, 1)); - break; - - case 9: - case 8: - case 7: - case 6: - case 5: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 196: - case 14: - case 4: - case 3: - case 2: - case 1: - case 0: - ro[0] = *(ro_loc[0] = &XEXP (pat, 1)); - break; - - default: - abort (); - } -} diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-flags.h b/gnu/usr.bin/gcc2/arch/ns32k/insn-flags.h deleted file mode 100644 index 7a264cc0669..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-flags.h +++ /dev/null @@ -1,489 +0,0 @@ -/* Generated automatically by the program `genflags' -from the machine description file `md'. */ - -#define HAVE_tstsi 1 -#define HAVE_tsthi 1 -#define HAVE_tstqi 1 -#define HAVE_tstdf (TARGET_32081) -#define HAVE_tstsf (TARGET_32081) -#define HAVE_cmpsi 1 -#define HAVE_cmphi 1 -#define HAVE_cmpqi 1 -#define HAVE_cmpdf (TARGET_32081) -#define HAVE_cmpsf (TARGET_32081) -#define HAVE_movdf 1 -#define HAVE_movsf 1 -#define HAVE_movdi 1 -#define HAVE_movsi 1 -#define HAVE_movhi 1 -#define HAVE_movstricthi 1 -#define HAVE_movqi 1 -#define HAVE_movstrictqi 1 -#define HAVE_movstrsi 1 -#define HAVE_movstrsi1 1 -#define HAVE_truncsiqi2 1 -#define HAVE_truncsihi2 1 -#define HAVE_trunchiqi2 1 -#define HAVE_extendhisi2 1 -#define HAVE_extendqihi2 1 -#define HAVE_extendqisi2 1 -#define HAVE_extendsfdf2 (TARGET_32081) -#define HAVE_truncdfsf2 (TARGET_32081) -#define HAVE_zero_extendhisi2 1 -#define HAVE_zero_extendqihi2 1 -#define HAVE_zero_extendqisi2 1 -#define HAVE_floatsisf2 (TARGET_32081) -#define HAVE_floatsidf2 (TARGET_32081) -#define HAVE_floathisf2 (TARGET_32081) -#define HAVE_floathidf2 (TARGET_32081) -#define HAVE_floatqisf2 (TARGET_32081) -#define HAVE_fixsfqi2 (TARGET_32081) -#define HAVE_fixsfhi2 (TARGET_32081) -#define HAVE_fixsfsi2 (TARGET_32081) -#define HAVE_fixdfqi2 (TARGET_32081) -#define HAVE_fixdfhi2 (TARGET_32081) -#define HAVE_fixdfsi2 (TARGET_32081) -#define HAVE_fixunssfqi2 (TARGET_32081) -#define HAVE_fixunssfhi2 (TARGET_32081) -#define HAVE_fixunssfsi2 (TARGET_32081) -#define HAVE_fixunsdfqi2 (TARGET_32081) -#define HAVE_fixunsdfhi2 (TARGET_32081) -#define HAVE_fixunsdfsi2 (TARGET_32081) -#define HAVE_fix_truncsfqi2 (TARGET_32081) -#define HAVE_fix_truncsfhi2 (TARGET_32081) -#define HAVE_fix_truncsfsi2 (TARGET_32081) -#define HAVE_fix_truncdfqi2 (TARGET_32081) -#define HAVE_fix_truncdfhi2 (TARGET_32081) -#define HAVE_fix_truncdfsi2 (TARGET_32081) -#define HAVE_adddf3 (TARGET_32081) -#define HAVE_addsf3 (TARGET_32081) -#define HAVE_addsi3 1 -#define HAVE_addhi3 1 -#define HAVE_addqi3 1 -#define HAVE_subdf3 (TARGET_32081) -#define HAVE_subsf3 (TARGET_32081) -#define HAVE_subsi3 1 -#define HAVE_subhi3 1 -#define HAVE_subqi3 1 -#define HAVE_muldf3 (TARGET_32081) -#define HAVE_mulsf3 (TARGET_32081) -#define HAVE_mulsi3 1 -#define HAVE_mulhi3 1 -#define HAVE_mulqi3 1 -#define HAVE_umulsidi3 1 -#define HAVE_divdf3 (TARGET_32081) -#define HAVE_divsf3 (TARGET_32081) -#define HAVE_divsi3 1 -#define HAVE_divhi3 1 -#define HAVE_divqi3 1 -#define HAVE_udivsi3 1 -#define HAVE_udivhi3 1 -#define HAVE_udivqi3 1 -#define HAVE_modsi3 1 -#define HAVE_modhi3 1 -#define HAVE_modqi3 1 -#define HAVE_umodsi3 1 -#define HAVE_umodhi3 1 -#define HAVE_umodqi3 1 -#define HAVE_andsi3 1 -#define HAVE_andhi3 1 -#define HAVE_andqi3 1 -#define HAVE_iorsi3 1 -#define HAVE_iorhi3 1 -#define HAVE_iorqi3 1 -#define HAVE_xorsi3 1 -#define HAVE_xorhi3 1 -#define HAVE_xorqi3 1 -#define HAVE_negdf2 (TARGET_32081) -#define HAVE_negsf2 (TARGET_32081) -#define HAVE_negsi2 1 -#define HAVE_neghi2 1 -#define HAVE_negqi2 1 -#define HAVE_one_cmplsi2 1 -#define HAVE_one_cmplhi2 1 -#define HAVE_one_cmplqi2 1 -#define HAVE_ashlsi3 1 -#define HAVE_ashlhi3 1 -#define HAVE_ashlqi3 1 -#define HAVE_ashrsi3 1 -#define HAVE_ashrhi3 1 -#define HAVE_ashrqi3 1 -#define HAVE_lshlsi3 1 -#define HAVE_lshlhi3 1 -#define HAVE_lshlqi3 1 -#define HAVE_lshrsi3 1 -#define HAVE_lshrhi3 1 -#define HAVE_lshrqi3 1 -#define HAVE_rotlsi3 1 -#define HAVE_rotlhi3 1 -#define HAVE_rotlqi3 1 -#define HAVE_rotrsi3 1 -#define HAVE_rotrhi3 1 -#define HAVE_rotrqi3 1 -#define HAVE_extzv (! TARGET_32532) -#define HAVE_insv 1 -#define HAVE_jump 1 -#define HAVE_beq 1 -#define HAVE_bne 1 -#define HAVE_bgt 1 -#define HAVE_bgtu 1 -#define HAVE_blt 1 -#define HAVE_bltu 1 -#define HAVE_bge 1 -#define HAVE_bgeu 1 -#define HAVE_ble 1 -#define HAVE_bleu 1 -#define HAVE_call 1 -#define HAVE_call_value 1 -#define HAVE_untyped_call 1 -#define HAVE_blockage 1 -#define HAVE_return (0) -#define HAVE_abssf2 (TARGET_32081) -#define HAVE_absdf2 (TARGET_32081) -#define HAVE_abssi2 1 -#define HAVE_abshi2 1 -#define HAVE_absqi2 1 -#define HAVE_nop 1 -#define HAVE_indirect_jump 1 -#define HAVE_tablejump 1 -#define HAVE_seq 1 -#define HAVE_sne 1 -#define HAVE_sgt 1 -#define HAVE_sgtu 1 -#define HAVE_slt 1 -#define HAVE_sltu 1 -#define HAVE_sge 1 -#define HAVE_sgeu 1 -#define HAVE_sle 1 -#define HAVE_sleu 1 -#define HAVE_ffsqi2 1 -#define HAVE_ffshi2 1 -#define HAVE_ffssi2 1 - -#ifndef NO_MD_PROTOTYPES -extern rtx gen_tstsi PROTO((rtx)); -extern rtx gen_tsthi PROTO((rtx)); -extern rtx gen_tstqi PROTO((rtx)); -extern rtx gen_tstdf PROTO((rtx)); -extern rtx gen_tstsf PROTO((rtx)); -extern rtx gen_cmpsi PROTO((rtx, rtx)); -extern rtx gen_cmphi PROTO((rtx, rtx)); -extern rtx gen_cmpqi PROTO((rtx, rtx)); -extern rtx gen_cmpdf PROTO((rtx, rtx)); -extern rtx gen_cmpsf PROTO((rtx, rtx)); -extern rtx gen_movdf PROTO((rtx, rtx)); -extern rtx gen_movsf PROTO((rtx, rtx)); -extern rtx gen_movdi PROTO((rtx, rtx)); -extern rtx gen_movsi PROTO((rtx, rtx)); -extern rtx gen_movhi PROTO((rtx, rtx)); -extern rtx gen_movstricthi PROTO((rtx, rtx)); -extern rtx gen_movqi PROTO((rtx, rtx)); -extern rtx gen_movstrictqi PROTO((rtx, rtx)); -extern rtx gen_movstrsi PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_movstrsi1 PROTO((rtx, rtx, rtx)); -extern rtx gen_truncsiqi2 PROTO((rtx, rtx)); -extern rtx gen_truncsihi2 PROTO((rtx, rtx)); -extern rtx gen_trunchiqi2 PROTO((rtx, rtx)); -extern rtx gen_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_extendsfdf2 PROTO((rtx, rtx)); -extern rtx gen_truncdfsf2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_floatsisf2 PROTO((rtx, rtx)); -extern rtx gen_floatsidf2 PROTO((rtx, rtx)); -extern rtx gen_floathisf2 PROTO((rtx, rtx)); -extern rtx gen_floathidf2 PROTO((rtx, rtx)); -extern rtx gen_floatqisf2 PROTO((rtx, rtx)); -extern rtx gen_fixsfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixsfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixsfsi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixdfsi2 PROTO((rtx, rtx)); -extern rtx gen_fixunssfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixunssfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixunssfsi2 PROTO((rtx, rtx)); -extern rtx gen_fixunsdfqi2 PROTO((rtx, rtx)); -extern rtx gen_fixunsdfhi2 PROTO((rtx, rtx)); -extern rtx gen_fixunsdfsi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncsfqi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncsfhi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncsfsi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfqi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfhi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfsi2 PROTO((rtx, rtx)); -extern rtx gen_adddf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_muldf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_modsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_modhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_modqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umodsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umodhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umodqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_negdf2 PROTO((rtx, rtx)); -extern rtx gen_negsf2 PROTO((rtx, rtx)); -extern rtx gen_negsi2 PROTO((rtx, rtx)); -extern rtx gen_neghi2 PROTO((rtx, rtx)); -extern rtx gen_negqi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplsi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplhi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplqi2 PROTO((rtx, rtx)); -extern rtx gen_ashlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotlqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrhi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_rotrqi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_extzv PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_insv PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_jump PROTO((rtx)); -extern rtx gen_beq PROTO((rtx)); -extern rtx gen_bne PROTO((rtx)); -extern rtx gen_bgt PROTO((rtx)); -extern rtx gen_bgtu PROTO((rtx)); -extern rtx gen_blt PROTO((rtx)); -extern rtx gen_bltu PROTO((rtx)); -extern rtx gen_bge PROTO((rtx)); -extern rtx gen_bgeu PROTO((rtx)); -extern rtx gen_ble PROTO((rtx)); -extern rtx gen_bleu PROTO((rtx)); -extern rtx gen_untyped_call PROTO((rtx, rtx, rtx)); -extern rtx gen_blockage PROTO((void)); -extern rtx gen_return PROTO((void)); -extern rtx gen_abssf2 PROTO((rtx, rtx)); -extern rtx gen_absdf2 PROTO((rtx, rtx)); -extern rtx gen_abssi2 PROTO((rtx, rtx)); -extern rtx gen_abshi2 PROTO((rtx, rtx)); -extern rtx gen_absqi2 PROTO((rtx, rtx)); -extern rtx gen_nop PROTO((void)); -extern rtx gen_indirect_jump PROTO((rtx)); -extern rtx gen_tablejump PROTO((rtx, rtx)); -extern rtx gen_seq PROTO((rtx)); -extern rtx gen_sne PROTO((rtx)); -extern rtx gen_sgt PROTO((rtx)); -extern rtx gen_sgtu PROTO((rtx)); -extern rtx gen_slt PROTO((rtx)); -extern rtx gen_sltu PROTO((rtx)); -extern rtx gen_sge PROTO((rtx)); -extern rtx gen_sgeu PROTO((rtx)); -extern rtx gen_sle PROTO((rtx)); -extern rtx gen_sleu PROTO((rtx)); -extern rtx gen_ffsqi2 PROTO((rtx, rtx)); -extern rtx gen_ffshi2 PROTO((rtx, rtx)); -extern rtx gen_ffssi2 PROTO((rtx, rtx)); - -#ifdef MD_CALL_PROTOTYPES -extern rtx gen_call PROTO((rtx, rtx)); -extern rtx gen_call_value PROTO((rtx, rtx, rtx)); - -#else /* !MD_CALL_PROTOTYPES */ -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* !MD_CALL_PROTOTYPES */ - -#else /* NO_MD_PROTOTYPES */ -extern rtx gen_tstsi (); -extern rtx gen_tsthi (); -extern rtx gen_tstqi (); -extern rtx gen_tstdf (); -extern rtx gen_tstsf (); -extern rtx gen_cmpsi (); -extern rtx gen_cmphi (); -extern rtx gen_cmpqi (); -extern rtx gen_cmpdf (); -extern rtx gen_cmpsf (); -extern rtx gen_movdf (); -extern rtx gen_movsf (); -extern rtx gen_movdi (); -extern rtx gen_movsi (); -extern rtx gen_movhi (); -extern rtx gen_movstricthi (); -extern rtx gen_movqi (); -extern rtx gen_movstrictqi (); -extern rtx gen_movstrsi (); -extern rtx gen_movstrsi1 (); -extern rtx gen_truncsiqi2 (); -extern rtx gen_truncsihi2 (); -extern rtx gen_trunchiqi2 (); -extern rtx gen_extendhisi2 (); -extern rtx gen_extendqihi2 (); -extern rtx gen_extendqisi2 (); -extern rtx gen_extendsfdf2 (); -extern rtx gen_truncdfsf2 (); -extern rtx gen_zero_extendhisi2 (); -extern rtx gen_zero_extendqihi2 (); -extern rtx gen_zero_extendqisi2 (); -extern rtx gen_floatsisf2 (); -extern rtx gen_floatsidf2 (); -extern rtx gen_floathisf2 (); -extern rtx gen_floathidf2 (); -extern rtx gen_floatqisf2 (); -extern rtx gen_fixsfqi2 (); -extern rtx gen_fixsfhi2 (); -extern rtx gen_fixsfsi2 (); -extern rtx gen_fixdfqi2 (); -extern rtx gen_fixdfhi2 (); -extern rtx gen_fixdfsi2 (); -extern rtx gen_fixunssfqi2 (); -extern rtx gen_fixunssfhi2 (); -extern rtx gen_fixunssfsi2 (); -extern rtx gen_fixunsdfqi2 (); -extern rtx gen_fixunsdfhi2 (); -extern rtx gen_fixunsdfsi2 (); -extern rtx gen_fix_truncsfqi2 (); -extern rtx gen_fix_truncsfhi2 (); -extern rtx gen_fix_truncsfsi2 (); -extern rtx gen_fix_truncdfqi2 (); -extern rtx gen_fix_truncdfhi2 (); -extern rtx gen_fix_truncdfsi2 (); -extern rtx gen_adddf3 (); -extern rtx gen_addsf3 (); -extern rtx gen_addsi3 (); -extern rtx gen_addhi3 (); -extern rtx gen_addqi3 (); -extern rtx gen_subdf3 (); -extern rtx gen_subsf3 (); -extern rtx gen_subsi3 (); -extern rtx gen_subhi3 (); -extern rtx gen_subqi3 (); -extern rtx gen_muldf3 (); -extern rtx gen_mulsf3 (); -extern rtx gen_mulsi3 (); -extern rtx gen_mulhi3 (); -extern rtx gen_mulqi3 (); -extern rtx gen_umulsidi3 (); -extern rtx gen_divdf3 (); -extern rtx gen_divsf3 (); -extern rtx gen_divsi3 (); -extern rtx gen_divhi3 (); -extern rtx gen_divqi3 (); -extern rtx gen_udivsi3 (); -extern rtx gen_udivhi3 (); -extern rtx gen_udivqi3 (); -extern rtx gen_modsi3 (); -extern rtx gen_modhi3 (); -extern rtx gen_modqi3 (); -extern rtx gen_umodsi3 (); -extern rtx gen_umodhi3 (); -extern rtx gen_umodqi3 (); -extern rtx gen_andsi3 (); -extern rtx gen_andhi3 (); -extern rtx gen_andqi3 (); -extern rtx gen_iorsi3 (); -extern rtx gen_iorhi3 (); -extern rtx gen_iorqi3 (); -extern rtx gen_xorsi3 (); -extern rtx gen_xorhi3 (); -extern rtx gen_xorqi3 (); -extern rtx gen_negdf2 (); -extern rtx gen_negsf2 (); -extern rtx gen_negsi2 (); -extern rtx gen_neghi2 (); -extern rtx gen_negqi2 (); -extern rtx gen_one_cmplsi2 (); -extern rtx gen_one_cmplhi2 (); -extern rtx gen_one_cmplqi2 (); -extern rtx gen_ashlsi3 (); -extern rtx gen_ashlhi3 (); -extern rtx gen_ashlqi3 (); -extern rtx gen_ashrsi3 (); -extern rtx gen_ashrhi3 (); -extern rtx gen_ashrqi3 (); -extern rtx gen_lshlsi3 (); -extern rtx gen_lshlhi3 (); -extern rtx gen_lshlqi3 (); -extern rtx gen_lshrsi3 (); -extern rtx gen_lshrhi3 (); -extern rtx gen_lshrqi3 (); -extern rtx gen_rotlsi3 (); -extern rtx gen_rotlhi3 (); -extern rtx gen_rotlqi3 (); -extern rtx gen_rotrsi3 (); -extern rtx gen_rotrhi3 (); -extern rtx gen_rotrqi3 (); -extern rtx gen_extzv (); -extern rtx gen_insv (); -extern rtx gen_jump (); -extern rtx gen_beq (); -extern rtx gen_bne (); -extern rtx gen_bgt (); -extern rtx gen_bgtu (); -extern rtx gen_blt (); -extern rtx gen_bltu (); -extern rtx gen_bge (); -extern rtx gen_bgeu (); -extern rtx gen_ble (); -extern rtx gen_bleu (); -extern rtx gen_untyped_call (); -extern rtx gen_blockage (); -extern rtx gen_return (); -extern rtx gen_abssf2 (); -extern rtx gen_absdf2 (); -extern rtx gen_abssi2 (); -extern rtx gen_abshi2 (); -extern rtx gen_absqi2 (); -extern rtx gen_nop (); -extern rtx gen_indirect_jump (); -extern rtx gen_tablejump (); -extern rtx gen_seq (); -extern rtx gen_sne (); -extern rtx gen_sgt (); -extern rtx gen_sgtu (); -extern rtx gen_slt (); -extern rtx gen_sltu (); -extern rtx gen_sge (); -extern rtx gen_sgeu (); -extern rtx gen_sle (); -extern rtx gen_sleu (); -extern rtx gen_ffsqi2 (); -extern rtx gen_ffshi2 (); -extern rtx gen_ffssi2 (); -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* NO_MD_PROTOTYPES */ diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-opinit.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-opinit.c deleted file mode 100644 index 0b262b74dd1..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-opinit.c +++ /dev/null @@ -1,199 +0,0 @@ -/* Generated automatically by the program `genopinit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "flags.h" -#include "insn-flags.h" -#include "insn-codes.h" -#include "insn-config.h" -#include "recog.h" -#include "expr.h" -#include "reload.h" - -void -init_all_optabs () -{ - tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi; - tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi; - tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi; - if (HAVE_tstdf) - tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf; - if (HAVE_tstsf) - tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf; - cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi; - cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi; - cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi; - if (HAVE_cmpdf) - cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf; - if (HAVE_cmpsf) - cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf; - mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf; - mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf; - mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi; - mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi; - mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi; - movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi; - mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi; - movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi; - movstr_optab[(int) SImode] = CODE_FOR_movstrsi; - extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2; - extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2; - extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2; - if (HAVE_extendsfdf2) - extendtab[(int) DFmode][(int) SFmode][0] = CODE_FOR_extendsfdf2; - extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2; - extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2; - extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2; - if (HAVE_floatsisf2) - floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2; - if (HAVE_floatsidf2) - floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2; - if (HAVE_floathisf2) - floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2; - if (HAVE_floathidf2) - floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2; - if (HAVE_floatqisf2) - floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2; - if (HAVE_fixsfqi2) - fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2; - if (HAVE_fixsfhi2) - fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2; - if (HAVE_fixsfsi2) - fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2; - if (HAVE_fixdfqi2) - fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2; - if (HAVE_fixdfhi2) - fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2; - if (HAVE_fixdfsi2) - fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2; - if (HAVE_fixunssfqi2) - fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2; - if (HAVE_fixunssfhi2) - fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2; - if (HAVE_fixunssfsi2) - fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2; - if (HAVE_fixunsdfqi2) - fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2; - if (HAVE_fixunsdfhi2) - fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2; - if (HAVE_fixunsdfsi2) - fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2; - if (HAVE_fix_truncsfqi2) - fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2; - if (HAVE_fix_truncsfhi2) - fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2; - if (HAVE_fix_truncsfsi2) - fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2; - if (HAVE_fix_truncdfqi2) - fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2; - if (HAVE_fix_truncdfhi2) - fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2; - if (HAVE_fix_truncdfsi2) - fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2; - if (HAVE_adddf3) - add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3; - if (HAVE_addsf3) - add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3; - add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3; - add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3; - add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3; - if (HAVE_subdf3) - sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3; - if (HAVE_subsf3) - sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3; - sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3; - sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3; - sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3; - if (HAVE_muldf3) - smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3; - if (HAVE_mulsf3) - smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3; - smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3; - smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3; - smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3; - umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3; - if (HAVE_divdf3) - flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3; - if (HAVE_divsf3) - flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3; - sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3; - sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3; - sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3; - udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3; - udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3; - udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3; - smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3; - smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3; - smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3; - umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3; - umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3; - umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3; - and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3; - and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3; - and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3; - ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3; - ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3; - ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3; - xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3; - xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3; - xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3; - if (HAVE_negdf2) - neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2; - if (HAVE_negsf2) - neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2; - neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2; - neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2; - neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2; - one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2; - one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2; - one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2; - ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3; - ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3; - ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3; - ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3; - ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3; - ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3; - lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3; - lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3; - lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3; - lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3; - lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3; - lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3; - rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3; - rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3; - rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3; - rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3; - rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3; - rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3; - bcc_gen_fctn[(int) EQ] = gen_beq; - bcc_gen_fctn[(int) NE] = gen_bne; - bcc_gen_fctn[(int) GT] = gen_bgt; - bcc_gen_fctn[(int) GTU] = gen_bgtu; - bcc_gen_fctn[(int) LT] = gen_blt; - bcc_gen_fctn[(int) LTU] = gen_bltu; - bcc_gen_fctn[(int) GE] = gen_bge; - bcc_gen_fctn[(int) GEU] = gen_bgeu; - bcc_gen_fctn[(int) LE] = gen_ble; - bcc_gen_fctn[(int) LEU] = gen_bleu; - if (HAVE_abssf2) - abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2; - if (HAVE_absdf2) - abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2; - abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2; - abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2; - abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2; - setcc_gen_code[(int) EQ] = CODE_FOR_seq; - setcc_gen_code[(int) NE] = CODE_FOR_sne; - setcc_gen_code[(int) GT] = CODE_FOR_sgt; - setcc_gen_code[(int) GTU] = CODE_FOR_sgtu; - setcc_gen_code[(int) LT] = CODE_FOR_slt; - setcc_gen_code[(int) LTU] = CODE_FOR_sltu; - setcc_gen_code[(int) GE] = CODE_FOR_sge; - setcc_gen_code[(int) GEU] = CODE_FOR_sgeu; - setcc_gen_code[(int) LE] = CODE_FOR_sle; - setcc_gen_code[(int) LEU] = CODE_FOR_sleu; - ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2; - ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2; - ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2; -} diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-output.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-output.c deleted file mode 100644 index cafdb98b0b0..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-output.c +++ /dev/null @@ -1,4116 +0,0 @@ -/* Generated automatically by the program `genoutput' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" - -#include "conditions.h" -#include "insn-flags.h" -#include "insn-attr.h" - -#include "insn-codes.h" - -#include "recog.h" - -#include -#include "output.h" - -static char * -output_0 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return "cmpqd %1,%0"; } -} - -static char * -output_1 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return "cmpqw %1,%0"; } -} - -static char * -output_2 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return "cmpqb %1,%0"; } -} - -static char * -output_3 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (DFmode); - return "cmpl %1,%0"; } -} - -static char * -output_4 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (SFmode); - return "cmpf %1,%0"; } -} - -static char * -output_5 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - return "cmpqd %1,%0"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - int i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - return "cmpqd %0,%1"; - } - return "cmpd %0,%1"; -} -} - -static char * -output_6 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return "cmpqw %1,%0"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - short i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return "cmpqw %0,%1"; - } - } - return "cmpw %0,%1"; -} -} - -static char * -output_7 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - char i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return "cmpqb %1,%0"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - char i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return "cmpqb %0,%1"; - } - } - return "cmpb %0,%1"; -} -} - -static char * -output_10 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return "movl %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("movd %1,tos", xoperands); - output_asm_insn ("movd %1,tos", operands); - return "movl tos,%0"; - } - return "movl %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn ("movl %1,tos\n\tmovd tos,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "movd tos,%0"; - } - else - return "movl %1,%0"; - } - return output_move_double (operands); -} -} - -static char * -output_11 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return "movd %1,tos\n\tmovf tos,%0"; - else - return "movf %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return "movf %1,tos\n\tmovd tos,%0"; - return "movf %1,%0"; - } -#if 0 /* Someone suggested this for the Sequent. Is it needed? */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return "movf %1,%0"; -#endif -/* There was a #if 0 around this, but that was erroneous - for many machines -- rms. */ -#ifndef MOVD_FLOAT_OK - /* GAS understands floating constants in ordinary movd instructions - but other assemblers might object. */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - union {int i[2]; float f; double d;} convrt; - convrt.i[0] = CONST_DOUBLE_LOW (operands[1]); - convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]); - convrt.f = convrt.d; - - /* Is there a better machine-independent way to to this? */ - operands[1] = gen_rtx (CONST_INT, VOIDmode, convrt.i[0]); - return "movd %1,%0"; - } -#endif - else return "movd %1,%0"; -} -} - -static char * -output_13 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return "movl %1,%0"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn ("movd %1,tos", xoperands); - output_asm_insn ("movd %1,tos", operands); - return "movl tos,%0"; - } - return "movl %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn ("movl %1,tos\n\tmovd tos,%0", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "movd tos,%0"; - } - else - return "movl %1,%0"; - } - return output_move_double (operands); -} -} - -static char * -output_15 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return "movd %1,tos\n\tmovf tos,%0"; - else - return "movf %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return "movf %1,tos\n\tmovd tos,%0"; - return "movf %1,%0"; - } - if (GET_CODE (operands[0]) == REG - && REGNO (operands[0]) == FRAME_POINTER_REGNUM) - return "lprd fp,%1"; - if (GET_CODE (operands[1]) == CONST_DOUBLE) - operands[1] - = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (! TARGET_32532) - { - if (i <= 7 && i >= -8) - return "movqd %1,%0"; - if (i < 0x4000 && i >= -0x4000) -#if defined (GNX_V3) || defined (UTEK_ASM) - return "addr %c1,%0"; -#else - return "addr @%c1,%0"; -#endif - } - else - return output_move_dconst(i, "%$%1,%0"); - } - else if (GET_CODE (operands[1]) == REG) - { - if (REGNO (operands[1]) < 16) - return "movd %1,%0"; - else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return "sprd fp,%0"; - else - return "addr 0(fp),%0" ; - } - else if (REGNO (operands[1]) == STACK_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return "sprd sp,%0"; - else - return "addr 0(sp),%0" ; - } - else abort (); - } - else if (GET_CODE (operands[1]) == MEM) - return "movd %1,%0"; - - /* Check if this effective address can be - calculated faster by pulling it apart. */ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return "addr %a1,%0"; -} -} - -static char * -output_16 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, i); - return "movqw %1,%0"; - } - return "movw %1,%0"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return "movwf %1,tos\n\tmovf tos,%0"; - else - return "movwf %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return "movf %1,tos\n\tmovd tos,%0"; - return "movf %1,%0"; - } - else - return "movw %1,%0"; -} -} - -static char * -output_17 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8) - return "movqw %1,%0"; - return "movw %1,%0"; -} -} - -static char * -output_18 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[1]) == CONST_INT) - { - char char_val = (char)INTVAL (operands[1]); - if (char_val <= 7 && char_val >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, char_val); - return "movqb %1,%0"; - } - return "movb %1,%0"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return "movbf %1,tos\n\tmovf tos,%0"; - else - return "movbf %1,%0"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return "movf %1,tos\n\tmovd tos,%0"; - return "movf %1,%0"; - } - else - return "movb %1,%0"; -} -} - -static char * -output_19 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9) - return "movqb %1,%0"; - return "movb %1,%0"; -} -} - -static char * -output_21 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - abort (); - operands[0] = XEXP (operands[0], 0); - operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[0]) == MEM) - if (GET_CODE (operands[1]) == MEM) - output_asm_insn ("movd %0,r2\n\tmovd %1,r1", operands); - else - output_asm_insn ("movd %0,r2\n\taddr %a1,r1", operands); - else if (GET_CODE (operands[1]) == MEM) - output_asm_insn ("addr %a0,r2\n\tmovd %1,r1", operands); - else - output_asm_insn ("addr %a0,r2\n\taddr %a1,r1", operands); - -#ifdef UTEK_ASM - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return "movqd %2,r0\n\tmovsd $0"; - else - return "movd %2,r0\n\tmovsd $0"; - } - else - { - return "movd %2,r0\n\tmovsb $0"; - } -#else - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return "movqd %2,r0\n\tmovsd"; - else - return "movd %2,r0\n\tmovsd"; - } - else - { - return "movd %2,r0\n\tmovsb"; - } -#endif -} -} - -static char * -output_58 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef SEQUENT_ADJUST_STACK - if (TARGET_32532) - if (INTVAL (operands[0]) == 8) - return "cmpd tos,tos"; - if (TARGET_32532 || TARGET_32332) - if (INTVAL (operands[0]) == 4) - return "cmpqd %$0,tos"; -#endif - if (! TARGET_32532) - { - if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64) - return "adjspb %$%n0"; - else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192) - return "adjspw %$%n0"; - } - return "adjspd %$%n0"; -} -} - -static char * -output_61 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (which_alternative == 1) - { - int i = INTVAL (operands[2]); - if (NS32K_DISPLACEMENT_P (i)) - return "addr %c2(%1),%0"; - else - return "movd %1,%0\n\taddd %2,%0"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 7 && i >= -8) - return "addqd %2,%0"; - else if (GET_CODE (operands[0]) == REG - && i < 0x4000 && i >= -0x4000 && ! TARGET_32532) - return "addr %c2(%0),%0"; - } - return "addd %2,%0"; -} -} - -static char * -output_62 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return "addqw %2,%0"; - } - return "addw %2,%0"; -} -} - -static char * -output_63 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return "addqw %2,%0"; - return "addw %2,%0"; -} -} - -static char * -output_64 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return "addqb %2,%0"; - } - return "addb %2,%0"; -} -} - -static char * -output_65 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return "addqb %2,%0"; - return "addb %2,%0"; -} -} - -static char * -output_68 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 - && INTVAL(operands[0]) > -64 && ! TARGET_32532) - return "adjspb %$%0"; - return "adjspd %$%0"; -} -} - -static char * -output_69 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return "addqd %$%n2,%0"; - } - return "subd %2,%0"; -} -} - -static char * -output_70 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return "addqw %$%n2,%0"; - } - return "subw %2,%0"; -} -} - -static char * -output_71 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return "addqw %$%n2,%0"; - return "subw %2,%0"; -} -} - -static char * -output_72 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return "addqb %$%n2,%0"; - } - return "subb %2,%0"; -} -} - -static char * -output_73 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return "addqb %$%n2,%0"; - return "subb %2,%0"; -} -} - -static char * -output_85 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return "deid %2,%0\n\tmovd %1,%0"; -} -} - -static char * -output_86 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]) + 1); - return "deiw %2,%0\n\tmovw %1,%0"; -} -} - -static char * -output_87 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[1] = gen_rtx (REG, QImode, REGNO (operands[0]) + 1); - return "deib %2,%0\n\tmovb %1,%0"; -} -} - -static char * -output_94 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if ((INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return "movqb %$0,%0"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return "andb %2,%0"; - } - } - if ((INTVAL (operands[2]) | 0xffff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffff0000) - return "movqw %$0,%0"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - return "andw %2,%0"; - } - } - } - return "andd %2,%0"; -} -} - -static char * -output_95 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return "movqb %$0,%0"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return "andb %2,%0"; - } - } - return "andw %2,%0"; -} -} - -static char * -output_100 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return "orb %2,%0"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return "orw %2,%0"; - } - return "ord %2,%0"; -} -} - -static char * -output_101 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return "orb %2,%0"; - return "orw %2,%0"; -} -} - -static char * -output_103 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return "xorb %2,%0"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return "xorw %2,%0"; - } - return "xord %2,%0"; -} -} - -static char * -output_104 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return "xorb %2,%0"; - return "xorw %2,%0"; -} -} - -static char * -output_114 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (TARGET_32532) - return "lshd %2,%0"; - else - return output_shift_insn (operands); -} -} - -static char * -output_115 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return "addw %0,%0"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return "addw %0,%0\n\taddw %0,%0"; - } - if (TARGET_32532) - return "lshw %2,%0"; - else - return "ashw %2,%0"; -} -} - -static char * -output_116 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return "addb %0,%0"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return "addb %0,%0\n\taddb %0,%0"; - } - if (TARGET_32532) - return "lshb %2,%0"; - else - return "ashb %2,%0"; -} -} - -static char * -output_150 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return "addr %a1,%0"; -} -} - -static char * -output_155 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ cc_status.flags = CC_Z_IN_F; - return "tbitd %1,%0"; -} -} - -static char * -output_156 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - output_asm_insn ("movd %1,tos", operands); - if (INTVAL (operands[2]) == 16) - { - if (INTVAL (operands[3]) == 8) - output_asm_insn ("movzwd 1(sp),%0", operands); - else - output_asm_insn ("movzwd 2(sp),%0", operands); - } - else - { - if (INTVAL (operands[3]) == 8) - output_asm_insn ("movzbd 1(sp),%0", operands); - else if (INTVAL (operands[3]) == 16) - output_asm_insn ("movzbd 2(sp),%0", operands); - else - output_asm_insn ("movzbd 3(sp),%0", operands); - } - if (TARGET_32532 || TARGET_32332) - return "cmpqd %$0,tos"; - else - return "adjspb %$-4"; -} -} - -static char * -output_157 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[3]) == CONST_INT) - return "extsd %1,%0,%3,%2"; - else return "extd %3,%1,%0,%2"; -} -} - -static char * -output_158 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[3]) == CONST_INT) - return "extsd %1,%0,%3,%2"; - else return "extd %3,%1,%0,%2"; -} -} - -static char * -output_159 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 8) - { - operands[0] = adj_offsettable_operand (operands[0], - INTVAL (operands[2]) / 8); - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8); - } - if (INTVAL (operands[1]) <= 8) - return "inssb %3,%0,%2,%1"; - else if (INTVAL (operands[1]) <= 16) - return "inssw %3,%0,%2,%1"; - else - return "inssd %3,%0,%2,%1"; - } - return "insd %2,%3,%0,%1"; -} -} - -static char * -output_160 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return "inssb %3,%0,%2,%1"; - else if (INTVAL (operands[1]) <= 16) - return "inssw %3,%0,%2,%1"; - else - return "inssd %3,%0,%2,%1"; - return "insd %2,%3,%0,%1"; -} -} - -static char * -output_161 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return "inssb %3,%0,%2,%1"; - else if (INTVAL (operands[1]) <= 16) - return "inssw %3,%0,%2,%1"; - else - return "inssd %3,%0,%2,%1"; - return "insd %2,%3,%0,%1"; -} -} - -static char * -output_163 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "bfc %l0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "bfs %l0"; - else return "beq %l0"; -} -} - -static char * -output_164 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "bfs %l0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "bfc %l0"; - else return "bne %l0"; -} -} - -static char * -output_173 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "bfs %l0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "bfc %l0"; - else return "bne %l0"; -} -} - -static char * -output_174 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "bfc %l0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "bfs %l0"; - else return "beq %l0"; -} -} - -static char * -output_185 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[0]) == MEM) - { - rtx temp = XEXP (operands[0], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return "bsr %?%0"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[0] = temp; - return "bsr %0"; -#else -#ifdef GNX_V3 - return "bsr %0"; -#else - return "bsr %?%a0"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[0], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return "jsr %0"; -#else - return "jsr %a0"; -#endif - } -#endif /* not JSR_ALWAYS */ - return "jsr %0"; -} -} - -static char * -output_186 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[1]) == MEM) - { - rtx temp = XEXP (operands[1], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return "bsr %?%1"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[1] = temp; - return "bsr %1"; -#else -#ifdef GNX_V3 - return "bsr %1"; -#else - return "bsr %?%a1"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[1], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return "jsr %1"; -#else - return "jsr %a1"; -#endif - } -#endif /* not JSR_ALWAYS */ - return "jsr %1"; -} -} - -static char * -output_197 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LI", - CODE_LABEL_NUMBER (operands[1])); - return "cased %0"; -} -} - -static char * -output_198 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfcd %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfsd %0"; - else return "seqd %0"; -} -} - -static char * -output_199 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfcw %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfsw %0"; - else return "seqw %0"; -} -} - -static char * -output_200 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfcb %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfsb %0"; - else return "seqb %0"; -} -} - -static char * -output_201 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfsd %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfcd %0"; - else return "sned %0"; -} -} - -static char * -output_202 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfsw %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfcw %0"; - else return "snew %0"; -} -} - -static char * -output_203 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ if (cc_prev_status.flags & CC_Z_IN_F) - return "sfsb %0"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return "sfcb %0"; - else return "sneb %0"; -} -} - -static char * -output_228 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "movqb 0,%0; ffsd %1,%0; bfs 1f; addqb 1,%0; 1:"; -} -} - -static char * -output_229 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "movqw 0,%0; ffsd %1,%0; bfs 1f; addqw 1,%0; 1:"; -} -} - -static char * -output_230 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "movqd 0,%0; ffsd %1,%0; bfs 1f; addqd 1,%0; 1:"; -} -} - -static char * -output_231 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,tos"), - operands); - else - output_asm_insn ("movzwd %1,tos", operands); - return ""; -} -} - -static char * -output_232 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,tos"), - operands); - else - output_asm_insn ("movzbd %1,tos", operands); - return ""; -} -} - -static char * -output_233 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,tos"), - operands); - else - output_asm_insn ("movxbd %1,tos", operands); - return ""; -} -} - -static char * -output_234 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,tos"), - operands); - else - output_asm_insn ("movzbd %1,tos", operands); - return ""; -} -} - -static char * -output_235 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,0(sp)"), - operands); - else - output_asm_insn ("movd %1,0(sp)", operands); - return ""; -} -} - -static char * -output_236 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), "%$%1,4(sp)"), - operands); - else - output_asm_insn ("movd %1,4(sp)", operands); - - if (GET_CODE (operands[3]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[3]), "%$%3,0(sp)"), - operands); - else - output_asm_insn ("movd %3,0(sp)", operands); - return ""; -} -} - -char * const insn_template[] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "cmpl %0,%1", - "cmpf %0,%1", - 0, - 0, - "movmd %1,%0,4", - 0, - "lprd sp,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "movb %1,%0", - "movw %1,%0", - "movb %1,%0", - "movxwd %1,%0", - "movxbw %1,%0", - "movxbd %1,%0", - "movfl %1,%0", - "movlf %1,%0", - "movzwd %1,%0", - "movzbw %1,%0", - "movzbd %1,%0", - "movdf %1,%0", - "movdl %1,%0", - "movwf %1,%0", - "movwl %1,%0", - "movbf %1,%0", - "truncfb %1,%0", - "truncfw %1,%0", - "truncfd %1,%0", - "trunclb %1,%0", - "trunclw %1,%0", - "truncld %1,%0", - "truncfb %1,%0", - "truncfw %1,%0", - "truncfd %1,%0", - "trunclb %1,%0", - "trunclw %1,%0", - "truncld %1,%0", - "truncfb %1,%0", - "truncfw %1,%0", - "truncfd %1,%0", - "trunclb %1,%0", - "trunclw %1,%0", - "truncld %1,%0", - "addl %2,%0", - "addf %2,%0", - 0, - "addr %c1(fp),%0", - "addr %c1(sp),%0", - 0, - 0, - 0, - 0, - 0, - "subl %2,%0", - "subf %2,%0", - 0, - 0, - 0, - 0, - 0, - 0, - "mull %2,%0", - "mulf %2,%0", - "muld %2,%0", - "mulw %2,%0", - "mulb %2,%0", - "meid %2,%0", - "divl %2,%0", - "divf %2,%0", - "quod %2,%0", - "quow %2,%0", - "quob %2,%0", - 0, - 0, - 0, - "remd %2,%0", - "remw %2,%0", - "remb %2,%0", - "deid %2,%0", - "deiw %2,%0", - "deib %2,%0", - 0, - 0, - "andb %2,%0", - "bicd %1,%0", - "bicw %1,%0", - "bicb %1,%0", - 0, - 0, - "orb %2,%0", - 0, - 0, - "xorb %2,%0", - "negl %1,%0", - "negf %1,%0", - "negd %1,%0", - "negw %1,%0", - "negb %1,%0", - "comd %1,%0", - "comw %1,%0", - "comb %1,%0", - 0, - 0, - 0, - 0, - "ashd %$%n2,%0", - "ashd %2,%0", - 0, - "ashw %$%n2,%0", - "ashw %2,%0", - 0, - "ashb %$%n2,%0", - "ashb %2,%0", - "lshd %2,%0", - "lshw %2,%0", - "lshb %2,%0", - 0, - "lshd %$%n2,%0", - "lshd %2,%0", - 0, - "lshw %$%n2,%0", - "lshw %2,%0", - 0, - "lshb %$%n2,%0", - "lshb %2,%0", - "rotd %2,%0", - "rotw %2,%0", - "rotb %2,%0", - 0, - "rotd %$%n2,%0", - "rotd %2,%0", - 0, - "rotw %$%n2,%0", - "rotw %2,%0", - 0, - "rotb %$%n2,%0", - "rotb %2,%0", - 0, - "sbitd %1,%0", - "cbitd %1,%0", - "ibitd %1,%0", - "ibitb %1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "br %l0", - 0, - 0, - "bgt %l0", - "bhi %l0", - "blt %l0", - "blo %l0", - "bge %l0", - "bhs %l0", - "ble %l0", - "bls %l0", - 0, - 0, - "ble %l0", - "bls %l0", - "bge %l0", - "bhs %l0", - "blt %l0", - "blo %l0", - "bgt %l0", - "bhi %l0", - "acbd %$%n1,%0,%l2", - "acbd %3,%0,%l2", - 0, - 0, - 0, - "", - "ret 0", - "absf %1,%0", - "absl %1,%0", - "absd %1,%0", - "absw %1,%0", - "absb %1,%0", - "nop", - "jump %0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "sgtd %0", - "sgtw %0", - "sgtb %0", - "shid %0", - "shiw %0", - "shib %0", - "sltd %0", - "sltw %0", - "sltb %0", - "slod %0", - "slow %0", - "slob %0", - "sged %0", - "sgew %0", - "sgeb %0", - "shsd %0", - "shsw %0", - "shsb %0", - "sled %0", - "slew %0", - "sleb %0", - "slsd %0", - "slsw %0", - "slsb %0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *(*const insn_outfun[])() = - { - output_0, - output_1, - output_2, - output_3, - output_4, - output_5, - output_6, - output_7, - 0, - 0, - output_10, - output_11, - 0, - output_13, - 0, - output_15, - output_16, - output_17, - output_18, - output_19, - 0, - output_21, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_58, - 0, - 0, - output_61, - output_62, - output_63, - output_64, - output_65, - 0, - 0, - output_68, - output_69, - output_70, - output_71, - output_72, - output_73, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_85, - output_86, - output_87, - 0, - 0, - 0, - 0, - 0, - 0, - output_94, - output_95, - 0, - 0, - 0, - 0, - output_100, - output_101, - 0, - output_103, - output_104, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_114, - output_115, - output_116, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_150, - 0, - 0, - 0, - 0, - output_155, - output_156, - output_157, - output_158, - output_159, - output_160, - output_161, - 0, - output_163, - output_164, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_173, - output_174, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_185, - output_186, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_197, - output_198, - output_199, - output_200, - output_201, - output_202, - output_203, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_228, - output_229, - output_230, - output_231, - output_232, - output_233, - output_234, - output_235, - output_236, - }; - -rtx (*const insn_gen_function[]) () = - { - gen_tstsi, - gen_tsthi, - gen_tstqi, - gen_tstdf, - gen_tstsf, - gen_cmpsi, - gen_cmphi, - gen_cmpqi, - gen_cmpdf, - gen_cmpsf, - gen_movdf, - gen_movsf, - 0, - gen_movdi, - 0, - gen_movsi, - gen_movhi, - gen_movstricthi, - gen_movqi, - gen_movstrictqi, - gen_movstrsi, - gen_movstrsi1, - gen_truncsiqi2, - gen_truncsihi2, - gen_trunchiqi2, - gen_extendhisi2, - gen_extendqihi2, - gen_extendqisi2, - gen_extendsfdf2, - gen_truncdfsf2, - gen_zero_extendhisi2, - gen_zero_extendqihi2, - gen_zero_extendqisi2, - gen_floatsisf2, - gen_floatsidf2, - gen_floathisf2, - gen_floathidf2, - gen_floatqisf2, - gen_fixsfqi2, - gen_fixsfhi2, - gen_fixsfsi2, - gen_fixdfqi2, - gen_fixdfhi2, - gen_fixdfsi2, - gen_fixunssfqi2, - gen_fixunssfhi2, - gen_fixunssfsi2, - gen_fixunsdfqi2, - gen_fixunsdfhi2, - gen_fixunsdfsi2, - gen_fix_truncsfqi2, - gen_fix_truncsfhi2, - gen_fix_truncsfsi2, - gen_fix_truncdfqi2, - gen_fix_truncdfhi2, - gen_fix_truncdfsi2, - gen_adddf3, - gen_addsf3, - 0, - 0, - 0, - gen_addsi3, - gen_addhi3, - 0, - gen_addqi3, - 0, - gen_subdf3, - gen_subsf3, - 0, - gen_subsi3, - gen_subhi3, - 0, - gen_subqi3, - 0, - gen_muldf3, - gen_mulsf3, - gen_mulsi3, - gen_mulhi3, - gen_mulqi3, - gen_umulsidi3, - gen_divdf3, - gen_divsf3, - gen_divsi3, - gen_divhi3, - gen_divqi3, - gen_udivsi3, - gen_udivhi3, - gen_udivqi3, - gen_modsi3, - gen_modhi3, - gen_modqi3, - gen_umodsi3, - gen_umodhi3, - gen_umodqi3, - gen_andsi3, - gen_andhi3, - gen_andqi3, - 0, - 0, - 0, - gen_iorsi3, - gen_iorhi3, - gen_iorqi3, - gen_xorsi3, - gen_xorhi3, - gen_xorqi3, - gen_negdf2, - gen_negsf2, - gen_negsi2, - gen_neghi2, - gen_negqi2, - gen_one_cmplsi2, - gen_one_cmplhi2, - gen_one_cmplqi2, - gen_ashlsi3, - gen_ashlhi3, - gen_ashlqi3, - gen_ashrsi3, - 0, - 0, - gen_ashrhi3, - 0, - 0, - gen_ashrqi3, - 0, - 0, - gen_lshlsi3, - gen_lshlhi3, - gen_lshlqi3, - gen_lshrsi3, - 0, - 0, - gen_lshrhi3, - 0, - 0, - gen_lshrqi3, - 0, - 0, - gen_rotlsi3, - gen_rotlhi3, - gen_rotlqi3, - gen_rotrsi3, - 0, - 0, - gen_rotrhi3, - 0, - 0, - gen_rotrqi3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_extzv, - 0, - 0, - gen_insv, - gen_jump, - gen_beq, - gen_bne, - gen_bgt, - gen_bgtu, - gen_blt, - gen_bltu, - gen_bge, - gen_bgeu, - gen_ble, - gen_bleu, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_call, - gen_call_value, - gen_untyped_call, - gen_blockage, - gen_return, - gen_abssf2, - gen_absdf2, - gen_abssi2, - gen_abshi2, - gen_absqi2, - gen_nop, - gen_indirect_jump, - gen_tablejump, - gen_seq, - 0, - 0, - gen_sne, - 0, - 0, - gen_sgt, - 0, - 0, - gen_sgtu, - 0, - 0, - gen_slt, - 0, - 0, - gen_sltu, - 0, - 0, - gen_sge, - 0, - 0, - gen_sgeu, - 0, - 0, - gen_sle, - 0, - 0, - gen_sleu, - 0, - 0, - gen_ffsqi2, - gen_ffshi2, - gen_ffssi2, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *insn_name[] = - { - "tstsi", - "tsthi", - "tstqi", - "tstdf", - "tstsf", - "cmpsi", - "cmphi", - "cmpqi", - "cmpdf", - "cmpsf", - "movdf", - "movsf", - "movsf+1", - "movdi", - "movdi+1", - "movsi", - "movhi", - "movstricthi", - "movqi", - "movstrictqi", - "movstrsi", - "movstrsi1", - "truncsiqi2", - "truncsihi2", - "trunchiqi2", - "extendhisi2", - "extendqihi2", - "extendqisi2", - "extendsfdf2", - "truncdfsf2", - "zero_extendhisi2", - "zero_extendqihi2", - "zero_extendqisi2", - "floatsisf2", - "floatsidf2", - "floathisf2", - "floathidf2", - "floatqisf2", - "fixsfqi2", - "fixsfhi2", - "fixsfsi2", - "fixdfqi2", - "fixdfhi2", - "fixdfsi2", - "fixunssfqi2", - "fixunssfhi2", - "fixunssfsi2", - "fixunsdfqi2", - "fixunsdfhi2", - "fixunsdfsi2", - "fix_truncsfqi2", - "fix_truncsfhi2", - "fix_truncsfsi2", - "fix_truncdfqi2", - "fix_truncdfhi2", - "fix_truncdfsi2", - "adddf3", - "addsf3", - "addsf3+1", - "addsf3+2", - "addsi3-1", - "addsi3", - "addhi3", - "addhi3+1", - "addqi3", - "addqi3+1", - "subdf3", - "subsf3", - "subsf3+1", - "subsi3", - "subhi3", - "subhi3+1", - "subqi3", - "subqi3+1", - "muldf3", - "mulsf3", - "mulsi3", - "mulhi3", - "mulqi3", - "umulsidi3", - "divdf3", - "divsf3", - "divsi3", - "divhi3", - "divqi3", - "udivsi3", - "udivhi3", - "udivqi3", - "modsi3", - "modhi3", - "modqi3", - "umodsi3", - "umodhi3", - "umodqi3", - "andsi3", - "andhi3", - "andqi3", - "andqi3+1", - "andqi3+2", - "iorsi3-1", - "iorsi3", - "iorhi3", - "iorqi3", - "xorsi3", - "xorhi3", - "xorqi3", - "negdf2", - "negsf2", - "negsi2", - "neghi2", - "negqi2", - "one_cmplsi2", - "one_cmplhi2", - "one_cmplqi2", - "ashlsi3", - "ashlhi3", - "ashlqi3", - "ashrsi3", - "ashrsi3+1", - "ashrhi3-1", - "ashrhi3", - "ashrhi3+1", - "ashrqi3-1", - "ashrqi3", - "ashrqi3+1", - "lshlsi3-1", - "lshlsi3", - "lshlhi3", - "lshlqi3", - "lshrsi3", - "lshrsi3+1", - "lshrhi3-1", - "lshrhi3", - "lshrhi3+1", - "lshrqi3-1", - "lshrqi3", - "lshrqi3+1", - "rotlsi3-1", - "rotlsi3", - "rotlhi3", - "rotlqi3", - "rotrsi3", - "rotrsi3+1", - "rotrhi3-1", - "rotrhi3", - "rotrhi3+1", - "rotrqi3-1", - "rotrqi3", - "rotrqi3+1", - "rotrqi3+2", - "rotrqi3+3", - "rotrqi3+4", - "rotrqi3+5", - "extzv-5", - "extzv-4", - "extzv-3", - "extzv-2", - "extzv-1", - "extzv", - "extzv+1", - "insv-1", - "insv", - "jump", - "beq", - "bne", - "bgt", - "bgtu", - "blt", - "bltu", - "bge", - "bgeu", - "ble", - "bleu", - "bleu+1", - "bleu+2", - "bleu+3", - "bleu+4", - "bleu+5", - "bleu+6", - "call-6", - "call-5", - "call-4", - "call-3", - "call-2", - "call-1", - "call", - "call_value", - "untyped_call", - "blockage", - "return", - "abssf2", - "absdf2", - "abssi2", - "abshi2", - "absqi2", - "nop", - "indirect_jump", - "tablejump", - "seq", - "seq+1", - "sne-1", - "sne", - "sne+1", - "sgt-1", - "sgt", - "sgt+1", - "sgtu-1", - "sgtu", - "sgtu+1", - "slt-1", - "slt", - "slt+1", - "sltu-1", - "sltu", - "sltu+1", - "sge-1", - "sge", - "sge+1", - "sgeu-1", - "sgeu", - "sgeu+1", - "sle-1", - "sle", - "sle+1", - "sleu-1", - "sleu", - "sleu+1", - "ffsqi2-1", - "ffsqi2", - "ffshi2", - "ffssi2", - "ffssi2+1", - "ffssi2+2", - "ffssi2+3", - "ffssi2+4", - "ffssi2+5", - "ffssi2+6", - }; -char **insn_name_ptr = insn_name; - -const int insn_n_operands[] = - { - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 2, - 2, - 2, - 2, - 2, - 4, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 1, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 1, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 4, - 4, - 4, - 4, - 4, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 4, - 2, - 3, - 3, - 0, - 0, - 2, - 2, - 2, - 2, - 2, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 4, - }; - -const int insn_n_dups[] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 3, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] = - { - { "rm", }, - { "g", }, - { "g", }, - { "fmF", }, - { "fmF", }, - { "rmn", "rmn", }, - { "g", "g", }, - { "g", "g", }, - { "fmF", "fmF", }, - { "fmF", "fmF", }, - { "=fg<", "fFg", }, - { "=fg<", "fFg", }, - { "=m", "m", }, - { "=g<,*f,g", "gF,g,*f", }, - { "rmn", }, - { "=g<,g<,*f,g,x", "g,?xy,g,*f,rmn", }, - { "=g<,*f,g", "g,g,*f", }, - { "+r", "g", }, - { "=g<,*f,g", "g,g,*f", }, - { "+r", "g", }, - { "=g", "g", "rmn", "", }, - { "=g", "g", "rmn", }, - { "=g<", "rmn", }, - { "=g<", "rmn", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=fm<", "fmF", }, - { "=fm<", "fmF", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=fm<", "rm", }, - { "=fm<", "rm", }, - { "=fm<", "rm", }, - { "=fm<", "rm", }, - { "=fm<", "rm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=g<", "fm", }, - { "=fm", "%0", "fmF", }, - { "=fm", "%0", "fmF", }, - { "i", }, - { "=g<", "i", }, - { "=g<", "i", }, - { "=g,=g&<", "%0,r", "rmn,n", }, - { "=g", "%0", "g", }, - { "=r", "0", "g", }, - { "=g", "%0", "g", }, - { "=r", "0", "g", }, - { "=fm", "0", "fmF", }, - { "=fm", "0", "fmF", }, - { "i", }, - { "=g", "0", "rmn", }, - { "=g", "0", "g", }, - { "=r", "0", "g", }, - { "=g", "0", "g", }, - { "=r", "0", "g", }, - { "=fm", "%0", "fmF", }, - { "=fm", "%0", "fmF", }, - { "=g", "%0", "rmn", }, - { "=g", "%0", "g", }, - { "=g", "%0", "g", }, - { "=g", "0", "rmn", }, - { "=fm", "0", "fmF", }, - { "=fm", "0", "fmF", }, - { "=g", "0", "rmn", }, - { "=g", "0", "g", }, - { "=g", "0", "g", }, - { "=r", "0", "rmn", }, - { "=r", "0", "g", }, - { "=r", "0", "g", }, - { "=g", "0", "rmn", }, - { "=g", "0", "g", }, - { "=g", "0", "g", }, - { "=r", "0", "rmn", }, - { "=r", "0", "g", }, - { "=r", "0", "g", }, - { "=g", "%0", "rmn", }, - { "=g", "%0", "g", }, - { "=g", "%0", "g", }, - { "=g", "rmn", "0", }, - { "=g", "g", "0", }, - { "=g", "g", "0", }, - { "=g", "%0", "rmn", }, - { "=g", "%0", "g", }, - { "=g", "%0", "g", }, - { "=g", "%0", "rmn", }, - { "=g", "%0", "g", }, - { "=g", "%0", "g", }, - { "=fm<", "fmF", }, - { "=fm<", "fmF", }, - { "=g<", "rmn", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=g<", "rmn", }, - { "=g<", "g", }, - { "=g<", "g", }, - { "=g,g", "r,0", "I,rmn", }, - { "=g", "0", "rmn", }, - { "=g", "0", "rmn", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "0", "rmn", }, - { "=g", "0", "rmn", }, - { "=g", "0", "rmn", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "0", "rmn", }, - { "=g", "0", "rmn", }, - { "=g", "0", "rmn", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g", "g", "g", }, - { "=g", "0", "i", }, - { "=g", "0", "r", }, - { "=g<", "p", }, - { "+g", "rmn", }, - { "+g", "rmn", }, - { "+g", "rmn", }, - { "=g", "rmn", }, - { "rm", "g", }, - { "=ro", "r", "i", "i", }, - { "=g<", "g", "i", "rK", }, - { "=g<", "g", "i", "rK", }, - { "+o", "i", "rn", "rm", }, - { "+r", "i", "rK", "rm", }, - { "+g", "i", "rK", "rm", }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { "+g", "i", }, - { "+g", "i", "", "i", }, - { "m", "g", }, - { "=rf", "m", "g", }, - { "", "", "", }, - { 0 }, - { 0 }, - { "=fm<", "fmF", }, - { "=fm<", "fmF", }, - { "=g<", "rmn", }, - { "=g<", "g", }, - { "=g<", "g", }, - { 0 }, - { "r", }, - { "g", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g<", }, - { "=g", "g", }, - { "=g", "g", }, - { "=g", "g", }, - { "=m", "g", }, - { "=m", "g", }, - { "=m", "g", }, - { "=m", "g", }, - { "=m", "g", }, - { "=m", "g", "=m", "g", }, - }; - -const enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] = - { - { SImode, }, - { HImode, }, - { QImode, }, - { DFmode, }, - { SFmode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { TImode, TImode, }, - { DImode, DImode, }, - { SImode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { BLKmode, BLKmode, SImode, VOIDmode, }, - { BLKmode, BLKmode, SImode, }, - { QImode, SImode, }, - { HImode, SImode, }, - { QImode, HImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { DFmode, SFmode, }, - { SFmode, DFmode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { SFmode, SImode, }, - { DFmode, SImode, }, - { SFmode, HImode, }, - { DFmode, HImode, }, - { SFmode, QImode, }, - { QImode, SFmode, }, - { HImode, SFmode, }, - { SImode, SFmode, }, - { QImode, DFmode, }, - { HImode, DFmode, }, - { SImode, DFmode, }, - { QImode, SFmode, }, - { HImode, SFmode, }, - { SImode, SFmode, }, - { QImode, DFmode, }, - { HImode, DFmode, }, - { SImode, DFmode, }, - { QImode, SFmode, }, - { HImode, SFmode, }, - { SImode, SFmode, }, - { QImode, DFmode, }, - { HImode, DFmode, }, - { SImode, DFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, QImode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { QImode, QImode, QImode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { DImode, SImode, SImode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { SImode, DImode, SImode, }, - { HImode, DImode, HImode, }, - { QImode, DImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { SImode, DImode, SImode, }, - { HImode, DImode, HImode, }, - { QImode, DImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, HImode, }, - { QImode, QImode, QImode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { HImode, HImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { QImode, QImode, SImode, }, - { SImode, QImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { QImode, QImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, QImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { QImode, SImode, SImode, SImode, }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { SImode, SImode, }, - { SImode, SImode, VOIDmode, SImode, }, - { QImode, QImode, }, - { VOIDmode, QImode, QImode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode }, - { VOIDmode }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { SImode, SImode, }, - { HImode, HImode, }, - { QImode, QImode, }, - { VOIDmode }, - { SImode, }, - { SImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { SImode, }, - { HImode, }, - { QImode, }, - { QImode, SImode, }, - { HImode, SImode, }, - { SImode, SImode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - }; - -const char insn_operand_strict_low[][MAX_RECOG_OPERANDS] = - { - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 1, 0, }, - { 0, 0, }, - { 1, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, 0, }, - { 0, 0, 0, }, - { 1, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0 }, - { 0 }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0 }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - }; - -extern int nonimmediate_operand (); -extern int general_operand (); -extern int memory_operand (); -extern int immediate_operand (); -extern int register_operand (); -extern int reg_or_mem_operand (); -extern int address_operand (); -extern int const_int_operand (); - -int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() = - { - { nonimmediate_operand, }, - { nonimmediate_operand, }, - { nonimmediate_operand, }, - { general_operand, }, - { general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { nonimmediate_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { memory_operand, memory_operand, }, - { general_operand, general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, 0, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, nonimmediate_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { immediate_operand, }, - { general_operand, immediate_operand, }, - { general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, nonimmediate_operand, nonimmediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { register_operand, reg_or_mem_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, general_operand, immediate_operand, }, - { general_operand, general_operand, general_operand, }, - { general_operand, address_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, register_operand, const_int_operand, const_int_operand, }, - { general_operand, register_operand, const_int_operand, general_operand, }, - { general_operand, general_operand, const_int_operand, general_operand, }, - { memory_operand, const_int_operand, general_operand, general_operand, }, - { register_operand, const_int_operand, general_operand, general_operand, }, - { general_operand, const_int_operand, general_operand, general_operand, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { general_operand, const_int_operand, }, - { general_operand, const_int_operand, 0, const_int_operand, }, - { memory_operand, general_operand, }, - { 0, memory_operand, general_operand, }, - { 0, 0, 0, }, - { 0 }, - { 0 }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { 0 }, - { register_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { general_operand, general_operand, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, 0, }, - }; - -const int insn_n_alternatives[] = - { - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 3, - 1, - 5, - 3, - 1, - 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - }; diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-peep.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-peep.c deleted file mode 100644 index fbc7a297a5b..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-peep.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Generated automatically by the program `genpeep' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "output.h" -#include "real.h" - -extern rtx peep_operand[]; - -#define operands peep_operand - -rtx -peephole (ins1) - rtx ins1; -{ - rtx insn, x, pat; - int i; - - if (NEXT_INSN (ins1) - && GET_CODE (NEXT_INSN (ins1)) == BARRIER) - return 0; - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L231; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L231; - if (GET_MODE (x) != SImode) goto L231; - if (XINT (x, 0) != 17) goto L231; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L231; - if (GET_MODE (x) != SImode) goto L231; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L231; - if (GET_MODE (x) != SImode) goto L231; - if (XINT (x, 0) != 17) goto L231; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L231; - if (XWINT (x, 0) != -2) goto L231; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L231; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L231; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L231; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, HImode)) goto L231; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, HImode)) goto L231; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L231; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 231; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L231: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L232; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L232; - if (GET_MODE (x) != SImode) goto L232; - if (XINT (x, 0) != 17) goto L232; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L232; - if (GET_MODE (x) != SImode) goto L232; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L232; - if (GET_MODE (x) != SImode) goto L232; - if (XINT (x, 0) != 17) goto L232; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L232; - if (XWINT (x, 0) != -2) goto L232; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L232; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L232; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L232; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, HImode)) goto L232; - x = XEXP (pat, 1); - if (GET_CODE (x) != ZERO_EXTEND) goto L232; - if (GET_MODE (x) != HImode) goto L232; - x = XEXP (XEXP (pat, 1), 0); - operands[1] = x; - if (! general_operand (x, QImode)) goto L232; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L232; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 232; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L232: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L233; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L233; - if (GET_MODE (x) != SImode) goto L233; - if (XINT (x, 0) != 17) goto L233; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L233; - if (GET_MODE (x) != SImode) goto L233; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L233; - if (GET_MODE (x) != SImode) goto L233; - if (XINT (x, 0) != 17) goto L233; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L233; - if (XWINT (x, 0) != -2) goto L233; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L233; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L233; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L233; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, HImode)) goto L233; - x = XEXP (pat, 1); - if (GET_CODE (x) != SIGN_EXTEND) goto L233; - if (GET_MODE (x) != HImode) goto L233; - x = XEXP (XEXP (pat, 1), 0); - operands[1] = x; - if (! general_operand (x, QImode)) goto L233; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L233; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 233; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L233: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L234; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L234; - if (GET_MODE (x) != SImode) goto L234; - if (XINT (x, 0) != 17) goto L234; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L234; - if (GET_MODE (x) != SImode) goto L234; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L234; - if (GET_MODE (x) != SImode) goto L234; - if (XINT (x, 0) != 17) goto L234; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L234; - if (XWINT (x, 0) != -3) goto L234; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L234; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L234; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L234; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, QImode)) goto L234; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, QImode)) goto L234; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L234; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 234; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L234: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L235; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L235; - if (GET_MODE (x) != SImode) goto L235; - if (XINT (x, 0) != 17) goto L235; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L235; - if (GET_MODE (x) != SImode) goto L235; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L235; - if (GET_MODE (x) != SImode) goto L235; - if (XINT (x, 0) != 17) goto L235; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L235; - if (XWINT (x, 0) != 4) goto L235; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L235; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L235; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L235; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, SImode)) goto L235; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, SImode)) goto L235; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]))) goto L235; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 235; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L235: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L236; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L236; - if (GET_MODE (x) != SImode) goto L236; - if (XINT (x, 0) != 17) goto L236; - x = XEXP (pat, 1); - if (GET_CODE (x) != PLUS) goto L236; - if (GET_MODE (x) != SImode) goto L236; - x = XEXP (XEXP (pat, 1), 0); - if (GET_CODE (x) != REG) goto L236; - if (GET_MODE (x) != SImode) goto L236; - if (XINT (x, 0) != 17) goto L236; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L236; - if (XWINT (x, 0) != 8) goto L236; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L236; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L236; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L236; - x = XEXP (pat, 0); - operands[0] = x; - if (! push_operand (x, SImode)) goto L236; - x = XEXP (pat, 1); - operands[1] = x; - if (! general_operand (x, SImode)) goto L236; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L236; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L236; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L236; - x = XEXP (pat, 0); - operands[2] = x; - if (! push_operand (x, SImode)) goto L236; - x = XEXP (pat, 1); - operands[3] = x; - if (! general_operand (x, SImode)) goto L236; - if (! (! reg_mentioned_p (stack_pointer_rtx, operands[1]) - && ! reg_mentioned_p (stack_pointer_rtx, operands[3]))) goto L236; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 236; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L236: - - return 0; -} - -rtx peep_operand[4]; diff --git a/gnu/usr.bin/gcc2/arch/ns32k/insn-recog.c b/gnu/usr.bin/gcc2/arch/ns32k/insn-recog.c deleted file mode 100644 index ff6fa5937a8..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/insn-recog.c +++ /dev/null @@ -1,4416 +0,0 @@ -/* Generated automatically by the program `genrecog' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "real.h" -#include "output.h" -#include "flags.h" - - -/* `recog' contains a decision tree - that recognizes whether the rtx X0 is a valid instruction. - - recog returns -1 if the rtx is not valid. - If the rtx is valid, recog returns a nonnegative number - which is the insn code number for the pattern that matched. - This is the same as the order in the machine description of - the entry that matched. This number can be used as an index into - entry that matched. This number can be used as an index into various - insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands - (found in insn-output.c). - - The third argument to recog is an optional pointer to an int. - If present, recog will accept a pattern if it matches except for - missing CLOBBER expressions at the end. In that case, the value - pointed to by the optional pointer will be set to the number of - CLOBBERs that need to be added (it should be initialized to zero by - the caller). If it is set nonzero, the caller should allocate a - PARALLEL of the appropriate size, copy the initial entries, and call - add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.*/ - -rtx recog_operand[MAX_RECOG_OPERANDS]; - -rtx *recog_operand_loc[MAX_RECOG_OPERANDS]; - -rtx *recog_dup_loc[MAX_DUP_OPERANDS]; - -char recog_dup_num[MAX_DUP_OPERANDS]; - -#define operands recog_operand - -int -recog_1 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - switch (GET_CODE (x1)) - { - case SIGN_EXTEND: - goto L105; - case ZERO_EXTEND: - goto L125; - case FIX: - goto L167; - case UNSIGNED_FIX: - goto L197; - case PLUS: - goto L256; - case MINUS: - goto L308; - case MULT: - goto L345; - case DIV: - goto L377; - case MOD: - goto L410; - case AND: - goto L458; - case IOR: - goto L476; - case XOR: - goto L697; - case NEG: - goto L514; - case NOT: - goto L526; - case ASHIFT: - goto L538; - case ASHIFTRT: - goto L553; - case LSHIFT: - goto L586; - case LSHIFTRT: - goto L601; - case ROTATE: - goto L634; - case ROTATERT: - goto L649; - case ZERO_EXTRACT: - goto L718; - } - } - if (general_operand (x1, SImode)) - { - ro[1] = x1; - return 15; - } - L681: - if (address_operand (x1, QImode)) - { - ro[1] = x1; - return 150; - } - goto ret0; - - L105: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[1] = x2; - return 25; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - return 27; - } - } - goto ret0; - - L125: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[1] = x2; - return 30; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - return 32; - } - } - goto ret0; - - L167: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SFmode: - switch (GET_CODE (x2)) - { - case FIX: - goto L168; - } - break; - case DFmode: - if (GET_CODE (x2) == FIX && 1) - goto L183; - } - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 52; - } - L237: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 55; - } - goto ret0; - - L168: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 40; - } - goto ret0; - - L183: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 43; - } - goto ret0; - - L197: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) != FIX) - goto ret0; - switch (GET_MODE (x2)) - { - case SFmode: - goto L198; - case DFmode: - goto L213; - } - goto ret0; - - L198: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 46; - } - goto ret0; - - L213: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 49; - } - goto ret0; - - L256: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - switch (GET_CODE (x2)) - { - case REG: - if (XINT (x2, 0) == 16 && 1) - goto L257; - if (XINT (x2, 0) == 17 && 1) - goto L262; - } - } - L266: - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L267; - } - goto L681; - - L257: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) == CONST_INT) - return 59; - } - x2 = XEXP (x1, 0); - goto L266; - - L262: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) == CONST_INT) - return 60; - } - x2 = XEXP (x1, 0); - goto L266; - - L267: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 61; - } - goto L681; - - L308: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L309; - } - goto L681; - - L309: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 69; - } - goto L681; - - L345: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L346; - } - goto L681; - - L346: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 76; - } - goto L681; - - L377: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L378; - } - goto ret0; - - L378: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 82; - } - goto ret0; - - L410: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L411; - } - goto ret0; - - L411: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 88; - } - goto ret0; - - L458: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L459; - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L444; - } - goto ret0; - - L459: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L460; - } - goto ret0; - - L460: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 97; - } - goto ret0; - - L444: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 94; - } - goto ret0; - - L476: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L477; - } - goto ret0; - - L477: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 100; - } - goto ret0; - - L697: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == ASHIFT && 1) - goto L698; - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L492; - } - goto ret0; - - L698: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 1 && 1) - goto L699; - goto ret0; - - L699: - x3 = XEXP (x2, 1); - if (general_operand (x3, SImode)) - { - ro[1] = x3; - goto L700; - } - goto ret0; - - L700: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 153; - goto ret0; - - L492: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 103; - } - goto ret0; - - L514: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 108; - } - goto ret0; - - L526: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 111; - } - goto ret0; - - L538: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L539; - } - goto ret0; - - L539: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 114; - } - goto ret0; - - L553: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L559; - } - goto ret0; - - L559: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L560; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 118; - } - goto ret0; - - L560: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 119; - } - goto ret0; - - L586: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L587; - } - goto ret0; - - L587: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 126; - } - goto ret0; - - L601: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L607; - } - goto ret0; - - L607: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L608; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 130; - } - goto ret0; - - L608: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 131; - } - goto ret0; - - L634: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L635; - } - goto ret0; - - L635: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 138; - } - goto ret0; - - L649: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L655; - } - goto ret0; - - L655: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L656; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 142; - } - goto ret0; - - L656: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 143; - } - goto ret0; - - L718: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L719; - } - break; - case QImode: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L731; - } - } - goto ret0; - - L719: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[2] = x2; - goto L720; - } - goto ret0; - - L720: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[3] = x2; - if ((INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && (INTVAL (operands[3]) == 8 || INTVAL (operands[3]) == 16 || INTVAL (operands[3]) == 24)) - return 156; - } - L726: - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (! TARGET_32532) - return 157; - } - goto ret0; - - L731: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[2] = x2; - goto L732; - } - goto ret0; - - L732: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[3] = x2; - if (! TARGET_32532) - return 158; - } - goto ret0; - ret0: return -1; -} - -int -recog_2 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case HImode: - switch (GET_CODE (x1)) - { - case TRUNCATE: - goto L97; - case SIGN_EXTEND: - goto L109; - case ZERO_EXTEND: - goto L129; - case FIX: - goto L162; - case UNSIGNED_FIX: - goto L192; - case PLUS: - goto L271; - case MINUS: - goto L313; - case MULT: - goto L350; - case DIV: - goto L382; - case MOD: - goto L415; - case AND: - goto L464; - case IOR: - goto L481; - case XOR: - goto L496; - case NEG: - goto L518; - case NOT: - goto L530; - case ASHIFT: - goto L543; - case ASHIFTRT: - goto L564; - case LSHIFT: - goto L591; - case LSHIFTRT: - goto L612; - case ROTATE: - goto L639; - case ROTATERT: - goto L660; - } - } - if (general_operand (x1, HImode)) - { - ro[1] = x1; - return 16; - } - goto ret0; - - L97: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, SImode)) - { - ro[1] = x2; - return 23; - } - goto ret0; - - L109: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - return 26; - } - goto ret0; - - L129: - x2 = XEXP (x1, 0); - if (nonimmediate_operand (x2, QImode)) - { - ro[1] = x2; - return 31; - } - goto ret0; - - L162: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SFmode: - switch (GET_CODE (x2)) - { - case FIX: - goto L163; - } - break; - case DFmode: - if (GET_CODE (x2) == FIX && 1) - goto L178; - } - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 51; - } - L233: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 54; - } - goto ret0; - - L163: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 39; - } - goto ret0; - - L178: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 42; - } - goto ret0; - - L192: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) != FIX) - goto ret0; - switch (GET_MODE (x2)) - { - case SFmode: - goto L193; - case DFmode: - goto L208; - } - goto ret0; - - L193: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 45; - } - goto ret0; - - L208: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 48; - } - goto ret0; - - L271: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L272; - } - goto ret0; - - L272: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 62; - } - goto ret0; - - L313: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L314; - } - goto ret0; - - L314: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 70; - } - goto ret0; - - L350: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L351; - } - goto ret0; - - L351: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 77; - } - goto ret0; - - L382: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L383; - } - goto ret0; - - L383: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 83; - } - goto ret0; - - L415: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L416; - } - goto ret0; - - L416: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 89; - } - goto ret0; - - L464: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == NOT && 1) - goto L465; - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L449; - } - goto ret0; - - L465: - x3 = XEXP (x2, 0); - if (general_operand (x3, HImode)) - { - ro[1] = x3; - goto L466; - } - goto ret0; - - L466: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 98; - } - goto ret0; - - L449: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 95; - } - goto ret0; - - L481: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L482; - } - goto ret0; - - L482: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 101; - } - goto ret0; - - L496: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L497; - } - goto ret0; - - L497: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 104; - } - goto ret0; - - L518: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 109; - } - goto ret0; - - L530: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 112; - } - goto ret0; - - L543: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L544; - } - goto ret0; - - L544: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 115; - } - goto ret0; - - L564: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L570; - } - goto ret0; - - L570: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L571; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 121; - } - goto ret0; - - L571: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 122; - } - goto ret0; - - L591: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L592; - } - goto ret0; - - L592: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 127; - } - goto ret0; - - L612: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L618; - } - goto ret0; - - L618: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L619; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 133; - } - goto ret0; - - L619: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 134; - } - goto ret0; - - L639: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L640; - } - goto ret0; - - L640: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 139; - } - goto ret0; - - L660: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L666; - } - goto ret0; - - L666: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L667; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 145; - } - goto ret0; - - L667: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 146; - } - goto ret0; - ret0: return -1; -} - -int -recog_3 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case QImode: - switch (GET_CODE (x1)) - { - case TRUNCATE: - goto L93; - case FIX: - goto L157; - case UNSIGNED_FIX: - goto L187; - case PLUS: - goto L282; - case MINUS: - goto L324; - case MULT: - goto L355; - case DIV: - goto L387; - case MOD: - goto L420; - case AND: - goto L470; - case IOR: - goto L486; - case XOR: - goto L704; - case NEG: - goto L522; - case NOT: - goto L534; - case ASHIFT: - goto L548; - case ASHIFTRT: - goto L575; - case LSHIFT: - goto L596; - case LSHIFTRT: - goto L623; - case ROTATE: - goto L644; - case ROTATERT: - goto L671; - } - } - if (general_operand (x1, QImode)) - { - ro[1] = x1; - return 18; - } - goto ret0; - - L93: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[1] = x2; - return 22; - } - break; - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[1] = x2; - return 24; - } - } - goto ret0; - - L157: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SFmode: - switch (GET_CODE (x2)) - { - case FIX: - goto L158; - } - break; - case DFmode: - if (GET_CODE (x2) == FIX && 1) - goto L173; - } - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 50; - } - L229: - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 53; - } - goto ret0; - - L158: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 38; - } - goto ret0; - - L173: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 41; - } - goto ret0; - - L187: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) != FIX) - goto ret0; - switch (GET_MODE (x2)) - { - case SFmode: - goto L188; - case DFmode: - goto L203; - } - goto ret0; - - L188: - x3 = XEXP (x2, 0); - if (general_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 44; - } - goto ret0; - - L203: - x3 = XEXP (x2, 0); - if (general_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_32081) - return 47; - } - goto ret0; - - L282: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L283; - } - goto ret0; - - L283: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 64; - } - goto ret0; - - L324: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L325; - } - goto ret0; - - L325: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 72; - } - goto ret0; - - L355: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L356; - } - goto ret0; - - L356: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 78; - } - goto ret0; - - L387: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L388; - } - goto ret0; - - L388: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 84; - } - goto ret0; - - L420: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L421; - } - goto ret0; - - L421: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 90; - } - goto ret0; - - L470: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == QImode && GET_CODE (x2) == NOT && 1) - goto L471; - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L454; - } - goto ret0; - - L471: - x3 = XEXP (x2, 0); - if (general_operand (x3, QImode)) - { - ro[1] = x3; - goto L472; - } - goto ret0; - - L472: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 99; - } - goto ret0; - - L454: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 96; - } - goto ret0; - - L486: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L487; - } - goto ret0; - - L487: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 102; - } - goto ret0; - - L704: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == QImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L705; - L501: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L502; - } - goto ret0; - - L705: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == ASHIFT && 1) - goto L706; - goto L501; - - L706: - x4 = XEXP (x3, 0); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 1 && 1) - goto L707; - goto L501; - - L707: - x4 = XEXP (x3, 1); - if (general_operand (x4, QImode)) - { - ro[1] = x4; - goto L708; - } - goto L501; - - L708: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[0]) && 1) - return 154; - x2 = XEXP (x1, 0); - goto L501; - - L502: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 105; - } - goto ret0; - - L522: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 110; - } - goto ret0; - - L534: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 113; - } - goto ret0; - - L548: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L549; - } - goto ret0; - - L549: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 116; - } - goto ret0; - - L575: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L581; - } - goto ret0; - - L581: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L582; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 124; - } - goto ret0; - - L582: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 125; - } - goto ret0; - - L596: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L597; - } - goto ret0; - - L597: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 128; - } - goto ret0; - - L623: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L629; - } - goto ret0; - - L629: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L630; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 136; - } - goto ret0; - - L630: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 137; - } - goto ret0; - - L644: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L645; - } - goto ret0; - - L645: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 140; - } - goto ret0; - - L671: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L677; - } - goto ret0; - - L677: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L678; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 148; - } - goto ret0; - - L678: - x3 = XEXP (x2, 0); - if (general_operand (x3, SImode)) - { - ro[2] = x3; - return 149; - } - goto ret0; - ret0: return -1; -} - -int -recog_4 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - x1 = XEXP (x0, 1); - x2 = XEXP (x1, 0); - switch (GET_CODE (x2)) - { - case EQ: - goto L759; - case NE: - goto L768; - case GT: - goto L777; - case GTU: - goto L786; - case LT: - goto L795; - case LTU: - goto L804; - case GE: - goto L813; - case GEU: - goto L822; - case LE: - goto L831; - case LEU: - goto L840; - } - goto ret0; - - L759: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L760; - goto ret0; - - L760: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L761; - goto ret0; - - L761: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L762; - case PC: - goto L852; - } - goto ret0; - - L762: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L763; - - L763: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 163; - goto ret0; - - L852: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L853; - goto ret0; - - L853: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 173; - - L768: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L769; - goto ret0; - - L769: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L770; - goto ret0; - - L770: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L771; - case PC: - goto L861; - } - goto ret0; - - L771: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L772; - - L772: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 164; - goto ret0; - - L861: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L862; - goto ret0; - - L862: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 174; - - L777: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L778; - goto ret0; - - L778: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L779; - goto ret0; - - L779: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L780; - case PC: - goto L870; - } - goto ret0; - - L780: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L781; - - L781: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 165; - goto ret0; - - L870: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L871; - goto ret0; - - L871: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 175; - - L786: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L787; - goto ret0; - - L787: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L788; - goto ret0; - - L788: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L789; - case PC: - goto L879; - } - goto ret0; - - L789: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L790; - - L790: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 166; - goto ret0; - - L879: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L880; - goto ret0; - - L880: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 176; - - L795: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L796; - goto ret0; - - L796: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L797; - goto ret0; - - L797: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L798; - case PC: - goto L888; - } - goto ret0; - - L798: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L799; - - L799: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 167; - goto ret0; - - L888: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L889; - goto ret0; - - L889: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 177; - - L804: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L805; - goto ret0; - - L805: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L806; - goto ret0; - - L806: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L807; - case PC: - goto L897; - } - goto ret0; - - L807: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L808; - - L808: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 168; - goto ret0; - - L897: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L898; - goto ret0; - - L898: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 178; - - L813: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L814; - goto ret0; - - L814: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L815; - goto ret0; - - L815: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L816; - case PC: - goto L906; - } - goto ret0; - - L816: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L817; - - L817: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 169; - goto ret0; - - L906: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L907; - goto ret0; - - L907: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 179; - - L822: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L823; - goto ret0; - - L823: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L824; - goto ret0; - - L824: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L825; - case PC: - goto L915; - } - goto ret0; - - L825: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L826; - - L826: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 170; - goto ret0; - - L915: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L916; - goto ret0; - - L916: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 180; - - L831: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L832; - goto ret0; - - L832: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L833; - goto ret0; - - L833: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L834; - case PC: - goto L924; - } - goto ret0; - - L834: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L835; - - L835: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 171; - goto ret0; - - L924: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L925; - goto ret0; - - L925: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 181; - - L840: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CC0 && 1) - goto L841; - goto ret0; - - L841: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L842; - goto ret0; - - L842: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L843; - case PC: - goto L933; - } - goto ret0; - - L843: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L844; - - L844: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 172; - goto ret0; - - L933: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L934; - goto ret0; - - L934: - x3 = XEXP (x2, 0); - ro[0] = x3; - return 182; - ret0: return -1; -} - -int -recog_5 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - x1 = XEXP (x0, 0); - switch (GET_MODE (x1)) - { - case DFmode: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - goto L116; - } - break; - case SFmode: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - goto L120; - } - break; - case TImode: - if (memory_operand (x1, TImode)) - { - ro[0] = x1; - goto L48; - } - break; - case DImode: - if (general_operand (x1, DImode)) - { - ro[0] = x1; - goto L359; - } - break; - case SImode: - switch (GET_CODE (x1)) - { - case REG: - if (XINT (x1, 0) == 17 && 1) - goto L250; - break; - case ZERO_EXTRACT: - goto L684; - } - L56: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L104; - } - L390: - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L391; - } - break; - case HImode: - if (general_operand (x1, HImode)) - { - ro[0] = x1; - goto L96; - } - L396: - if (register_operand (x1, HImode)) - { - ro[0] = x1; - goto L397; - } - break; - case QImode: - if (general_operand (x1, QImode)) - { - ro[0] = x1; - goto L92; - } - L402: - if (register_operand (x1, QImode)) - { - ro[0] = x1; - goto L403; - } - } - switch (GET_CODE (x1)) - { - case CC0: - goto L2; - case STRICT_LOW_PART: - goto L63; - case PC: - goto L753; - } - L969: - ro[0] = x1; - goto L970; - L977: - switch (GET_MODE (x1)) - { - case SFmode: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - goto L978; - } - break; - case DFmode: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - goto L982; - } - break; - case SImode: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L986; - } - break; - case HImode: - if (general_operand (x1, HImode)) - { - ro[0] = x1; - goto L990; - } - break; - case QImode: - if (general_operand (x1, QImode)) - { - ro[0] = x1; - goto L994; - } - } - if (GET_CODE (x1) == PC && 1) - goto L999; - goto ret0; - - L116: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case DFmode: - switch (GET_CODE (x1)) - { - case FLOAT_EXTEND: - goto L117; - case FLOAT: - goto L141; - case PLUS: - goto L241; - case MINUS: - goto L293; - case MULT: - goto L335; - case DIV: - goto L367; - case NEG: - goto L506; - } - } - if (general_operand (x1, DFmode)) - { - ro[1] = x1; - return 10; - } - x1 = XEXP (x0, 0); - goto L969; - - L117: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 28; - } - x1 = XEXP (x0, 0); - goto L969; - - L141: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_32081) - return 34; - } - L149: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - if (TARGET_32081) - return 36; - } - x1 = XEXP (x0, 0); - goto L969; - - L241: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L242; - } - x1 = XEXP (x0, 0); - goto L969; - - L242: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 56; - } - x1 = XEXP (x0, 0); - goto L969; - - L293: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L294; - } - x1 = XEXP (x0, 0); - goto L969; - - L294: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 66; - } - x1 = XEXP (x0, 0); - goto L969; - - L335: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L336; - } - x1 = XEXP (x0, 0); - goto L969; - - L336: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 74; - } - x1 = XEXP (x0, 0); - goto L969; - - L367: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - goto L368; - } - x1 = XEXP (x0, 0); - goto L969; - - L368: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 80; - } - x1 = XEXP (x0, 0); - goto L969; - - L506: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 106; - } - x1 = XEXP (x0, 0); - goto L969; - - L120: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SFmode: - switch (GET_CODE (x1)) - { - case FLOAT_TRUNCATE: - goto L121; - case FLOAT: - goto L137; - case PLUS: - goto L246; - case MINUS: - goto L298; - case MULT: - goto L340; - case DIV: - goto L372; - case NEG: - goto L510; - } - } - if (general_operand (x1, SFmode)) - { - ro[1] = x1; - return 11; - } - x1 = XEXP (x0, 0); - goto L969; - - L121: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 29; - } - x1 = XEXP (x0, 0); - goto L969; - - L137: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_32081) - return 33; - } - L145: - if (general_operand (x2, HImode)) - { - ro[1] = x2; - if (TARGET_32081) - return 35; - } - L153: - if (general_operand (x2, QImode)) - { - ro[1] = x2; - if (TARGET_32081) - return 37; - } - x1 = XEXP (x0, 0); - goto L969; - - L246: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L247; - } - x1 = XEXP (x0, 0); - goto L969; - - L247: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 57; - } - x1 = XEXP (x0, 0); - goto L969; - - L298: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L299; - } - x1 = XEXP (x0, 0); - goto L969; - - L299: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 67; - } - x1 = XEXP (x0, 0); - goto L969; - - L340: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L341; - } - x1 = XEXP (x0, 0); - goto L969; - - L341: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 75; - } - x1 = XEXP (x0, 0); - goto L969; - - L372: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - goto L373; - } - x1 = XEXP (x0, 0); - goto L969; - - L373: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_32081) - return 81; - } - x1 = XEXP (x0, 0); - goto L969; - - L510: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 107; - } - x1 = XEXP (x0, 0); - goto L969; - - L48: - x1 = XEXP (x0, 1); - if (memory_operand (x1, TImode)) - { - ro[1] = x1; - return 12; - } - x1 = XEXP (x0, 0); - goto L969; - - L359: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == DImode && GET_CODE (x1) == MULT && 1) - goto L360; - if (general_operand (x1, DImode)) - { - ro[1] = x1; - return 13; - } - x1 = XEXP (x0, 0); - goto L969; - - L360: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DImode && GET_CODE (x2) == ZERO_EXTEND && 1) - goto L361; - x1 = XEXP (x0, 0); - goto L969; - - L361: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, SImode)) - { - ro[1] = x3; - goto L362; - } - x1 = XEXP (x0, 0); - goto L969; - - L362: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DImode && GET_CODE (x2) == ZERO_EXTEND && 1) - goto L363; - x1 = XEXP (x0, 0); - goto L969; - - L363: - x3 = XEXP (x2, 0); - if (nonimmediate_operand (x3, SImode)) - { - ro[2] = x3; - return 79; - } - x1 = XEXP (x0, 0); - goto L969; - - L250: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - switch (GET_CODE (x1)) - { - case PLUS: - goto L251; - case MINUS: - goto L303; - } - } - if (general_operand (x1, SImode)) - { - ro[0] = x1; - return 14; - } - x1 = XEXP (x0, 0); - goto L56; - - L251: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 17 && 1) - goto L252; - x1 = XEXP (x0, 0); - goto L56; - - L252: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[0] = x2; - if (GET_CODE (operands[0]) == CONST_INT) - return 58; - } - x1 = XEXP (x0, 0); - goto L56; - - L303: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 17 && 1) - goto L304; - x1 = XEXP (x0, 0); - goto L56; - - L304: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, SImode)) - { - ro[0] = x2; - if (GET_CODE (operands[0]) == CONST_INT) - return 68; - } - x1 = XEXP (x0, 0); - goto L56; - - L684: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (general_operand (x2, SImode)) - { - ro[0] = x2; - goto L685; - } - L735: - if (memory_operand (x2, SImode)) - { - ro[0] = x2; - goto L736; - } - L741: - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L742; - } - break; - case QImode: - if (general_operand (x2, QImode)) - { - ro[0] = x2; - goto L748; - } - } - goto L969; - - L685: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 1 && 1) - goto L686; - x2 = XEXP (x1, 0); - goto L735; - - L686: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - goto L687; - } - x2 = XEXP (x1, 0); - goto L735; - - L687: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) != CONST_INT) - { - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L735; - } - if (XWINT (x1, 0) == 1 && 1) - return 151; - if (XWINT (x1, 0) == 0 && 1) - return 152; - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L735; - - L736: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[1] = x2; - goto L737; - } - x2 = XEXP (x1, 0); - goto L741; - - L737: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L738; - } - x2 = XEXP (x1, 0); - goto L741; - - L738: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[3] = x1; - return 159; - } - x1 = XEXP (x0, 0); - x2 = XEXP (x1, 0); - goto L741; - - L742: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[1] = x2; - goto L743; - } - goto L969; - - L743: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L744; - } - goto L969; - - L744: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[3] = x1; - return 160; - } - x1 = XEXP (x0, 0); - goto L969; - - L748: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - { - ro[1] = x2; - goto L749; - } - goto L969; - - L749: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L750; - } - goto L969; - - L750: - x1 = XEXP (x0, 1); - if (general_operand (x1, SImode)) - { - ro[3] = x1; - return 161; - } - x1 = XEXP (x0, 0); - goto L969; - L104: - tem = recog_1 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L390; - - L391: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SImode) - { - x1 = XEXP (x0, 0); - goto L969; - } - switch (GET_CODE (x1)) - { - case UDIV: - goto L392; - case UMOD: - goto L425; - } - x1 = XEXP (x0, 0); - goto L969; - - L392: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L393; - x1 = XEXP (x0, 0); - goto L969; - - L393: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L394; - } - x1 = XEXP (x0, 0); - goto L969; - - L394: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 85; - } - x1 = XEXP (x0, 0); - goto L969; - - L425: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L426; - x1 = XEXP (x0, 0); - goto L969; - - L426: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L427; - } - x1 = XEXP (x0, 0); - goto L969; - - L427: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - return 91; - } - x1 = XEXP (x0, 0); - goto L969; - L96: - tem = recog_2 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L396; - - L397: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != HImode) - { - x1 = XEXP (x0, 0); - goto L969; - } - switch (GET_CODE (x1)) - { - case UDIV: - goto L398; - case UMOD: - goto L431; - } - x1 = XEXP (x0, 0); - goto L969; - - L398: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L399; - x1 = XEXP (x0, 0); - goto L969; - - L399: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L400; - } - x1 = XEXP (x0, 0); - goto L969; - - L400: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 86; - } - x1 = XEXP (x0, 0); - goto L969; - - L431: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == HImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L432; - x1 = XEXP (x0, 0); - goto L969; - - L432: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L433; - } - x1 = XEXP (x0, 0); - goto L969; - - L433: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 92; - } - x1 = XEXP (x0, 0); - goto L969; - L92: - tem = recog_3 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L402; - - L403: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != QImode) - { - x1 = XEXP (x0, 0); - goto L969; - } - switch (GET_CODE (x1)) - { - case UDIV: - goto L404; - case UMOD: - goto L437; - } - x1 = XEXP (x0, 0); - goto L969; - - L404: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == QImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L405; - x1 = XEXP (x0, 0); - goto L969; - - L405: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L406; - } - x1 = XEXP (x0, 0); - goto L969; - - L406: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 87; - } - x1 = XEXP (x0, 0); - goto L969; - - L437: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == QImode && GET_CODE (x2) == SUBREG && XINT (x2, 1) == 0 && 1) - goto L438; - x1 = XEXP (x0, 0); - goto L969; - - L438: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == DImode && reg_or_mem_operand (x3, DImode)) - { - ro[1] = x3; - goto L439; - } - x1 = XEXP (x0, 0); - goto L969; - - L439: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 93; - } - x1 = XEXP (x0, 0); - goto L969; - - L2: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - if (nonimmediate_operand (x1, SImode)) - { - ro[0] = x1; - return 0; - } - break; - case HImode: - if (nonimmediate_operand (x1, HImode)) - { - ro[0] = x1; - return 1; - } - break; - case QImode: - if (nonimmediate_operand (x1, QImode)) - { - ro[0] = x1; - return 2; - } - } - switch (GET_CODE (x1)) - { - case COMPARE: - goto L18; - case ZERO_EXTRACT: - goto L712; - case CONST_INT: - case CONST_DOUBLE: - case CONST: - case SYMBOL_REF: - case LABEL_REF: - case SUBREG: - case REG: - case MEM: - L11: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - if (TARGET_32081) - return 3; - } - } - L14: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - if (TARGET_32081) - return 4; - } - x1 = XEXP (x0, 0); - goto L969; - - L18: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (nonimmediate_operand (x2, SImode)) - { - ro[0] = x2; - goto L19; - } - break; - case HImode: - if (nonimmediate_operand (x2, HImode)) - { - ro[0] = x2; - goto L24; - } - break; - case QImode: - if (nonimmediate_operand (x2, QImode)) - { - ro[0] = x2; - goto L29; - } - break; - case DFmode: - if (general_operand (x2, DFmode)) - { - ro[0] = x2; - goto L34; - } - break; - case SFmode: - if (general_operand (x2, SFmode)) - { - ro[0] = x2; - goto L39; - } - } - x1 = XEXP (x0, 0); - goto L969; - - L19: - x2 = XEXP (x1, 1); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 5; - } - x1 = XEXP (x0, 0); - goto L969; - - L24: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 6; - } - x1 = XEXP (x0, 0); - goto L969; - - L29: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 7; - } - x1 = XEXP (x0, 0); - goto L969; - - L34: - x2 = XEXP (x1, 1); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 8; - } - x1 = XEXP (x0, 0); - goto L969; - - L39: - x2 = XEXP (x1, 1); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 9; - } - x1 = XEXP (x0, 0); - goto L969; - - L712: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && general_operand (x2, SImode)) - { - ro[0] = x2; - goto L713; - } - x1 = XEXP (x0, 0); - goto L969; - - L713: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 1 && 1) - goto L714; - x1 = XEXP (x0, 0); - goto L969; - - L714: - x2 = XEXP (x1, 2); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 155; - } - x1 = XEXP (x0, 0); - goto L969; - - L63: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (general_operand (x2, HImode)) - { - ro[0] = x2; - goto L276; - } - break; - case QImode: - if (general_operand (x2, QImode)) - { - ro[0] = x2; - goto L287; - } - } - goto L969; - - L276: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case HImode: - switch (GET_CODE (x1)) - { - case PLUS: - goto L277; - case MINUS: - goto L319; - } - } - if (general_operand (x1, HImode)) - { - ro[1] = x1; - return 17; - } - x1 = XEXP (x0, 0); - goto L969; - - L277: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L278; - } - x1 = XEXP (x0, 0); - goto L969; - - L278: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 63; - } - x1 = XEXP (x0, 0); - goto L969; - - L319: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - goto L320; - } - x1 = XEXP (x0, 0); - goto L969; - - L320: - x2 = XEXP (x1, 1); - if (general_operand (x2, HImode)) - { - ro[2] = x2; - return 71; - } - x1 = XEXP (x0, 0); - goto L969; - - L287: - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case QImode: - switch (GET_CODE (x1)) - { - case PLUS: - goto L288; - case MINUS: - goto L330; - } - } - if (general_operand (x1, QImode)) - { - ro[1] = x1; - return 19; - } - x1 = XEXP (x0, 0); - goto L969; - - L288: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L289; - } - x1 = XEXP (x0, 0); - goto L969; - - L289: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 65; - } - x1 = XEXP (x0, 0); - goto L969; - - L330: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - goto L331; - } - x1 = XEXP (x0, 0); - goto L969; - - L331: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 73; - } - x1 = XEXP (x0, 0); - goto L969; - - L753: - x1 = XEXP (x0, 1); - switch (GET_CODE (x1)) - { - case LABEL_REF: - goto L754; - case IF_THEN_ELSE: - goto L758; - } - x1 = XEXP (x0, 0); - goto L969; - - L754: - x2 = XEXP (x1, 0); - ro[0] = x2; - return 162; - L758: - tem = recog_4 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L969; - - L970: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) == CALL && 1) - goto L971; - x1 = XEXP (x0, 0); - goto L977; - - L971: - x2 = XEXP (x1, 0); - if (memory_operand (x2, QImode)) - { - ro[1] = x2; - goto L972; - } - x1 = XEXP (x0, 0); - goto L977; - - L972: - x2 = XEXP (x1, 1); - if (general_operand (x2, QImode)) - { - ro[2] = x2; - return 186; - } - x1 = XEXP (x0, 0); - goto L977; - - L978: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SFmode && GET_CODE (x1) == ABS && 1) - goto L979; - goto ret0; - - L979: - x2 = XEXP (x1, 0); - if (general_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 190; - } - goto ret0; - - L982: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == DFmode && GET_CODE (x1) == ABS && 1) - goto L983; - goto ret0; - - L983: - x2 = XEXP (x1, 0); - if (general_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_32081) - return 191; - } - goto ret0; - - L986: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SImode) - goto ret0; - switch (GET_CODE (x1)) - { - case ABS: - goto L987; - case EQ: - goto L1012; - case NE: - goto L1027; - case GT: - goto L1042; - case GTU: - goto L1057; - case LT: - goto L1072; - case LTU: - goto L1087; - case GE: - goto L1102; - case GEU: - goto L1117; - case LE: - goto L1132; - case LEU: - goto L1147; - case FFS: - goto L1170; - } - goto ret0; - - L987: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 192; - } - goto ret0; - - L1012: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1013; - goto ret0; - - L1013: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 198; - goto ret0; - - L1027: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1028; - goto ret0; - - L1028: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 201; - goto ret0; - - L1042: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1043; - goto ret0; - - L1043: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 204; - goto ret0; - - L1057: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1058; - goto ret0; - - L1058: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 207; - goto ret0; - - L1072: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1073; - goto ret0; - - L1073: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 210; - goto ret0; - - L1087: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1088; - goto ret0; - - L1088: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 213; - goto ret0; - - L1102: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1103; - goto ret0; - - L1103: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 216; - goto ret0; - - L1117: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1118; - goto ret0; - - L1118: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 219; - goto ret0; - - L1132: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1133; - goto ret0; - - L1133: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 222; - goto ret0; - - L1147: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1148; - goto ret0; - - L1148: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 225; - goto ret0; - - L1170: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 230; - } - goto ret0; - - L990: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != HImode) - goto ret0; - switch (GET_CODE (x1)) - { - case ABS: - goto L991; - case EQ: - goto L1017; - case NE: - goto L1032; - case GT: - goto L1047; - case GTU: - goto L1062; - case LT: - goto L1077; - case LTU: - goto L1092; - case GE: - goto L1107; - case GEU: - goto L1122; - case LE: - goto L1137; - case LEU: - goto L1152; - case FFS: - goto L1166; - } - goto ret0; - - L991: - x2 = XEXP (x1, 0); - if (general_operand (x2, HImode)) - { - ro[1] = x2; - return 193; - } - goto ret0; - - L1017: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1018; - goto ret0; - - L1018: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 199; - goto ret0; - - L1032: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1033; - goto ret0; - - L1033: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 202; - goto ret0; - - L1047: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1048; - goto ret0; - - L1048: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 205; - goto ret0; - - L1062: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1063; - goto ret0; - - L1063: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 208; - goto ret0; - - L1077: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1078; - goto ret0; - - L1078: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 211; - goto ret0; - - L1092: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1093; - goto ret0; - - L1093: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 214; - goto ret0; - - L1107: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1108; - goto ret0; - - L1108: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 217; - goto ret0; - - L1122: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1123; - goto ret0; - - L1123: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 220; - goto ret0; - - L1137: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1138; - goto ret0; - - L1138: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 223; - goto ret0; - - L1152: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1153; - goto ret0; - - L1153: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 226; - goto ret0; - - L1166: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 229; - } - goto ret0; - - L994: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != QImode) - goto ret0; - switch (GET_CODE (x1)) - { - case ABS: - goto L995; - case EQ: - goto L1022; - case NE: - goto L1037; - case GT: - goto L1052; - case GTU: - goto L1067; - case LT: - goto L1082; - case LTU: - goto L1097; - case GE: - goto L1112; - case GEU: - goto L1127; - case LE: - goto L1142; - case LEU: - goto L1157; - case FFS: - goto L1162; - } - goto ret0; - - L995: - x2 = XEXP (x1, 0); - if (general_operand (x2, QImode)) - { - ro[1] = x2; - return 194; - } - goto ret0; - - L1022: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1023; - goto ret0; - - L1023: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 200; - goto ret0; - - L1037: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1038; - goto ret0; - - L1038: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 203; - goto ret0; - - L1052: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1053; - goto ret0; - - L1053: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 206; - goto ret0; - - L1067: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1068; - goto ret0; - - L1068: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 209; - goto ret0; - - L1082: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1083; - goto ret0; - - L1083: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 212; - goto ret0; - - L1097: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1098; - goto ret0; - - L1098: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 215; - goto ret0; - - L1112: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1113; - goto ret0; - - L1113: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 218; - goto ret0; - - L1127: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1128; - goto ret0; - - L1128: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 221; - goto ret0; - - L1142: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1143; - goto ret0; - - L1143: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 224; - goto ret0; - - L1157: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CC0 && 1) - goto L1158; - goto ret0; - - L1158: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 227; - goto ret0; - - L1162: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[1] = x2; - return 228; - } - goto ret0; - - L999: - x1 = XEXP (x0, 1); - if (register_operand (x1, SImode)) - { - ro[0] = x1; - return 196; - } - goto ret0; - ret0: return -1; -} - -int -recog (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - int tem; - - L0: - switch (GET_CODE (x0)) - { - case SET: - goto L41; - case PARALLEL: - if (XVECLEN (x0, 0) == 5 && 1) - goto L73; - if (XVECLEN (x0, 0) == 2 && 1) - goto L85; - break; - case CALL: - goto L966; - case UNSPEC_VOLATILE: - if (XINT (x0, 1) == 0 && XVECLEN (x0, 0) == 1 && 1) - goto L974; - break; - case RETURN: - if (0) - return 189; - break; - case CONST_INT: - if (XWINT (x0, 0) == 0 && 1) - return 195; - } - goto ret0; - L41: - return recog_5 (x0, insn, pnum_clobbers); - - L73: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == SET && 1) - goto L74; - goto ret0; - - L74: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == BLKmode && general_operand (x2, BLKmode)) - { - ro[0] = x2; - goto L75; - } - goto ret0; - - L75: - x2 = XEXP (x1, 1); - if (general_operand (x2, BLKmode)) - { - ro[1] = x2; - goto L76; - } - goto ret0; - - L76: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L77; - goto ret0; - - L77: - x2 = XEXP (x1, 0); - if (general_operand (x2, SImode)) - { - ro[2] = x2; - goto L78; - } - goto ret0; - - L78: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L79; - goto ret0; - - L79: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L80; - goto ret0; - - L80: - x1 = XVECEXP (x0, 0, 3); - if (GET_CODE (x1) == CLOBBER && 1) - goto L81; - goto ret0; - - L81: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 1 && 1) - goto L82; - goto ret0; - - L82: - x1 = XVECEXP (x0, 0, 4); - if (GET_CODE (x1) == CLOBBER && 1) - goto L83; - goto ret0; - - L83: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 2 && 1) - return 21; - goto ret0; - - L85: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == SET && 1) - goto L86; - goto ret0; - - L86: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == BLKmode && general_operand (x2, BLKmode)) - { - ro[0] = x2; - goto L87; - } - if (GET_CODE (x2) == PC && 1) - goto L1003; - goto ret0; - - L87: - x2 = XEXP (x1, 1); - if (general_operand (x2, BLKmode)) - { - ro[1] = x2; - goto L88; - } - goto ret0; - - L88: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L89; - goto ret0; - - L89: - x2 = XEXP (x1, 0); - if (pnum_clobbers != 0 && general_operand (x2, SImode)) - { - ro[2] = x2; - *pnum_clobbers = 3; - return 21; - } - goto ret0; - - L1003: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case PLUS: - if (GET_MODE (x2) == SImode && 1) - goto L1004; - break; - case IF_THEN_ELSE: - goto L939; - } - goto ret0; - - L1004: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == PC && 1) - goto L1005; - goto ret0; - - L1005: - x3 = XEXP (x2, 1); - if (general_operand (x3, SImode)) - { - ro[0] = x3; - goto L1006; - } - goto ret0; - - L1006: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L1007; - goto ret0; - - L1007: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1008; - goto ret0; - - L1008: - x3 = XEXP (x2, 0); - ro[1] = x3; - return 197; - - L939: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == NE && 1) - goto L940; - goto ret0; - - L940: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == SImode && general_operand (x4, SImode)) - { - ro[0] = x4; - goto L941; - } - goto ret0; - - L941: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && 1) - { - ro[1] = x4; - goto L942; - } - goto ret0; - - L942: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == LABEL_REF && 1) - goto L943; - goto ret0; - - L943: - x4 = XEXP (x3, 0); - ro[2] = x4; - goto L944; - - L944: - x3 = XEXP (x2, 2); - if (GET_CODE (x3) == PC && 1) - goto L945; - goto ret0; - - L945: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L946; - goto ret0; - - L946: - x2 = XEXP (x1, 0); - if (rtx_equal_p (x2, ro[0]) && 1) - goto L947; - goto ret0; - - L947: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != SImode) - goto ret0; - switch (GET_CODE (x2)) - { - case MINUS: - goto L948; - case PLUS: - goto L963; - } - goto ret0; - - L948: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L949; - goto ret0; - - L949: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[1]) && 1) - if (INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8) - return 183; - goto ret0; - - L963: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - goto L964; - goto ret0; - - L964: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && 1) - { - ro[3] = x3; - if (INTVAL (operands[1]) == - INTVAL (operands[3]) - && INTVAL (operands[3]) >= -8 && INTVAL (operands[3]) < 8) - return 184; - } - goto ret0; - - L966: - x1 = XEXP (x0, 0); - if (memory_operand (x1, QImode)) - { - ro[0] = x1; - goto L967; - } - goto ret0; - - L967: - x1 = XEXP (x0, 1); - if (general_operand (x1, QImode)) - { - ro[1] = x1; - return 185; - } - goto ret0; - - L974: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == CONST_INT && XWINT (x1, 0) == 0 && 1) - return 188; - goto ret0; - ret0: return -1; -} - -rtx -split_insns (x0, insn) - register rtx x0; - rtx insn; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4; - rtx tem; - - goto ret0; - ret0: return 0; -} - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/md b/gnu/usr.bin/gcc2/arch/ns32k/md deleted file mode 100644 index 8511a52c231..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/md +++ /dev/null @@ -1,2753 +0,0 @@ -; BUGS: -;; Insert no-op between an insn with memory read-write operands -;; following by a scale-indexing operation. -;; The Sequent assembler does not allow addresses to be used -;; except in insns which explicitly compute an effective address. -;; I.e., one cannot say "cmpd _p,@_x" -;; Implement unsigned multiplication?? - -;;- Machine description for GNU compiler -;;- ns32000 Version -;; Copyright (C) 1988 Free Software Foundation, Inc. -;; Contributed by Michael Tiemann (tiemann@mcc.com) - -;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - -;;- Instruction patterns. When multiple patterns apply, -;;- the first one in the file is chosen. -;;- -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. -;;- -;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code -;;- updates for most instructions. - -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. - -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "rm"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqd %1,%0\"; }") - -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "g"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqw %1,%0\"; }") - -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "g"))] - "" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = const0_rtx; - return \"cmpqb %1,%0\"; }") - -(define_insn "tstdf" - [(set (cc0) - (match_operand:DF 0 "general_operand" "fmF"))] - "TARGET_32081" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (DFmode); - return \"cmpl %1,%0\"; }") - -(define_insn "tstsf" - [(set (cc0) - (match_operand:SF 0 "general_operand" "fmF"))] - "TARGET_32081" - "* -{ cc_status.flags |= CC_REVERSED; - operands[1] = CONST0_RTX (SFmode); - return \"cmpf %1,%0\"; }") - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "rmn") - (match_operand:SI 1 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - return \"cmpqd %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - int i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - return \"cmpqd %0,%1\"; - } - return \"cmpd %0,%1\"; -}") - -(define_insn "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "g") - (match_operand:HI 1 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqw %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - short i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqw %0,%1\"; - } - } - return \"cmpw %0,%1\"; -}") - -(define_insn "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "g") - (match_operand:QI 1 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - char i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - cc_status.flags |= CC_REVERSED; - if (INTVAL (operands[1]) > 7) - operands[1] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqb %1,%0\"; - } - } - cc_status.flags &= ~CC_REVERSED; - if (GET_CODE (operands[0]) == CONST_INT) - { - char i = INTVAL (operands[0]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[0]) > 7) - operands[0] = gen_rtx(CONST_INT, VOIDmode, i); - return \"cmpqb %0,%1\"; - } - } - return \"cmpb %0,%1\"; -}") - -(define_insn "cmpdf" - [(set (cc0) - (compare (match_operand:DF 0 "general_operand" "fmF") - (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "cmpl %0,%1") - -(define_insn "cmpsf" - [(set (cc0) - (compare (match_operand:SF 0 "general_operand" "fmF") - (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "cmpf %0,%1") - -(define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=fg<") - (match_operand:DF 1 "general_operand" "fFg"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movl %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"movd %1,tos\", xoperands); - output_asm_insn (\"movd %1,tos\", operands); - return \"movl tos,%0\"; - } - return \"movl %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"movd tos,%0\"; - } - else - return \"movl %1,%0\"; - } - return output_move_double (operands); -}") - -(define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=fg<") - (match_operand:SF 1 "general_operand" "fFg"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movd %1,tos\;movf tos,%0\"; - else - return \"movf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } -#if 0 /* Someone suggested this for the Sequent. Is it needed? */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movf %1,%0\"; -#endif -/* There was a #if 0 around this, but that was erroneous - for many machines -- rms. */ -#ifndef MOVD_FLOAT_OK - /* GAS understands floating constants in ordinary movd instructions - but other assemblers might object. */ - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - union {int i[2]; float f; double d;} convrt; - convrt.i[0] = CONST_DOUBLE_LOW (operands[1]); - convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]); - convrt.f = convrt.d; - - /* Is there a better machine-independent way to to this? */ - operands[1] = gen_rtx (CONST_INT, VOIDmode, convrt.i[0]); - return \"movd %1,%0\"; - } -#endif - else return \"movd %1,%0\"; -}") - -(define_insn "" - [(set (match_operand:TI 0 "memory_operand" "=m") - (match_operand:TI 1 "memory_operand" "m"))] - "" - "movmd %1,%0,4") - -(define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=g<,*f,g") - (match_operand:DI 1 "general_operand" "gF,g,*f"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) - return \"movl %1,%0\"; - if (REG_P (operands[1])) - { - rtx xoperands[2]; - xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - output_asm_insn (\"movd %1,tos\", xoperands); - output_asm_insn (\"movd %1,tos\", operands); - return \"movl tos,%0\"; - } - return \"movl %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - { - output_asm_insn (\"movl %1,tos\;movd tos,%0\", operands); - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"movd tos,%0\"; - } - else - return \"movl %1,%0\"; - } - return output_move_double (operands); -}") - -;; This special case must precede movsi. -(define_insn "" - [(set (reg:SI 17) - (match_operand:SI 0 "general_operand" "rmn"))] - "" - "lprd sp,%0") - -(define_insn "movsi" - [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g,x") - (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))] - "" - "* -{ - if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movd %1,tos\;movf tos,%0\"; - else - return \"movf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - if (GET_CODE (operands[0]) == REG - && REGNO (operands[0]) == FRAME_POINTER_REGNUM) - return \"lprd fp,%1\"; - if (GET_CODE (operands[1]) == CONST_DOUBLE) - operands[1] - = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); - if (GET_CODE (operands[1]) == CONST_INT) - { - int i = INTVAL (operands[1]); - if (! TARGET_32532) - { - if (i <= 7 && i >= -8) - return \"movqd %1,%0\"; - if (i < 0x4000 && i >= -0x4000) -#if defined (GNX_V3) || defined (UTEK_ASM) - return \"addr %c1,%0\"; -#else - return \"addr @%c1,%0\"; -#endif - } - else - return output_move_dconst(i, \"%$%1,%0\"); - } - else if (GET_CODE (operands[1]) == REG) - { - if (REGNO (operands[1]) < 16) - return \"movd %1,%0\"; - else if (REGNO (operands[1]) == FRAME_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return \"sprd fp,%0\"; - else - return \"addr 0(fp),%0\" ; - } - else if (REGNO (operands[1]) == STACK_POINTER_REGNUM) - { - if (GET_CODE(operands[0]) == REG) - return \"sprd sp,%0\"; - else - return \"addr 0(sp),%0\" ; - } - else abort (); - } - else if (GET_CODE (operands[1]) == MEM) - return \"movd %1,%0\"; - - /* Check if this effective address can be - calculated faster by pulling it apart. */ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return \"addr %a1,%0\"; -}") - -(define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=g<,*f,g") - (match_operand:HI 1 "general_operand" "g,g,*f"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - short i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, i); - return \"movqw %1,%0\"; - } - return \"movw %1,%0\"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movwf %1,tos\;movf tos,%0\"; - else - return \"movwf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - else - return \"movw %1,%0\"; -}") - -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "+r")) - (match_operand:HI 1 "general_operand" "g"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) <= 7 && INTVAL(operands[1]) >= -8) - return \"movqw %1,%0\"; - return \"movw %1,%0\"; -}") - -(define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=g<,*f,g") - (match_operand:QI 1 "general_operand" "g,g,*f"))] - "" - "* -{ if (GET_CODE (operands[1]) == CONST_INT) - { - char char_val = (char)INTVAL (operands[1]); - if (char_val <= 7 && char_val >= -8) - { - if (INTVAL (operands[1]) > 7) - operands[1] = - gen_rtx (CONST_INT, VOIDmode, char_val); - return \"movqb %1,%0\"; - } - return \"movb %1,%0\"; - } - else if (FP_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) - return \"movbf %1,tos\;movf tos,%0\"; - else - return \"movbf %1,%0\"; - } - else if (FP_REG_P (operands[1])) - { - if (REG_P (operands[0])) - return \"movf %1,tos\;movd tos,%0\"; - return \"movf %1,%0\"; - } - else - return \"movb %1,%0\"; -}") - -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+r")) - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL(operands[1]) < 8 && INTVAL(operands[1]) > -9) - return \"movqb %1,%0\"; - return \"movb %1,%0\"; -}") - -;; This is here to accept 4 arguments and pass the first 3 along -;; to the movstrsi1 pattern that really does the work. -(define_expand "movstrsi" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:SI 2 "general_operand" "rmn")) - (match_operand 3 "" "")] - "" - " - emit_insn (gen_movstrsi1 (operands[0], operands[1], operands[2])); - DONE; -") - -;; The definition of this insn does not really explain what it does, -;; but it should suffice -;; that anything generated as this insn will be recognized as one -;; and that it won't successfully combine with anything. -(define_insn "movstrsi1" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:SI 2 "general_operand" "rmn")) - (clobber (reg:SI 0)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2))] - "" - "* -{ - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) - abort (); - operands[0] = XEXP (operands[0], 0); - operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[0]) == MEM) - if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"movd %0,r2\;movd %1,r1\", operands); - else - output_asm_insn (\"movd %0,r2\;addr %a1,r1\", operands); - else if (GET_CODE (operands[1]) == MEM) - output_asm_insn (\"addr %a0,r2\;movd %1,r1\", operands); - else - output_asm_insn (\"addr %a0,r2\;addr %a1,r1\", operands); - -#ifdef UTEK_ASM - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return \"movqd %2,r0\;movsd $0\"; - else - return \"movd %2,r0\;movsd $0\"; - } - else - { - return \"movd %2,r0\;movsb $0\"; - } -#else - if (GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) & 0x3) == 0) - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); - if ((unsigned) INTVAL (operands[2]) <= 7) - return \"movqd %2,r0\;movsd\"; - else - return \"movd %2,r0\;movsd\"; - } - else - { - return \"movd %2,r0\;movsb\"; - } -#endif -}") - -;; Extension and truncation insns. -;; Those for integer source operand -;; are ordered widest source type first. - -(define_insn "truncsiqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "rmn")))] - "" - "movb %1,%0") - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "rmn")))] - "" - "movw %1,%0") - -(define_insn "trunchiqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movb %1,%0") - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movxwd %1,%0") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movxbw %1,%0") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movxbd %1,%0") - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "movfl %1,%0") - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float_truncate:SF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "movlf %1,%0") - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] - "" - "movzwd %1,%0") - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movzbw %1,%0") - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "movzbd %1,%0") - -;; Fix-to-float conversion insns. -;; Note that the ones that start with SImode come first. -;; That is so that an operand that is a CONST_INT -;; (and therefore lacks a specific machine mode). -;; will be recognized as SImode (which is always valid) -;; rather than as QImode or HImode. - -;; Rumor has it that the National part does not correctly convert -;; constant ints to floats. This conversion is therefore disabled. -;; A register must be used to perform the conversion. - -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:SI 1 "general_operand" "rm")))] - "TARGET_32081" - "movdf %1,%0") - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float:DF (match_operand:SI 1 "general_operand" "rm")))] - "TARGET_32081" - "movdl %1,%0") - -(define_insn "floathisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:HI 1 "general_operand" "rm")))] - "TARGET_32081" - "movwf %1,%0") - -(define_insn "floathidf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (float:DF (match_operand:HI 1 "general_operand" "rm")))] - "TARGET_32081" - "movwl %1,%0") - -(define_insn "floatqisf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (float:SF (match_operand:QI 1 "general_operand" "rm")))] - "TARGET_32081" - "movbf %1,%0") - -; Some assemblers warn that this insn doesn't work. -; Maybe they know something we don't. -;(define_insn "floatqidf2" -; [(set (match_operand:DF 0 "general_operand" "=fm<") -; (float:DF (match_operand:QI 1 "general_operand" "rm")))] -; "TARGET_32081" -; "movbl %1,%0") - -;; Float-to-fix conversion insns. -;; The sequent compiler always generates "trunc" insns. - -(define_insn "fixsfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fixsfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fixsfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fixdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fixdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fixdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncld %1,%0") - -;; Unsigned - -(define_insn "fixunssfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (unsigned_fix:QI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fixunssfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (unsigned_fix:HI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fixunssfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (unsigned_fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fixunsdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (unsigned_fix:QI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fixunsdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (unsigned_fix:HI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fixunsdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (unsigned_fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))] - "TARGET_32081" - "truncld %1,%0") - -;;; These are not yet used by GCC -(define_insn "fix_truncsfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfb %1,%0") - -(define_insn "fix_truncsfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfw %1,%0") - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (match_operand:SF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncfd %1,%0") - -(define_insn "fix_truncdfqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (fix:QI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "trunclb %1,%0") - -(define_insn "fix_truncdfhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (fix:HI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "trunclw %1,%0") - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (fix:SI (match_operand:DF 1 "general_operand" "fm")))] - "TARGET_32081" - "truncld %1,%0") - -;;- All kinds of add instructions. - -(define_insn "adddf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (plus:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "addl %2,%0") - - -(define_insn "addsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (plus:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "addf %2,%0") - -(define_insn "" - [(set (reg:SI 17) - (plus:SI (reg:SI 17) - (match_operand:SI 0 "immediate_operand" "i")))] - "GET_CODE (operands[0]) == CONST_INT" - "* -{ -#ifndef SEQUENT_ADJUST_STACK - if (TARGET_32532) - if (INTVAL (operands[0]) == 8) - return \"cmpd tos,tos\"; - if (TARGET_32532 || TARGET_32332) - if (INTVAL (operands[0]) == 4) - return \"cmpqd %$0,tos\"; -#endif - if (! TARGET_32532) - { - if (INTVAL (operands[0]) < 64 && INTVAL (operands[0]) > -64) - return \"adjspb %$%n0\"; - else if (INTVAL (operands[0]) < 8192 && INTVAL (operands[0]) >= -8192) - return \"adjspw %$%n0\"; - } - return \"adjspd %$%n0\"; -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (plus:SI (reg:SI 16) - (match_operand:SI 1 "immediate_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT" - "addr %c1(fp),%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (plus:SI (reg:SI 17) - (match_operand:SI 1 "immediate_operand" "i")))] - "GET_CODE (operands[1]) == CONST_INT" - "addr %c1(sp),%0") - -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=g,=g&<") - (plus:SI (match_operand:SI 1 "general_operand" "%0,r") - (match_operand:SI 2 "general_operand" "rmn,n")))] - "" - "* -{ - if (which_alternative == 1) - { - int i = INTVAL (operands[2]); - if (NS32K_DISPLACEMENT_P (i)) - return \"addr %c2(%1),%0\"; - else - return \"movd %1,%0\;addd %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 7 && i >= -8) - return \"addqd %2,%0\"; - else if (GET_CODE (operands[0]) == REG - && i < 0x4000 && i >= -0x4000 && ! TARGET_32532) - return \"addr %c2(%0),%0\"; - } - return \"addd %2,%0\"; -}") - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (plus:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return \"addqw %2,%0\"; - } - return \"addw %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "=r")) - (plus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqw %2,%0\"; - return \"addw %2,%0\"; -}") - -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (plus:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if (i <= 7 && i >= -8) - return \"addqb %2,%0\"; - } - return \"addb %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "=r")) - (plus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqb %2,%0\"; - return \"addb %2,%0\"; -}") - -;;- All kinds of subtract instructions. - -(define_insn "subdf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (minus:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "subl %2,%0") - -(define_insn "subsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (minus:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "subf %2,%0") - -(define_insn "" - [(set (reg:SI 17) - (minus:SI (reg:SI 17) - (match_operand:SI 0 "immediate_operand" "i")))] - "GET_CODE (operands[0]) == CONST_INT" - "* -{ - if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 - && INTVAL(operands[0]) > -64 && ! TARGET_32532) - return \"adjspb %$%0\"; - return \"adjspd %$%0\"; -}") - -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqd %$%n2,%0\"; - } - return \"subd %2,%0\"; -}") - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqw %$%n2,%0\"; - } - return \"subw %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:HI 0 "general_operand" "=r")) - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqw %$%n2,%0\"; - return \"subw %2,%0\"; -}") - -(define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (minus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if (i <= 8 && i >= -7) - return \"addqb %$%n2,%0\"; - } - return \"subb %2,%0\"; -}") - -(define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "=r")) - (minus:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqb %$%n2,%0\"; - return \"subb %2,%0\"; -}") - -;;- Multiply instructions. - -(define_insn "muldf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (mult:DF (match_operand:DF 1 "general_operand" "%0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "mull %2,%0") - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (mult:SF (match_operand:SF 1 "general_operand" "%0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "mulf %2,%0") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "muld %2,%0") - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "mulw %2,%0") - -(define_insn "mulqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (mult:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "mulb %2,%0") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "general_operand" "=g") - (mult:DI (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "0")) - (zero_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "rmn"))))] - "" - "meid %2,%0") - -;;- Divide instructions. - -(define_insn "divdf3" - [(set (match_operand:DF 0 "general_operand" "=fm") - (div:DF (match_operand:DF 1 "general_operand" "0") - (match_operand:DF 2 "general_operand" "fmF")))] - "TARGET_32081" - "divl %2,%0") - -(define_insn "divsf3" - [(set (match_operand:SF 0 "general_operand" "=fm") - (div:SF (match_operand:SF 1 "general_operand" "0") - (match_operand:SF 2 "general_operand" "fmF")))] - "TARGET_32081" - "divf %2,%0") - -(define_insn "divsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (div:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "quod %2,%0") - -(define_insn "divhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (div:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "quow %2,%0") - -(define_insn "divqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (div:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "quob %2,%0") - -(define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return \"deid %2,%0\;movd %1,%0\"; -}") - -(define_insn "udivhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (udiv:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]) + 1); - return \"deiw %2,%0\;movw %1,%0\"; -}") - -(define_insn "udivqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (udiv:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ - operands[1] = gen_rtx (REG, QImode, REGNO (operands[0]) + 1); - return \"deib %2,%0\;movb %1,%0\"; -}") - -;; Remainder instructions. - -(define_insn "modsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (mod:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "remd %2,%0") - -(define_insn "modhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (mod:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "remw %2,%0") - -(define_insn "modqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (mod:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "remb %2,%0") - -(define_insn "umodsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (umod:SI (subreg:SI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "deid %2,%0") - -(define_insn "umodhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (umod:HI (subreg:HI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:HI 2 "general_operand" "g")))] - "" - "deiw %2,%0") - -(define_insn "umodqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (umod:QI (subreg:QI (match_operand:DI 1 "reg_or_mem_operand" "0") 0) - (match_operand:QI 2 "general_operand" "g")))] - "" - "deib %2,%0") - -; This isn't be usable in its current form. -;(define_insn "udivmoddisi4" -; [(set (subreg:SI (match_operand:DI 0 "general_operand" "=r") 1) -; (udiv:SI (match_operand:DI 1 "general_operand" "0") -; (match_operand:SI 2 "general_operand" "rmn"))) -; (set (subreg:SI (match_dup 0) 0) -; (umod:SI (match_dup 1) (match_dup 2)))] -; "" -; "deid %2,%0") - -;;- Logical Instructions: AND - -(define_insn "andsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (and:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if ((INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return \"movqb %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return \"andb %2,%0\"; - } - } - if ((INTVAL (operands[2]) | 0xffff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffff0000) - return \"movqw %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - return \"andw %2,%0\"; - } - } - } - return \"andd %2,%0\"; -}") - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (and:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xff) == 0xffffffff) - { - if (INTVAL (operands[2]) == 0xffffff00) - return \"movqb %$0,%0\"; - else - { - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); - return \"andb %2,%0\"; - } - } - return \"andw %2,%0\"; -}") - -(define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (and:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "andb %2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (and:SI (not:SI (match_operand:SI 1 "general_operand" "rmn")) - (match_operand:SI 2 "general_operand" "0")))] - "" - "bicd %1,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (and:HI (not:HI (match_operand:HI 1 "general_operand" "g")) - (match_operand:HI 2 "general_operand" "0")))] - "" - "bicw %1,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "g")) - (match_operand:QI 2 "general_operand" "0")))] - "" - "bicb %1,%0") - -;;- Bit set instructions. - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (ior:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return \"orb %2,%0\"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return \"orw %2,%0\"; - } - return \"ord %2,%0\"; -}") - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ior:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return \"orb %2,%0\"; - return \"orw %2,%0\"; -}") - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ior:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "orb %2,%0") - -;;- xor instructions. - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (xor:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) { - if ((INTVAL (operands[2]) & 0xffffff00) == 0) - return \"xorb %2,%0\"; - if ((INTVAL (operands[2]) & 0xffff0000) == 0) - return \"xorw %2,%0\"; - } - return \"xord %2,%0\"; -}") - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "g")))] - "" - "* -{ - if (GET_CODE(operands[2]) == CONST_INT && - (INTVAL(operands[2]) & 0xffffff00) == 0) - return \"xorb %2,%0\"; - return \"xorw %2,%0\"; -}") - -(define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (xor:QI (match_operand:QI 1 "general_operand" "%0") - (match_operand:QI 2 "general_operand" "g")))] - "" - "xorb %2,%0") - -(define_insn "negdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (neg:DF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "negl %1,%0") - -(define_insn "negsf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (neg:SF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "negf %1,%0") - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (neg:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "negd %1,%0") - -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (neg:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "negw %1,%0") - -(define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (neg:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "negb %1,%0") - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (not:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "comd %1,%0") - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (not:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "comw %1,%0") - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (not:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "comb %1,%0") - -;; arithmetic left and right shift operations -;; on the 32532 we will always use lshd for arithmetic left shifts, -;; because it is three times faster. Broken programs which -;; use negative shift counts are probably broken differently -;; than elsewhere. - -;; alternative 0 never matches on the 32532 -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=g,g") - (ashift:SI (match_operand:SI 1 "general_operand" "r,0") - (match_operand:SI 2 "general_operand" "I,rmn")))] - "" - "* -{ if (TARGET_32532) - return \"lshd %2,%0\"; - else - return output_shift_insn (operands); -}") - -(define_insn "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return \"addw %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return \"addw %0,%0\;addw %0,%0\"; - } - if (TARGET_32532) - return \"lshw %2,%0\"; - else - return \"ashw %2,%0\"; -}") - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) == 1) - return \"addb %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) - return \"addb %0,%0\;addb %0,%0\"; - } - if (TARGET_32532) - return \"lshb %2,%0\"; - else - return \"ashb %2,%0\"; -}") - -;; Arithmetic right shift on the 32k works by negating the shift count. -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashd %2,%0") - -(define_expand "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashw %2,%0") - -(define_expand "ashrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "ashb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "ashb %2,%0") - -;; logical shift instructions - -(define_insn "lshlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshift:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshd %2,%0") - -(define_insn "lshlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshw %2,%0") - -(define_insn "lshlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshb %2,%0") - -;; Logical right shift on the 32k works by negating the shift count. -(define_expand "lshrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshd %2,%0") - -(define_expand "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshw %2,%0") - -(define_expand "lshrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "lshb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "lshb %2,%0") - -;; Rotate instructions - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotate:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotd %2,%0") - -(define_insn "rotlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotate:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotw %2,%0") - -(define_insn "rotlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotate:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "rotb %2,%0") - -;; Right rotate on the 32k works by negating the shift count. -(define_expand "rotrsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotd %$%n2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotd %2,%0") - -(define_expand "rotrhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotw %$%n2,%0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotw %2,%0") - -(define_expand "rotrqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "general_operand" "g")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] - "" - "rotb %$%n2,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") - (neg:SI (match_operand:SI 2 "general_operand" "r"))))] - "" - "rotb %2,%0") - -;;- load or push effective address -;; These come after the move, add, and multiply patterns -;; because we don't want pushl $1 turned into pushad 1. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (match_operand:QI 1 "address_operand" "p"))] - "" - "* -{ - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == MULT - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && (INTVAL (XEXP (operands[1], 1)) == 2 - || INTVAL (XEXP (operands[1], 1)) == 4)) - { - rtx xoperands[3]; - xoperands[0] = operands[0]; - xoperands[1] = XEXP (operands[1], 0); - xoperands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (XEXP (operands[1], 1)) >> 1); - return output_shift_insn (xoperands); - } - return \"addr %a1,%0\"; -}") - -;;; Index insns. These are about the same speed as multiply-add counterparts. -;;; but slower then using power-of-2 shifts if we can use them -; -;(define_insn "" -; [(set (match_operand:SI 0 "register_operand" "=r") -; (plus:SI (match_operand:SI 1 "general_operand" "rmn") -; (mult:SI (match_operand:SI 2 "register_operand" "0") -; (plus:SI (match_operand:SI 3 "general_operand" "rmn") (const_int 1)))))] -; "GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) > 8" -; "indexd %0,%3,%1") -; -;(define_insn "" -; [(set (match_operand:SI 0 "register_operand" "=r") -; (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "0") -; (plus:SI (match_operand:SI 2 "general_operand" "rmn") (const_int 1))) -; (match_operand:SI 3 "general_operand" "rmn")))] -; "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 8" -; "indexd %0,%2,%3") - -;; Set, Clear, and Invert bit - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g") - (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (const_int 1))] - "" - "sbitd %1,%0") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+g") - (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (const_int 0))] - "" - "cbitd %1,%0") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "+g") - (xor:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "general_operand" "rmn")) - (match_dup 0)))] - "" - "ibitd %1,%0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g") - (xor:QI (subreg:QI - (ashift:SI (const_int 1) - (match_operand:QI 1 "general_operand" "rmn")) 0) - (match_dup 0)))] - "" - "ibitb %1,%0") - -;; Recognize jbs and jbc instructions. - -(define_insn "" - [(set (cc0) - (zero_extract (match_operand:SI 0 "general_operand" "rm") - (const_int 1) - (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ cc_status.flags = CC_Z_IN_F; - return \"tbitd %1,%0\"; -}") - -;; extract(base, width, offset) -;; Signed bitfield extraction is not supported in hardware on the -;; NS 32032. It is therefore better to let GCC figure out a -;; good strategy for generating the proper instruction sequence -;; and represent it as rtl. - -;; Optimize the case of extracting a byte or word from a register. -;; Otherwise we must load a register with the offset of the -;; chunk we want, and perform an extract insn (each of which -;; is very expensive). Since we use the stack to do our bit-twiddling -;; we cannot use it for a destination. Perhaps things are fast -;; enough on the 32532 that such hacks are not needed. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=ro") - (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && (INTVAL (operands[3]) == 8 || INTVAL (operands[3]) == 16 || INTVAL (operands[3]) == 24)" - "* -{ - output_asm_insn (\"movd %1,tos\", operands); - if (INTVAL (operands[2]) == 16) - { - if (INTVAL (operands[3]) == 8) - output_asm_insn (\"movzwd 1(sp),%0\", operands); - else - output_asm_insn (\"movzwd 2(sp),%0\", operands); - } - else - { - if (INTVAL (operands[3]) == 8) - output_asm_insn (\"movzbd 1(sp),%0\", operands); - else if (INTVAL (operands[3]) == 16) - output_asm_insn (\"movzbd 2(sp),%0\", operands); - else - output_asm_insn (\"movzbd 3(sp),%0\", operands); - } - if (TARGET_32532 || TARGET_32332) - return \"cmpqd %$0,tos\"; - else - return \"adjspb %$-4\"; -}") - -;; The extsd/extd isntructions have the problem that they always access -;; 32 bits even if the bitfield is smaller. For example the instruction -;; extsd 7(r1),r0,2,5 -;; would read not only at address 7(r1) but also at 8(r1) to 10(r1). -;; If these addresses are in a different (unmapped) page a memory fault -;; is the result. -;; -;; Timing considerations: -;; movd 0(r1),r0 3 bytes -;; lshd -26,r0 4 -;; andd 0x1f,r0 5 -;; takes about 13 cycles on the 532 while -;; extsd 7(r1),r0,2,5 5 bytes -;; takes about 21 cycles. -;; -;; So lets forget about extsd/extd on the 532. - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extract:SI (match_operand:SI 1 "register_operand" "g") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "general_operand" "rK")))] - "! TARGET_32532" - "* -{ if (GET_CODE (operands[3]) == CONST_INT) - return \"extsd %1,%0,%3,%2\"; - else return \"extd %3,%1,%0,%2\"; -}") - -(define_insn "extzv" - [(set (match_operand:SI 0 "general_operand" "=g<") - (zero_extract:SI (match_operand:QI 1 "general_operand" "g") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "general_operand" "rK")))] - "! TARGET_32532" - "* -{ if (GET_CODE (operands[3]) == CONST_INT) - return \"extsd %1,%0,%3,%2\"; - else return \"extd %3,%1,%0,%2\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+o") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rn")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 8) - { - operands[0] = adj_offsettable_operand (operands[0], - INTVAL (operands[2]) / 8); - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 8); - } - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - } - return \"insd %2,%3,%0,%1\"; -}") - -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rK")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - return \"insd %2,%3,%0,%1\"; -}") - -(define_insn "insv" - [(set (zero_extract:SI (match_operand:QI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "general_operand" "rK")) - (match_operand:SI 3 "general_operand" "rm"))] - "" - "* -{ if (GET_CODE (operands[2]) == CONST_INT) - if (INTVAL (operands[1]) <= 8) - return \"inssb %3,%0,%2,%1\"; - else if (INTVAL (operands[1]) <= 16) - return \"inssw %3,%0,%2,%1\"; - else - return \"inssd %3,%0,%2,%1\"; - return \"insd %2,%3,%0,%1\"; -}") - - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "br %l0") - -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfc %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfs %l0\"; - else return \"beq %l0\"; -}") - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfs %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfc %l0\"; - else return \"bne %l0\"; -}") - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bgt %l0") - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bhi %l0") - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blt %l0") - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "blo %l0") - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bge %l0") - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bhs %l0") - -(define_insn "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "ble %l0") - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "bls %l0") - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfs %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfc %l0\"; - else return \"bne %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"bfc %l0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"bfs %l0\"; - else return \"beq %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "ble %l0") - -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bls %l0") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bge %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bhs %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "blt %l0") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "blo %l0") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bgt %l0") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "bhi %l0") - -;; Subtract-and-jump and Add-and-jump insns. -;; These can actually be used for adding numbers in the range -8 to 7 - -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:SI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i")) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (match_dup 0) - (minus:SI (match_dup 0) - (match_dup 1)))] - "INTVAL (operands[1]) > -8 && INTVAL (operands[1]) <= 8" - "acbd %$%n1,%0,%l2") - -(define_insn "" - [(set (pc) - (if_then_else - (ne (match_operand:SI 0 "general_operand" "+g") - (match_operand:SI 1 "const_int_operand" "i")) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (match_operand:SI 3 "const_int_operand" "i")))] - "INTVAL (operands[1]) == - INTVAL (operands[3]) - && INTVAL (operands[3]) >= -8 && INTVAL (operands[3]) < 8" - "acbd %3,%0,%l2") - -(define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "m") - (match_operand:QI 1 "general_operand" "g"))] - "" - "* -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[0]) == MEM) - { - rtx temp = XEXP (operands[0], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return \"bsr %?%0\"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[0] = temp; - return \"bsr %0\"; -#else -#ifdef GNX_V3 - return \"bsr %0\"; -#else - return \"bsr %?%a0\"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[0], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return \"jsr %0\"; -#else - return \"jsr %a0\"; -#endif - } -#endif /* not JSR_ALWAYS */ - return \"jsr %0\"; -}") - -(define_insn "call_value" - [(set (match_operand 0 "" "=rf") - (call (match_operand:QI 1 "memory_operand" "m") - (match_operand:QI 2 "general_operand" "g")))] - "" - "* -{ -#ifndef JSR_ALWAYS - if (GET_CODE (operands[1]) == MEM) - { - rtx temp = XEXP (operands[1], 0); - if (CONSTANT_ADDRESS_P (temp)) - { -#ifdef ENCORE_ASM - return \"bsr %?%1\"; -#else -#ifdef CALL_MEMREF_IMPLICIT - operands[1] = temp; - return \"bsr %1\"; -#else -#ifdef GNX_V3 - return \"bsr %1\"; -#else - return \"bsr %?%a1\"; -#endif -#endif -#endif - } - if (GET_CODE (XEXP (operands[1], 0)) == REG) -#if defined (GNX_V3) || defined (CALL_MEMREF_IMPLICIT) - return \"jsr %1\"; -#else - return \"jsr %a1\"; -#endif - } -#endif /* not JSR_ALWAYS */ - return \"jsr %1\"; -}") - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "") - -(define_insn "return" - [(return)] - "0" - "ret 0") - -(define_insn "abssf2" - [(set (match_operand:SF 0 "general_operand" "=fm<") - (abs:SF (match_operand:SF 1 "general_operand" "fmF")))] - "TARGET_32081" - "absf %1,%0") - -(define_insn "absdf2" - [(set (match_operand:DF 0 "general_operand" "=fm<") - (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] - "TARGET_32081" - "absl %1,%0") - -(define_insn "abssi2" - [(set (match_operand:SI 0 "general_operand" "=g<") - (abs:SI (match_operand:SI 1 "general_operand" "rmn")))] - "" - "absd %1,%0") - -(define_insn "abshi2" - [(set (match_operand:HI 0 "general_operand" "=g<") - (abs:HI (match_operand:HI 1 "general_operand" "g")))] - "" - "absw %1,%0") - -(define_insn "absqi2" - [(set (match_operand:QI 0 "general_operand" "=g<") - (abs:QI (match_operand:QI 1 "general_operand" "g")))] - "" - "absb %1,%0") - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "r"))] - "" - "jump %0") - -(define_insn "tablejump" - [(set (pc) - (plus:SI (pc) (match_operand:SI 0 "general_operand" "g"))) - (use (label_ref (match_operand 1 "" "")))] - "" - "* -{ - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", - CODE_LABEL_NUMBER (operands[1])); - return \"cased %0\"; -}") - -;; Scondi instructions -(define_insn "seq" - [(set (match_operand:SI 0 "general_operand" "=g<") - (eq:SI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcd %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsd %0\"; - else return \"seqd %0\"; -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (eq:HI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcw %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsw %0\"; - else return \"seqw %0\"; -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (eq:QI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfcb %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfsb %0\"; - else return \"seqb %0\"; -}") - -(define_insn "sne" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ne:SI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsd %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcd %0\"; - else return \"sned %0\"; -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ne:HI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsw %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcw %0\"; - else return \"snew %0\"; -}") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ne:QI (cc0) (const_int 0)))] - "" - "* -{ if (cc_prev_status.flags & CC_Z_IN_F) - return \"sfsb %0\"; - else if (cc_prev_status.flags & CC_Z_IN_NOT_F) - return \"sfcb %0\"; - else return \"sneb %0\"; -}") - -(define_insn "sgt" - [(set (match_operand:SI 0 "general_operand" "=g<") - (gt:SI (cc0) (const_int 0)))] - "" - "sgtd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (gt:HI (cc0) (const_int 0)))] - "" - "sgtw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (gt:QI (cc0) (const_int 0)))] - "" - "sgtb %0") - -(define_insn "sgtu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (gtu:SI (cc0) (const_int 0)))] - "" - "shid %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (gtu:HI (cc0) (const_int 0)))] - "" - "shiw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (gtu:QI (cc0) (const_int 0)))] - "" - "shib %0") - -(define_insn "slt" - [(set (match_operand:SI 0 "general_operand" "=g<") - (lt:SI (cc0) (const_int 0)))] - "" - "sltd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (lt:HI (cc0) (const_int 0)))] - "" - "sltw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (lt:QI (cc0) (const_int 0)))] - "" - "sltb %0") - -(define_insn "sltu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ltu:SI (cc0) (const_int 0)))] - "" - "slod %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ltu:HI (cc0) (const_int 0)))] - "" - "slow %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ltu:QI (cc0) (const_int 0)))] - "" - "slob %0") - -(define_insn "sge" - [(set (match_operand:SI 0 "general_operand" "=g<") - (ge:SI (cc0) (const_int 0)))] - "" - "sged %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (ge:HI (cc0) (const_int 0)))] - "" - "sgew %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (ge:QI (cc0) (const_int 0)))] - "" - "sgeb %0") - -(define_insn "sgeu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (geu:SI (cc0) (const_int 0)))] - "" - "shsd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (geu:HI (cc0) (const_int 0)))] - "" - "shsw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (geu:QI (cc0) (const_int 0)))] - "" - "shsb %0") - -(define_insn "sle" - [(set (match_operand:SI 0 "general_operand" "=g<") - (le:SI (cc0) (const_int 0)))] - "" - "sled %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (le:HI (cc0) (const_int 0)))] - "" - "slew %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (le:QI (cc0) (const_int 0)))] - "" - "sleb %0") - -(define_insn "sleu" - [(set (match_operand:SI 0 "general_operand" "=g<") - (leu:SI (cc0) (const_int 0)))] - "" - "slsd %0") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=g<") - (leu:HI (cc0) (const_int 0)))] - "" - "slsw %0") - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=g<") - (leu:QI (cc0) (const_int 0)))] - "" - "slsb %0") - -;; ffs instructions - -(define_insn "ffsqi2" - [(set (match_operand:QI 0 "general_operand" "=g") - (ffs:QI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqb 0,%0; ffsd %1,%0; bfs 1f; addqb 1,%0; 1:\"; -}") - -(define_insn "ffshi2" - [(set (match_operand:HI 0 "general_operand" "=g") - (ffs:HI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqw 0,%0; ffsd %1,%0; bfs 1f; addqw 1,%0; 1:\"; -}") - -(define_insn "ffssi2" - [(set (match_operand:SI 0 "general_operand" "=g") - (ffs:SI (match_operand:SI 1 "general_operand" "g")))] - "" - "* -{ - return \"movqd 0,%0; ffsd %1,%0; bfs 1f; addqd 1,%0; 1:\"; -}") - -;; Speed up stack adjust followed by a HI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (match_operand:HI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzwd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) - (set (match_operand:HI 0 "push_operand" "=m") - (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movxbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a QI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -3))) - (set (match_operand:QI 0 "push_operand" "=m") - (match_operand:QI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), - operands); - else - output_asm_insn (\"movzbd %1,tos\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by a SI fixedpoint push. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 4))) - (set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,0(sp)\"), - operands); - else - output_asm_insn (\"movd %1,0(sp)\", operands); - return \"\"; -}") - -;; Speed up stack adjust followed by two fullword fixedpoint pushes. - -(define_peephole - [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 8))) - (set (match_operand:SI 0 "push_operand" "=m") - (match_operand:SI 1 "general_operand" "g")) - (set (match_operand:SI 2 "push_operand" "=m") - (match_operand:SI 3 "general_operand" "g"))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1]) - && ! reg_mentioned_p (stack_pointer_rtx, operands[3])" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,4(sp)\"), - operands); - else - output_asm_insn (\"movd %1,4(sp)\", operands); - - if (GET_CODE (operands[3]) == CONST_INT) - output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%$%3,0(sp)\"), - operands); - else - output_asm_insn (\"movd %3,0(sp)\", operands); - return \"\"; -}") diff --git a/gnu/usr.bin/gcc2/arch/ns32k/ns32k.h b/gnu/usr.bin/gcc2/arch/ns32k/ns32k.h deleted file mode 100644 index bc98b14866f..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/ns32k.h +++ /dev/null @@ -1,1469 +0,0 @@ -/* Definitions of target machine for GNU compiler. NS32000 version. - Copyright (C) 1988 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@mcc.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* Note that some other tm.h files include this one and then override - many of the definitions that relate to assembler syntax. */ - -extern enum reg_class secondary_reload_class(); - -/* Names to predefine in the preprocessor for this target machine. */ - -#define CPP_PREDEFINES "-Dns32000 -Dunix -D__NetBSD__ -D__ns32k__" - -/* Print subsidiary information on the compiler version in use. */ -#define TARGET_VERSION fprintf (stderr, " (32000, GAS syntax)"); - - -/* ABSOLUTE PREFIX, IMMEDIATE_PREFIX and EXTERNAL_PREFIX can be defined - to cover most NS32k addressing syntax variations. This way we don't - need to redefine long macros in all the tm.h files for just slight - variations in assembler syntax. */ - -#ifndef ABSOLUTE_PREFIX -#define ABSOLUTE_PREFIX '@' -#endif - -#if defined(IMMEDIATE_PREFIX) && IMMEDIATE_PREFIX -#define PUT_IMMEDIATE_PREFIX(FILE) putc(IMMEDIATE_PREFIX, FILE) -#else -#define PUT_IMMEDIATE_PREFIX(FILE) -#endif -#if defined(ABSOLUTE_PREFIX) && ABSOLUTE_PREFIX -#define PUT_ABSOLUTE_PREFIX(FILE) putc(ABSOLUTE_PREFIX, FILE) -#else -#define PUT_ABSOLUTE_PREFIX(FILE) -#endif -#if defined(EXTERNAL_PREFIX) && EXTERNAL_PREFIX -#define PUT_EXTERNAL_PREFIX(FILE) putc(EXTERNAL_PREFIX, FILE) -#else -#define PUT_EXTERNAL_PREFIX(FILE) -#endif - -/* Run-time compilation parameters selecting different hardware subsets. */ - -extern int target_flags; - -/* Macros used in the machine description to test the flags. */ - -/* Compile 32081 insns for floating point (not library calls). */ -#define TARGET_32081 (target_flags & 1) - -/* Compile using rtd insn calling sequence. - This will not work unless you use prototypes at least - for all functions that can take varying numbers of args. */ -#define TARGET_RTD (target_flags & 2) - -/* Compile passing first two args in regs 0 and 1. */ -#define TARGET_REGPARM (target_flags & 4) - -/* Options to select type of CPU, for better optimization. - The output is correct for any kind of 32000 regardless of these options. */ -#define TARGET_32532 (target_flags & 8) -#define TARGET_32332 (target_flags & 16) - -/* Ok to use the static base register (and presume it's 0) */ -#define TARGET_SB ((target_flags & 32) == 0) - -/* Macro to define tables used to set the flags. - This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } - where VALUE is the bits to set or minus the bits to clear. - An empty string NAME is used to identify the default VALUE. */ - -#define TARGET_SWITCHES \ - { { "32081", 1}, \ - { "soft-float", -1}, \ - { "rtd", 2}, \ - { "nortd", -2}, \ - { "regparm", 4}, \ - { "noregparm", -4}, \ - { "32532", 24}, \ - { "32332", -8}, \ - { "32332", 16}, \ - { "32032", -24}, \ - { "sb", -32}, \ - { "nosb", 32}, \ - { "", TARGET_DEFAULT}} -/* TARGET_DEFAULT is defined in encore.h, pc532.h, etc. */ - -/* When we are generating PIC, the sb is used as a pointer - to the GOT. */ - -#define OVERRIDE_OPTIONS \ -{ \ - if (flag_pic) target_flags |= 32; \ -} - - -/* target machine storage layout */ - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. - This is not true on the ns32k. */ -#define BITS_BIG_ENDIAN 0 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is not true on the ns32k. */ -#define BYTES_BIG_ENDIAN 0 - -/* Define this if most significant word of a multiword number is lowest - numbered. This is not true on the ns32k. */ -#define WORDS_BIG_ENDIAN 0 - -/* Number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 32000, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD 32 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD 4 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE 32 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY 32 - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY 32 - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 16 - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 32 - -/* Every structure's size must be a multiple of this. */ -#define STRUCTURE_SIZE_BOUNDARY 8 - -/* No data type wants to be aligned rounder than this. */ -#define BIGGEST_ALIGNMENT 32 - -/* Set this nonzero if move instructions will actually fail to work - when given unaligned data. National claims that the NS32032 - works without strict alignment, but rumor has it that operands - crossing a page boundary cause unpredictable results. */ -#define STRICT_ALIGNMENT 1 - -/* If bit field type is int, dont let it cross an int, - and give entire struct the alignment of an int. */ -/* Required on the 386 since it doesn't have a full set of bitfield insns. - (There is no signed extv insn.) */ -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. */ -#define FIRST_PSEUDO_REGISTER 18 - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - On the ns32k, these are the FP, SP, (SB and PC are not included here). */ -#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1} - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS {1, 1, 1, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 1, 1} - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - On the ns32k, all registers are 32 bits long. */ -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) hard_regno_mode_ok (REGNO, MODE) - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (((MODE1) == DFmode || (MODE1) == DCmode || (MODE1) == DImode) == \ - ((MODE2) == DFmode || (MODE2) == DCmode || (MODE2) == DImode)) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* NS32000 pc is not overloaded on a register. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 17 - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 16 - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. */ -#define FRAME_POINTER_REQUIRED 0 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 16 - -/* Register in which static-chain is passed to a function. */ -#define STATIC_CHAIN_REGNUM 1 - -/* Register in which address to store a structure value - is passed to a function. */ -#define STRUCT_VALUE_REGNUM 2 - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, GEN_AND_FP_REGS, - FRAME_POINTER_REG, STACK_POINTER_REG, - GEN_AND_MEM_REGS, ALL_REGS, LIM_REG_CLASSES }; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ - {"NO_REGS", "GENERAL_REGS", "FLOAT_REGS", "GEN_AND_FP_REGS", \ - "FRAME_POINTER_REG", "STACK_POINTER_REG", "GEN_AND_MEM_REGS", "ALL_REGS" } - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS {0, 0x00ff, 0xff00, 0xffff, \ - 0x10000, 0x20000, 0x300ff, 0x3ffff } - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) < 8 ? GENERAL_REGS \ - : (REGNO) < 16 ? FLOAT_REGS \ - : (REGNO) == 16 ? FRAME_POINTER_REG \ - : (REGNO) == 17 ? STACK_POINTER_REG \ - : NO_REGS) - -/* The class value for index registers, and the one for base regs. */ - -#define INDEX_REG_CLASS GENERAL_REGS -#define BASE_REG_CLASS GEN_AND_MEM_REGS - -/* Get reg_class from a letter such as appears in the machine description. */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'f' ? FLOAT_REGS \ - : (C) == 'x' ? FRAME_POINTER_REG \ - : (C) == 'y' ? STACK_POINTER_REG \ - : NO_REGS) - -/* The letters I, J, K, L and M in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - On the ns32k, these letters are used as follows: - - I : Matches integers which are valid shift amounts for scaled indexing. - These are 0, 1, 2, 3 for byte, word, double, and quadword. - Used for matching arithmetic shifts only on 32032 & 32332. - J : Matches integers which fit a "quick" operand. - K : Matches integers 0 to 7 (for inss and exts instructions). - */ - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((VALUE) < 8 && (VALUE) + 8 >= 0 ? \ - ((C) == 'I' ? (!TARGET_32532 && 0 <= (VALUE) && (VALUE) <= 3) : \ - (C) == 'J' ? (VALUE) <= 7 : \ - (C) == 'K' ? 0 <= (VALUE) : 0) : 0) - -/* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. */ - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1 - -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. */ - -/* We return GENERAL_REGS instead of GEN_AND_MEM_REGS. - The latter offers no real additional possibilities - and can cause spurious secondary reloading. */ -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((CLASS) == GEN_AND_MEM_REGS ? GENERAL_REGS : (CLASS)) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On the 32000, this is the size of MODE in words */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Stack layout; function entry, exit and calling. */ - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. */ -#define FRAME_GROWS_DOWNWARD - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ -#define STARTING_FRAME_OFFSET 0 - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On the 32000, sp@- in a byte insn really pushes a BYTE. */ -#define PUSH_ROUNDING(BYTES) (BYTES) - -/* Offset of first parameter from the argument pointer register value. */ -#define FIRST_PARM_OFFSET(FNDECL) 8 - -/* Value is the number of byte of arguments automatically - popped when returning from a subroutine call. - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. - - On the 32000, the RET insn may be used to pop them if the number - of args is fixed, but if the number is variable then the caller - must pop them all. RET can't be used for library calls now - because the library is compiled with the Unix compiler. - Use of RET is a selectable option, since it is incompatible with - standard Unix calling sequences. If the option is not selected, - the caller must always pop the args. */ - -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) \ - ((TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE \ - && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ - || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ - == void_type_node))) \ - ? (SIZE) : 0) - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. */ - -/* On the 32000 the return value is in R0, - or perhaps in F0 is there is fp support. */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - (TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_32081 \ - ? gen_rtx (REG, TYPE_MODE (VALTYPE), 8) \ - : gen_rtx (REG, TYPE_MODE (VALTYPE), 0)) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -/* On the 32000 the return value is in R0, - or perhaps F0 is there is fp support. */ - -#define LIBCALL_VALUE(MODE) \ - (((MODE) == DFmode || (MODE) == SFmode) && TARGET_32081 \ - ? gen_rtx (REG, MODE, 8) \ - : gen_rtx (REG, MODE, 0)) - -/* Define this if PCC uses the nonreentrant convention for returning - structure and union values. */ - -#define PCC_STATIC_STRUCT_RETURN - -/* 1 if N is a possible register number for a function value. - On the 32000, R0 and F0 are the only registers thus used. */ - -#define FUNCTION_VALUE_REGNO_P(N) (((N) & ~8) == 0) - -/* 1 if N is a possible register number for function argument passing. - On the 32000, no registers are used in this way. */ - -#define FUNCTION_ARG_REGNO_P(N) 0 - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. - - On the ns32k, this is a single integer, which is a number of bytes - of arguments scanned so far. */ - -#define CUMULATIVE_ARGS int - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. - - On the ns32k, the offset starts at 0. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ - ((CUM) = 0) - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM) += ((MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + 3) & ~3 \ - : (int_size_in_bytes (TYPE) + 3) & ~3)) - -/* Define where to put the arguments to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -/* On the 32000 all args are pushed, except if -mregparm is specified - then the first two words of arguments are passed in r0, r1. - *NOTE* -mregparm does not work. - It exists only to test register calling conventions. */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8) ? gen_rtx (REG, (MODE), (CUM) / 4) : 0) - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8 \ - && 8 < ((CUM) + ((MODE) == BLKmode \ - ? int_size_in_bytes (TYPE) \ - : GET_MODE_SIZE (MODE)))) \ - ? 2 - (CUM) / 4 : 0) - -#ifndef MAIN_FUNCTION_PROLOGUE -#define MAIN_FUNCTION_PROLOGUE -#endif - -/* - * The function prologue for the ns32k is fairly simple. - * If a frame pointer is needed (decided in reload.c ?) then - * we need assembler of the form - * - * # Save the oldframe pointer, set the new frame pointer, make space - * # on the stack and save any general purpose registers necessary - * - * enter [], - * - * movf fn, tos # Save any floating point registers necessary - * . - * . - * - * If a frame pointer is not needed we need assembler of the form - * - * # Make space on the stack - * - * adjspd - * - * # Save any general purpose registers necessary - * - * save [] - * - * movf fn, tos # Save any floating point registers necessary - * . - * . - */ -#if defined(IMMEDIATE_PREFIX) && IMMEDIATE_PREFIX -# define ADJSP(FILE, n) \ - fprintf (FILE, "\tadjspd %c%d\n", IMMEDIATE_PREFIX, (n)) -#else -# define ADJSP(FILE, n) \ - fprintf (FILE, "\tadjspd %d\n", (n)) -#endif - -#define FUNCTION_PROLOGUE(FILE, SIZE) \ -{ register int regno, g_regs_used = 0; \ - int used_regs_buf[8], *bufp = used_regs_buf; \ - int used_fregs_buf[8], *fbufp = used_fregs_buf; \ - extern char call_used_regs[]; \ - extern int current_function_uses_pic_offset_table, flag_pic; \ - MAIN_FUNCTION_PROLOGUE; \ - for (regno = 0; regno < 8; regno++) \ - if (regs_ever_live[regno] \ - && ! call_used_regs[regno]) \ - { \ - *bufp++ = regno; g_regs_used++; \ - } \ - *bufp = -1; \ - for (; regno < 16; regno++) \ - if (regs_ever_live[regno] && !call_used_regs[regno]) \ - { \ - *fbufp++ = regno; \ - } \ - *fbufp = -1; \ - bufp = used_regs_buf; \ - if (frame_pointer_needed) \ - fprintf (FILE, "\tenter ["); \ - else \ - { \ - if (SIZE) \ - ADJSP(FILE, SIZE + 4); \ - if (g_regs_used && g_regs_used > 4) \ - fprintf (FILE, "\tsave ["); \ - else \ - { \ - while (*bufp >= 0) \ - fprintf (FILE, "\tmovd r%d,tos\n", *bufp++); \ - g_regs_used = 0; \ - } \ - } \ - while (*bufp >= 0) \ - { \ - fprintf (FILE, "r%d", *bufp++); \ - if (*bufp >= 0) \ - fputc (',', FILE); \ - } \ - if (frame_pointer_needed) \ - fprintf (FILE, "],%d\n", SIZE); \ - else if (g_regs_used) \ - fprintf (FILE, "]\n"); \ - fbufp = used_fregs_buf; \ - while (*fbufp >= 0) \ - { \ - if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1)) \ - fprintf (FILE, "\tmovf f%d,tos\n", *fbufp++ - 8); \ - else \ - { \ - fprintf (FILE, "\tmovl f%d,tos\n", fbufp[0] - 8); \ - fbufp += 2; \ - } \ - } \ - if (flag_pic && current_function_uses_pic_offset_table) \ - { \ - fprintf (FILE, "\tsprd sb,tos\n"); \ - if (TARGET_REGPARM) \ - { \ - fprintf (FILE, "\taddr __GLOBAL_OFFSET_TABLE_(pc),tos\n"); \ - fprintf (FILE, "\tlprd sb,tos\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\taddr __GLOBAL_OFFSET_TABLE_(pc),r0\n"); \ - fprintf (FILE, "\tlprd sb,r0\n"); \ - } \ - } \ -} - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. - - THIS DEFINITION FOR THE 32000 IS A GUESS. IT HAS NOT BEEN TESTED. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\taddr LP%d,r0\n\tbsr mcount\n", (LABELNO)) - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. The value is tested only in - functions that have frame pointers. - No definition is equivalent to always zero. - - We use 0, because using 1 requires hair in FUNCTION_EPILOGUE - that is worse than the stack adjust we could save. */ - -/* #define EXIT_IGNORE_STACK 1 */ - -/* This macro generates the assembly code for function exit, - on machines that need it. If FUNCTION_EPILOGUE is not defined - then individual return instructions are generated for each - return statement. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer, - if EXIT_IGNORE_STACK is nonzero. That doesn't apply here. - - If a frame pointer is needed (decided in reload.c ?) then - we need assembler of the form - - movf tos, fn # Restore any saved floating point registers - . - . - - # Restore any saved general purpose registers, restore the stack - # pointer from the frame pointer, restore the old frame pointer. - exit [] - - If a frame pointer is not needed we need assembler of the form - # Restore any general purpose registers saved - - movf tos, fn # Restore any saved floating point registers - . - . - . - restore [] - - # reclaim space allocated on stack - - adjspd <-(local stack space + 4)> */ - - -#define FUNCTION_EPILOGUE(FILE, SIZE) \ -{ register int regno, g_regs_used = 0, f_regs_used = 0; \ - int used_regs_buf[8], *bufp = used_regs_buf; \ - int used_fregs_buf[8], *fbufp = used_fregs_buf; \ - extern char call_used_regs[]; \ - extern int current_function_uses_pic_offset_table, flag_pic; \ - if (flag_pic && current_function_uses_pic_offset_table) \ - fprintf (FILE, "\tlprd sb,tos\n"); \ - *fbufp++ = -2; \ - for (regno = 8; regno < 16; regno++) \ - if (regs_ever_live[regno] && !call_used_regs[regno]) \ - { \ - *fbufp++ = regno; f_regs_used++; \ - } \ - fbufp--; \ - for (regno = 0; regno < 8; regno++) \ - if (regs_ever_live[regno] \ - && ! call_used_regs[regno]) \ - { \ - *bufp++ = regno; g_regs_used++; \ - } \ - while (fbufp > used_fregs_buf) \ - { \ - if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \ - { \ - fprintf (FILE, "\tmovl tos,f%d\n", fbufp[-1] - 8); \ - fbufp -= 2; \ - } \ - else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8); \ - } \ - if (frame_pointer_needed) \ - fprintf (FILE, "\texit ["); \ - else \ - { \ - if (g_regs_used && g_regs_used > 4) \ - fprintf (FILE, "\trestore ["); \ - else \ - { \ - while (bufp > used_regs_buf) \ - fprintf (FILE, "\tmovd tos,r%d\n", *--bufp); \ - g_regs_used = 0; \ - } \ - } \ - while (bufp > used_regs_buf) \ - { \ - fprintf (FILE, "r%d", *--bufp); \ - if (bufp > used_regs_buf) \ - fputc (',', FILE); \ - } \ - if (g_regs_used || frame_pointer_needed) \ - fprintf (FILE, "]\n"); \ - if (SIZE && !frame_pointer_needed) \ - ADJSP(FILE, -(SIZE + 4)); \ - if (current_function_pops_args) \ - fprintf (FILE, "\tret %d\n", current_function_pops_args); \ - else fprintf (FILE, "\tret 0\n"); } - -/* Store in the variable DEPTH the initial difference between the - frame pointer reg contents and the stack pointer reg contents, - as of the start of the function body. This depends on the layout - of the fixed parts of the stack frame and on how registers are saved. */ - -#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ -{ \ - int regno; \ - int offset = -4; \ - extern int current_function_uses_pic_offset_table, flag_pic; \ - for (regno = 0; regno < 16; regno++) \ - if (regs_ever_live[regno] && ! call_used_regs[regno]) \ - offset += 4; \ - if (flag_pic && current_function_uses_pic_offset_table) \ - offset += 4; \ - (DEPTH) = (offset + get_frame_size () \ - + (get_frame_size () == 0 ? 0 : 4)); \ -} - - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On the 32k, the trampoline looks like this: - addr .,r2 - jump @__trampoline - .int STATIC - .int FUNCTION -Doing trampolines with a library assist function is easier than figuring -out how to do stores to memory in reverse byte order (the way immediate -operands on the 32k are stored). */ - -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - fprintf (FILE, "\taddr .,r2\n" ); \ - fprintf (FILE, "\tjump " ); \ - PUT_ABSOLUTE_PREFIX (FILE); \ - fprintf (FILE, "__trampoline\n" ); \ - ASM_OUTPUT_INT (FILE, const0_rtx); \ - ASM_OUTPUT_INT (FILE, const0_rtx); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 20 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), CXT); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), FNADDR); \ -} - -/* This is the library routine that is used - to transfer control from the trampoline - to the actual nested function. */ - -/* The function name __transfer_from_trampoline is not actually used. - The function definition just permits use of "asm with operands" - (though the operand list is empty). */ -#define TRANSFER_FROM_TRAMPOLINE \ -void \ -__transfer_from_trampoline () \ -{ \ - asm ("___trampoline:"); \ - asm ("movd 16(r2),tos"); \ - asm ("movd 12(r2),r2"); \ - asm ("ret 0"); \ -} - -/* Addressing modes, and classification of registers for them. */ - -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ - -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -/* note that FP and SP cannot be used as an index. What about PC? */ -#define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < 8 || (unsigned)reg_renumber[REGNO] < 8) -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < 8 || (unsigned)reg_renumber[REGNO] < 8 \ - || (REGNO) == FRAME_POINTER_REGNUM || (REGNO) == STACK_POINTER_REGNUM) - -#define FP_REG_P(X) (GET_CODE (X) == REG && REGNO (X) > 7 && REGNO (X) < 16) - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. - This might not work on future ns32k processors as negative - displacements are not officially allowed but a mode reserved - to National. This works on processors up to 32532, though. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST \ - || (GET_CODE (X) == CONST_INT \ - && ((unsigned)INTVAL (X) >= 0xe0000000 \ - || (unsigned)INTVAL (X) < 0x20000000))) - -#define CONSTANT_ADDRESS_NO_LABEL_P(X) \ - (GET_CODE (X) == CONST_INT \ - && ((unsigned)INTVAL (X) >= 0xe0000000 \ - || (unsigned)INTVAL (X) < 0x20000000)) - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in CLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ - secondary_reload_class (CLASS, MODE, IN) - -/* Nonzero if the constant value X is a legitimate general operand. - It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -#define LEGITIMATE_CONSTANT_P(X) 1 - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - After reload, it makes no difference, since pseudo regs have - been eliminated by then. */ - -#ifndef REG_OK_STRICT - -/* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg. */ -#define REG_OK_FOR_INDEX_P(X) \ - (REGNO (X) < 8 || REGNO (X) >= FIRST_PSEUDO_REGISTER) -/* Nonzero if X is a hard reg that can be used as a base reg - of if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) (REGNO (X) < 8 || REGNO (X) >= FRAME_POINTER_REGNUM) -/* Nonzero if X is a floating point reg or a pseudo reg. */ - -#else - -/* Nonzero if X is a hard reg that can be used as an index. */ -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -/* Nonzero if X is a hard reg that can be used as a base reg. */ -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) - -#endif - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ - -/* 1 if X is an address that we could indirect through. */ -/***** NOTE ***** There is a bug in the Sequent assembler which fails - to fixup addressing information for symbols used as offsets - from registers which are not FP or SP (or SB or PC). This - makes _x(fp) valid, while _x(r0) is invalid. */ - -#define INDIRECTABLE_1_ADDRESS_P(X) \ - (CONSTANT_ADDRESS_P (X) \ - || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ - || (GET_CODE (X) == PLUS \ - && GET_CODE (XEXP (X, 0)) == REG \ - && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && (flag_pic ? \ - CONSTANT_ADDRESS_NO_LABEL_P (XEXP (X, 1)) \ - : \ - CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - && (GET_CODE (X) != CONST_INT || NS32K_DISPLACEMENT_P (INTVAL (X))))) - -/* 1 if integer I will fit in a 4 byte displacement field. - Strictly speaking, we can't be sure that a symbol will fit this range. - But, in practice, it always will. */ - -/* idall@eleceng.adelaide.edu.au says that the 32016 and 32032 - can handle the full range of displacements--it is only the addresses - that have a limited range. So the following was deleted: - (((i) <= 16777215 && (i) >= -16777216) - || ((TARGET_32532 || TARGET_32332) && ...)) */ -#define NS32K_DISPLACEMENT_P(i) \ - ((i) < (1 << 29) && (i) >= - (1 << 29)) - -/* Check for frame pointer or stack pointer. */ -#define MEM_REG(X) \ - (GET_CODE (X) == REG && (REGNO (X) ^ 16) < 2) - -/* A memory ref whose address is the FP or SP, with optional integer offset, - or (on certain machines) a constant address. */ -#define INDIRECTABLE_2_ADDRESS_P(X) \ - (GET_CODE (X) == MEM \ - && (((xfoo0 = XEXP (X, 0), MEM_REG (xfoo0)) \ - || (GET_CODE (xfoo0) == PLUS \ - && MEM_REG (XEXP (xfoo0, 0)) \ - && CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfoo0, 1)))) \ - || (TARGET_SB && CONSTANT_ADDRESS_P (xfoo0)))) - -/* Go to ADDR if X is a valid address not using indexing. - (This much is the easy part.) */ -#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \ -{ register rtx xfoob = (X); \ - if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; \ - if (INDIRECTABLE_2_ADDRESS_P (X)) goto ADDR; \ - if (GET_CODE (X) == PLUS) \ - if (CONSTANT_ADDRESS_NO_LABEL_P (XEXP (X, 1))) \ - if (INDIRECTABLE_2_ADDRESS_P (XEXP (X, 0))) \ - goto ADDR; \ -} - -/* Go to ADDR if X is a valid address not using indexing. - (This much is the easy part.) */ -#define GO_IF_INDEXING(X, MODE, ADDR) \ -{ register rtx xfoob = (X); \ - if (GET_CODE (xfoob) == PLUS && INDEX_TERM_P (XEXP (xfoob, 0), MODE)) \ - GO_IF_INDEXABLE_ADDRESS (XEXP (xfoob, 1), ADDR); \ - if (GET_CODE (xfoob) == PLUS && INDEX_TERM_P (XEXP (xfoob, 1), MODE)) \ - GO_IF_INDEXABLE_ADDRESS (XEXP (xfoob, 0), ADDR); } \ - -#define GO_IF_INDEXABLE_ADDRESS(X, ADDR) \ -{ if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR; \ - if (INDIRECTABLE_2_ADDRESS_P (X)) goto ADDR; \ - if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; \ -} - -/* 1 if PROD is either a reg times size of mode MODE - or just a reg, if MODE is just one byte. Actually, on the ns32k, - since the index mode is independent of the operand size, - we can match more stuff... - - This macro's expansion uses the temporary variables xfoo0, xfoo1 - and xfoo2 that must be declared in the surrounding context. */ -#define INDEX_TERM_P(PROD, MODE) \ -((GET_CODE (PROD) == REG && REG_OK_FOR_INDEX_P (PROD)) \ - || (GET_CODE (PROD) == MULT \ - && (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1), \ - (GET_CODE (xfoo1) == CONST_INT \ - && GET_CODE (xfoo0) == REG \ - && FITS_INDEX_RANGE (INTVAL (xfoo1)) \ - && REG_OK_FOR_INDEX_P (xfoo0))))) - -#define FITS_INDEX_RANGE(X) \ - ((xfoo2 = (unsigned)(X)-1), \ - ((xfoo2 < 4 && xfoo2 != 2) || xfoo2 == 7)) - -/* Note that xfoo0, xfoo1, xfoo2 are used in some of the submacros above. */ -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ register rtx xfooy, xfoo0, xfoo1; \ - unsigned xfoo2; \ - extern int current_function_uses_pic_offset_table, flag_pic; \ - xfooy = X; \ - if (flag_pic && ! current_function_uses_pic_offset_table \ - && global_symbolic_reference_mentioned_p (X, 1)) \ - current_function_uses_pic_offset_table = 1; \ - GO_IF_NONINDEXED_ADDRESS (xfooy, ADDR); \ - if (GET_CODE (xfooy) == PLUS) \ - { \ - if (CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfooy, 1)) \ - && GET_CODE (XEXP (xfooy, 0)) == PLUS) \ - xfooy = XEXP (xfooy, 0); \ - else if (CONSTANT_ADDRESS_NO_LABEL_P (XEXP (xfooy, 0)) \ - && GET_CODE (XEXP (xfooy, 1)) == PLUS) \ - xfooy = XEXP (xfooy, 1); \ - GO_IF_INDEXING (xfooy, MODE, ADDR); \ - } \ - else if (INDEX_TERM_P (xfooy, MODE)) \ - goto ADDR; \ - else if (GET_CODE (xfooy) == PRE_DEC) \ - if (REGNO (XEXP (xfooy, 0)) == STACK_POINTER_REGNUM) goto ADDR; \ - else abort (); \ -} - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. - - For the ns32k, we do nothing */ - -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {} - -/* Nonzero if the constant value X is a legitimate general operand - when generating PIC code. It is given that flag_pic is on and - that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ - -extern int current_function_uses_pic_offset_table, flag_pic; -#define LEGITIMATE_PIC_OPERAND_P(X) \ - (((! current_function_uses_pic_offset_table \ - && global_symbolic_reference_mentioned_p (X, 1))? \ - (current_function_uses_pic_offset_table = 1):0 \ - ), 1) - -/* Define this macro if references to a symbol must be treated - differently depending on something about the variable or - function named by the symbol (such as what section it is in). - - On the ns32k, if using PIC, mark a SYMBOL_REF for a non-global - symbol or a code symbol. These symbols are referenced via pc - and not via sb. */ - -#define ENCODE_SECTION_INFO(DECL) \ -do \ - { \ - extern int flag_pic; \ - if (flag_pic) \ - { \ - rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ - SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ - = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ - || TREE_CODE (DECL) == FUNCTION_DECL \ - || ! TREE_PUBLIC (DECL)); \ - } \ - } \ -while (0) - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - On the ns32k, only predecrement and postincrement address depend thus - (the amount of decrement or increment being the length of the operand). */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ - { if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC) \ - goto LABEL;} - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. - HI mode is more efficient but the range is not wide enough for - all programs. */ -#define CASE_VECTOR_MODE SImode - -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -#define CASE_VECTOR_PC_RELATIVE - -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 1 - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX 4 - -/* Define this if zero-extension is slow (more than one real instruction). */ -/* #define SLOW_ZERO_EXTEND */ - -/* Nonzero if access to memory by bytes is slow and undesirable. */ -#define SLOW_BYTE_ACCESS 0 - -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -/* #define SHIFT_COUNT_TRUNCATED */ - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE 1 - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ -#define Pmode SImode - -/* A function address in a call instruction - is a byte address (for indexing purposes) - so give the MEM rtx a byte's mode. */ -#define FUNCTION_MODE QImode - -/* Compute the cost of address ADDRESS. */ - -#define ADDRESS_COST(RTX) calc_address_cost (RTX) - -/* Compute the cost of computing a constant rtl expression RTX - whose rtx-code is CODE. The body of this macro is a portion - of a switch statement. If the code is computed here, - return it with a return statement. Otherwise, break from the switch. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - if (INTVAL (RTX) <= 7 && INTVAL (RTX) >= -8) return 0; \ - if (INTVAL (RTX) < 0x4000 && INTVAL (RTX) >= -0x4000) \ - return 1; \ - case CONST: \ - case LABEL_REF: \ - case SYMBOL_REF: \ - return 3; \ - case CONST_DOUBLE: \ - return 5; - -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). */ - -/* This bit means that what ought to be in the Z bit - should be tested in the F bit. */ -#define CC_Z_IN_F 04000 - -/* This bit means that what ought to be in the Z bit - is complemented in the F bit. */ -#define CC_Z_IN_NOT_F 010000 - -/* Store in cc_status the expressions - that the condition codes will describe - after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -#define NOTICE_UPDATE_CC(EXP, INSN) \ -{ if (GET_CODE (EXP) == SET) \ - { if (GET_CODE (SET_DEST (EXP)) == CC0) \ - { cc_status.flags = 0; \ - cc_status.value1 = SET_DEST (EXP); \ - cc_status.value2 = SET_SRC (EXP); \ - } \ - else if (GET_CODE (SET_SRC (EXP)) == CALL) \ - { CC_STATUS_INIT; } \ - else if (GET_CODE (SET_DEST (EXP)) == REG) \ - { if (cc_status.value1 \ - && reg_overlap_mentioned_p (SET_DEST (EXP), cc_status.value1)) \ - cc_status.value1 = 0; \ - if (cc_status.value2 \ - && reg_overlap_mentioned_p (SET_DEST (EXP), cc_status.value2)) \ - cc_status.value2 = 0; \ - } \ - else if (GET_CODE (SET_DEST (EXP)) == MEM) \ - { CC_STATUS_INIT; } \ - } \ - else if (GET_CODE (EXP) == PARALLEL \ - && GET_CODE (XVECEXP (EXP, 0, 0)) == SET) \ - { if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) == CC0) \ - { cc_status.flags = 0; \ - cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0)); \ - cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); \ - } \ - else if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) == REG) \ - { if (cc_status.value1 \ - && reg_overlap_mentioned_p (SET_DEST (XVECEXP (EXP, 0, 0)), cc_status.value1)) \ - cc_status.value1 = 0; \ - if (cc_status.value2 \ - && reg_overlap_mentioned_p (SET_DEST (XVECEXP (EXP, 0, 0)), cc_status.value2)) \ - cc_status.value2 = 0; \ - } \ - else if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) == MEM) \ - { CC_STATUS_INIT; } \ - } \ - else if (GET_CODE (EXP) == CALL) \ - { /* all bets are off */ CC_STATUS_INIT; } \ - else { /* nothing happens? CC_STATUS_INIT; */} \ - if (cc_status.value1 && GET_CODE (cc_status.value1) == REG \ - && cc_status.value2 \ - && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) \ - abort (); \ -} - -/* Describe the costs of the following register moves which are discouraged: - 1.) Moves between the Floating point registers and the frame pointer and stack pointer - 2.) Moves between the stack pointer and the frame pointer - 3.) Moves between the floating point and general registers */ - -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - ((((CLASS1) == FLOAT_REGS && ((CLASS2) == STACK_POINTER_REG || (CLASS2) == FRAME_POINTER_REG)) \ - || ((CLASS2) == FLOAT_REGS && ((CLASS1) == STACK_POINTER_REG || (CLASS1) == FRAME_POINTER_REG)) \ - || ((CLASS1) == STACK_POINTER_REG && (CLASS2) == FRAME_POINTER_REG) \ - || ((CLASS2) == STACK_POINTER_REG && (CLASS1) == FRAME_POINTER_REG) \ - || ((CLASS1) == FLOAT_REGS && (CLASS2) == GENERAL_REGS) \ - || ((CLASS1) == GENERAL_REGS && (CLASS2) == FLOAT_REGS)) \ - ? 4 : 2) - -#define OUTPUT_JUMP(NORMAL, NO_OV) \ -{ if (cc_status.flags & CC_NO_OVERFLOW) \ - return NO_OV; \ - return NORMAL; } - -/* Dividing the output into sections */ - -/* Output before read-only data. */ - -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP ".data" - -/* Define the output Assembly Language */ - -/* Output at beginning of assembler file. */ - -#define ASM_FILE_START(FILE) fprintf (FILE, "#NO_APP\n"); - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#define ASM_APP_ON "#APP\n" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "#NO_APP\n" - -/* Output of Data */ - -/* This is how to output an assembler line defining a `double' constant. */ - -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - fprintf (FILE, "\t.double 0d%.20e\n", (VALUE)) - -/* This is how to output an assembler line defining a `float' constant. */ - -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - fprintf (FILE, "\t.float 0f%.20e\n", (VALUE)) - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fprintf (FILE, "\t.long "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* Likewise for `char' and `short' constants. */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "\t.word "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fprintf (FILE, "\t.byte "), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf (FILE, "\t.byte 0x%x\n", (VALUE)) - -/* This is how to output an assembler line defining an external/static - address which is not in tree format (for collect.c). */ - -#define ASM_OUTPUT_LABELREF_AS_INT(STREAM, NAME) \ -do { \ - fprintf (STREAM, "\t.long\t"); \ - ASM_OUTPUT_LABELREF (STREAM, NAME); \ - fprintf (STREAM, "\n"); \ -} while (0) - -/* This is how to output an insn to push a register on the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tmovd %s,tos\n", reg_names[REGNO]) - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tmovd tos,%s\n", reg_names[REGNO]) - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -#define REGISTER_NAMES \ -{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ - "fp", "sp"} - -/* How to renumber registers for dbx and gdb. - NS32000 may need more change in the numeration. */ - -#define DBX_REGISTER_NUMBER(REGNO) ((REGNO < 8) ? (REGNO)+4 : (REGNO)) - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#ifndef COLLECT -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) -#else -#define ASM_OUTPUT_LABEL(STREAM,NAME) \ -do { \ - fprintf (STREAM, "%s:\n", NAME); \ -} while (0) -#endif - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#ifndef COLLECT -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fputs (".globl ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0) -#else -#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \ -do { \ - fprintf (STREAM, "\t.globl\t%s\n", NAME); \ -} while (0) -#endif - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "_%s", NAME) - -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d:\n", PREFIX, NUM) - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s%d", PREFIX, NUM) - -/* This is how to align the code that follows an unconditional branch. - Note that 0xa2 is a no-op. */ - -#define ASM_OUTPUT_ALIGN_CODE(FILE) \ - fprintf (FILE, "\t.align 2,0xa2\n") - -/* This is how to output an element of a case-vector that is absolute. - (The ns32k does not use such vectors, - but we must define this macro anyway.) */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.long L%d\n", VALUE) - -/* This is how to output an element of a case-vector that is relative. */ -/* ** Notice that the second element is LI format! */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.long L%d-LI%d\n", VALUE, REL) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - fprintf (FILE, "\t.align %d\n", (LOG)) - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.space %u\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (ROUNDED))) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) - -/* Define the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "(" -#define ASM_CLOSE_PAREN ")" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - -/* Print an instruction operand X on file FILE. - CODE is the code from the %-spec that requested printing this operand; - if `%z3' was used to print operand 3, then CODE is 'z'. */ - -/* %$ means print the prefix for an immediate operand. */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '$' || (CODE) == '?') - -#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE) - -/* Print a memory operand whose address is X, on file FILE. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address(FILE, ADDR) - -/* Define functions in ns32k.c and used in insn-output.c. */ - -extern char *output_move_double (); -extern char *output_shift_insn (); -extern char *output_move_dconst (); - -/* -Local variables: -version-control: t -End: -*/ diff --git a/gnu/usr.bin/gcc2/arch/ns32k/tconfig.h b/gnu/usr.bin/gcc2/arch/ns32k/tconfig.h deleted file mode 100644 index fdb3b8451f3..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/tconfig.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Configuration for GNU C-compiler for the ns32532. - Copyright (C) 1987, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: tconfig.h,v 1.1.1.1 1995/10/18 08:39:23 deraadt Exp $ -*/ - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* NetBSD does have atexit. */ - -#define HAVE_ATEXIT - diff --git a/gnu/usr.bin/gcc2/arch/ns32k/tm.h b/gnu/usr.bin/gcc2/arch/ns32k/tm.h deleted file mode 100644 index 196acb9ae6a..00000000000 --- a/gnu/usr.bin/gcc2/arch/ns32k/tm.h +++ /dev/null @@ -1,220 +0,0 @@ -/* Configuration for an ns32532 running NetBSD as the target machine. - -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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: tm.h,v 1.1.1.1 1995/10/18 08:39:23 deraadt Exp $ -*/ - -#if 0 -#include -#endif -#include "ns32k/ns32k.h" - -/* Compile for the floating point unit & 32532 by default; - Don't assume SB is zero */ - -#define TARGET_DEFAULT 57 - -/* 32-bit alignment for efficiency */ - -#undef POINTER_BOUNDARY -#define POINTER_BOUNDARY 32 - -/* 32-bit alignment for efficiency */ - -#undef FUNCTION_BOUNDARY -#define FUNCTION_BOUNDARY 32 - -/* 32532 spec says it can handle any alignment. Rumor from tm-ns32k.h - tells this might not be actually true (but it's for 32032, perhaps - National has fixed the bug for 32532). You might have to change this - if the bug still exists. */ - -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT 0 - -/* Use pc relative addressing whenever possible, - it's more efficient than absolute (ns32k.c) - You have to fix a bug in gas 1.38.1 to make this work with gas, - patch available from jkp@cs.hut.fi. - (NetBSD's gas version has this patch already applied) */ - -#define PC_RELATIVE - -/* Operand of bsr or jsr should be just the address. */ - -#define CALL_MEMREF_IMPLICIT - -/* movd insns may have floating point constant operands. */ - -#define MOVD_FLOAT_OK - -/* Every address needs to use a base reg. */ - -#define BASE_REG_NEEDED - -/* Names to predefine in the preprocessor for this target machine. */ - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dpc532 -Dns32k -Dns32532 -Dunix -D__NetBSD__ -D__ns32k__" - -/* Specify -k to assembler for pic generation. PIC needs -K too. */ - -#define ASM_SPEC "%{fpic:-k} %{fPIC:-k -K}" - -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -#define STARTFILE_SPEC \ - "%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}\ - %{!p:%{static:scrt0.o%s}%{!static:crt0.o%s}}}}" - -/* No more libg.a; no libraries if making shared object */ - -#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" - -/* Make gcc agree with */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "short unsigned int" - -#define WCHAR_UNSIGNED 1 - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 16 - -/* This is BSD, so it wants DBX format. */ - -#define DBX_DEBUGGING_INFO - -/* Do not break .stabs pseudos into continuations. */ - -#define DBX_CONTIN_LENGTH 0 - -/* This is the char to use for continuation (in case we need to turn - continuation back on). */ - -#define DBX_CONTIN_CHAR '?' - -/* Don't use the `xsfoo;' construct in DBX output; this system - doesn't support it. */ - -#define DBX_NO_XREFS - -/* Don't default to pcc-struct-return, because gcc is the only compiler, and - we want to retain compatibility with older gcc versions. */ - -#undef PCC_STATIC_STRUCT_RETURN -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* - * Some imports from svr4.h in support of shared libraries. - */ - -#define HANDLE_SYSV_PRAGMA - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" -#define WEAK_ASM_OP ".weak" -#define SET_ASM_OP ".set" - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* Write the extra assembler code needed to declare a function's result. - Most svr4 assemblers don't require any special declaration of the - result value, but there are exceptions. */ - -#ifndef ASM_DECLARE_RESULT -#define ASM_DECLARE_RESULT(FILE, RESULT) -#endif - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - if (!flag_inhibit_size_directive) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) diff --git a/gnu/usr.bin/gcc2/arch/sparc/aux-output.c b/gnu/usr.bin/gcc2/arch/sparc/aux-output.c deleted file mode 100644 index 5ecaa65ba7e..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/aux-output.c +++ /dev/null @@ -1,3460 +0,0 @@ -/* Subroutines for insn-output.c for Sun SPARC. - Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include "config.h" -#include "tree.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-flags.h" -#include "output.h" -#include "insn-attr.h" -#include "flags.h" -#include "expr.h" -#include "recog.h" - -/* Global variables for machine-dependent things. */ - -/* Save the operands last given to a compare for use when we - generate a scc or bcc insn. */ - -rtx sparc_compare_op0, sparc_compare_op1; - -/* We may need an epilogue if we spill too many registers. - If this is non-zero, then we branch here for the epilogue. */ -static rtx leaf_label; - -#ifdef LEAF_REGISTERS - -/* Vector to say how input registers are mapped to output - registers. FRAME_POINTER_REGNUM cannot be remapped by - this function to eliminate it. You must use -fomit-frame-pointer - to get that. */ -char leaf_reg_remap[] = -{ 0, 1, 2, 3, 4, 5, 6, 7, - -1, -1, -1, -1, -1, -1, 14, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - 8, 9, 10, 11, 12, 13, -1, 15, - - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63}; - -char leaf_reg_backmap[] = -{ 0, 1, 2, 3, 4, 5, 6, 7, - 24, 25, 26, 27, 28, 29, 14, 31, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63}; -#endif - -/* Global variables set by FUNCTION_PROLOGUE. */ -/* Size of frame. Need to know this to emit return insns from - leaf procedures. */ -int apparent_fsize; -int actual_fsize; - -/* Name of where we pretend to think the frame pointer points. - Normally, this is "%fp", but if we are in a leaf procedure, - this is "%sp+something". */ -char *frame_base_name; - -static rtx find_addr_reg (); - -/* Return non-zero only if OP is a register of mode MODE, - or const0_rtx. */ -int -reg_or_0_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (op == const0_rtx || register_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (op) == 0 - && CONST_DOUBLE_LOW (op) == 0) - return 1; - return 0; -} - -/* Nonzero if OP can appear as the dest of a RESTORE insn. */ -int -restore_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == REG && GET_MODE (op) == mode - && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32))); -} - -/* Call insn on SPARC can take a PC-relative constant address, or any regular - memory address. */ - -int -call_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) != MEM) - abort (); - op = XEXP (op, 0); - return (CONSTANT_P (op) || memory_address_p (Pmode, op)); -} - -int -call_operand_address (op, mode) - rtx op; - enum machine_mode mode; -{ - return (CONSTANT_P (op) || memory_address_p (Pmode, op)); -} - -/* Returns 1 if OP is either a symbol reference or a sum of a symbol - reference and a constant. */ - -int -symbolic_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - switch (GET_CODE (op)) - { - case SYMBOL_REF: - case LABEL_REF: - return 1; - - case CONST: - op = XEXP (op, 0); - return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF) - && GET_CODE (XEXP (op, 1)) == CONST_INT); - - /* ??? This clause seems to be irrelevant. */ - case CONST_DOUBLE: - return GET_MODE (op) == mode; - - default: - return 0; - } -} - -/* Return truth value of statement that OP is a symbolic memory - operand of mode MODE. */ - -int -symbolic_memory_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) != MEM) - return 0; - op = XEXP (op, 0); - return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST - || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF); -} - -/* Return 1 if the operand is either a register or a memory operand that is - not symbolic. */ - -int -reg_or_nonsymb_mem_operand (op, mode) - register rtx op; - enum machine_mode mode; -{ - if (register_operand (op, mode)) - return 1; - - if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) - return 1; - - return 0; -} - -int -sparc_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (register_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT) - return SMALL_INT (op); - if (GET_MODE (op) != mode) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) != MEM) - return 0; - - op = XEXP (op, 0); - if (GET_CODE (op) == LO_SUM) - return (GET_CODE (XEXP (op, 0)) == REG - && symbolic_operand (XEXP (op, 1), Pmode)); - return memory_address_p (mode, op); -} - -int -move_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (mode == DImode && arith_double_operand (op, mode)) - return 1; - if (register_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT) - return (SMALL_INT (op) || (INTVAL (op) & 0x3ff) == 0); - - if (GET_MODE (op) != mode) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) != MEM) - return 0; - op = XEXP (op, 0); - if (GET_CODE (op) == LO_SUM) - return (register_operand (XEXP (op, 0), Pmode) - && CONSTANT_P (XEXP (op, 1))); - return memory_address_p (mode, op); -} - -int -move_pic_label (op, mode) - rtx op; - enum machine_mode mode; -{ - /* Special case for PIC. */ - if (flag_pic && GET_CODE (op) == LABEL_REF) - return 1; - return 0; -} - -/* The rtx for the global offset table which is a special form - that *is* a position independent symbolic constant. */ -rtx pic_pc_rtx; - -/* Ensure that we are not using patterns that are not OK with PIC. */ - -int -check_pic (i) - int i; -{ - switch (flag_pic) - { - case 1: - if (GET_CODE (recog_operand[i]) == SYMBOL_REF - || (GET_CODE (recog_operand[i]) == CONST - && ! rtx_equal_p (pic_pc_rtx, recog_operand[i]))) - abort (); - case 2: - default: - return 1; - } -} - -/* Return true if X is an address which needs a temporary register when - reloaded while generating PIC code. */ - -int -pic_address_needs_scratch (x) - rtx x; -{ - /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) - return 1; - - return 0; -} - -int -memop (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == MEM) - return (mode == VOIDmode || mode == GET_MODE (op)); - return 0; -} - -/* Return truth value of whether OP is EQ or NE. */ - -int -eq_or_neq (op, mode) - rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == EQ || GET_CODE (op) == NE); -} - -/* Return 1 if this is a comparison operator, but not an EQ, NE, GEU, - or LTU for non-floating-point. We handle those specially. */ - -int -normal_comp_operator (op, mode) - rtx op; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (op); - - if (GET_RTX_CLASS (code) != '<') - return 0; - - if (GET_MODE (XEXP (op, 0)) == CCFPmode - || GET_MODE (XEXP (op, 0)) == CCFPEmode) - return 1; - - return (code != NE && code != EQ && code != GEU && code != LTU); -} - -/* Return 1 if this is a comparison operator. This allows the use of - MATCH_OPERATOR to recognize all the branch insns. */ - -int -noov_compare_op (op, mode) - register rtx op; - enum machine_mode mode; -{ - enum rtx_code code = GET_CODE (op); - - if (GET_RTX_CLASS (code) != '<') - return 0; - - if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode) - /* These are the only branches which work with CC_NOOVmode. */ - return (code == EQ || code == NE || code == GE || code == LT); - return 1; -} - -/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */ - -int -extend_op (op, mode) - rtx op; - enum machine_mode mode; -{ - return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND; -} - -/* Return nonzero if OP is an operator of mode MODE which can set - the condition codes explicitly. We do not include PLUS and MINUS - because these require CC_NOOVmode, which we handle explicitly. */ - -int -cc_arithop (op, mode) - rtx op; - enum machine_mode mode; -{ - if (GET_CODE (op) == AND - || GET_CODE (op) == IOR - || GET_CODE (op) == XOR) - return 1; - - return 0; -} - -/* Return nonzero if OP is an operator of mode MODE which can bitwise - complement its second operand and set the condition codes explicitly. */ - -int -cc_arithopn (op, mode) - rtx op; - enum machine_mode mode; -{ - /* XOR is not here because combine canonicalizes (xor (not ...) ...) - and (xor ... (not ...)) to (not (xor ...)). */ - return (GET_CODE (op) == AND - || GET_CODE (op) == IOR); -} - -/* Return true if OP is a register, or is a CONST_INT that can fit in a 13 - bit immediate field. This is an acceptable SImode operand for most 3 - address instructions. */ - -int -arith_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) - || (GET_CODE (op) == CONST_INT && SMALL_INT (op))); -} - -/* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that - can fit in a 13 bit immediate field. This is an acceptable DImode operand - for most 3 address instructions. */ - -int -arith_double_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) - || (GET_CODE (op) == CONST_DOUBLE - && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) - && (unsigned) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 - && ((CONST_DOUBLE_HIGH (op) == -1 - && (CONST_DOUBLE_LOW (op) & 0x1000) == 0x1000) - || (CONST_DOUBLE_HIGH (op) == 0 - && (CONST_DOUBLE_LOW (op) & 0x1000) == 0))) - || (GET_CODE (op) == CONST_INT - && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) - && (unsigned) (INTVAL (op) + 0x1000) < 0x2000)); -} - -/* Return truth value of whether OP is a integer which fits the - range constraining immediate operands in most three-address insns, - which have a 13 bit immediate field. */ - -int -small_int (op, mode) - rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); -} - -/* Return truth value of statement that OP is a call-clobbered register. */ -int -clobbered_register (op, mode) - rtx op; - enum machine_mode mode; -{ - return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]); -} - -/* X and Y are two things to compare using CODE. Emit the compare insn and - return the rtx for register 0 in the proper mode. */ - -rtx -gen_compare_reg (code, x, y) - enum rtx_code code; - rtx x, y; -{ - enum machine_mode mode = SELECT_CC_MODE (code, x, y); - rtx cc_reg = gen_rtx (REG, mode, 0); - - emit_insn (gen_rtx (SET, VOIDmode, cc_reg, - gen_rtx (COMPARE, mode, x, y))); - - return cc_reg; -} - -/* Return nonzero if a return peephole merging return with - setting of output register is ok. */ -int -leaf_return_peephole_ok () -{ - return (actual_fsize == 0); -} - -/* Return nonzero if TRIAL can go into the function epilogue's - delay slot. SLOT is the slot we are trying to fill. */ - -int -eligible_for_epilogue_delay (trial, slot) - rtx trial; - int slot; -{ - rtx pat, src; - - if (slot >= 1) - return 0; - if (GET_CODE (trial) != INSN - || GET_CODE (PATTERN (trial)) != SET) - return 0; - if (get_attr_length (trial) != 1) - return 0; - - /* In the case of a true leaf function, anything can go into the delay slot. - A delay slot only exists however if the frame size is zero, otherwise - we will put an insn to adjust the stack after the return. */ - if (leaf_function) - { - if (leaf_return_peephole_ok ()) - return (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE); - return 0; - } - - /* Otherwise, only operations which can be done in tandem with - a `restore' insn can go into the delay slot. */ - pat = PATTERN (trial); - if (GET_CODE (SET_DEST (pat)) != REG - || REGNO (SET_DEST (pat)) == 0 - || REGNO (SET_DEST (pat)) >= 32 - || REGNO (SET_DEST (pat)) < 24) - return 0; - - src = SET_SRC (pat); - if (arith_operand (src, GET_MODE (src))) - return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); - if (arith_double_operand (src, GET_MODE (src))) - return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); - if (GET_CODE (src) == PLUS) - { - if (register_operand (XEXP (src, 0), SImode) - && arith_operand (XEXP (src, 1), SImode)) - return 1; - if (register_operand (XEXP (src, 1), SImode) - && arith_operand (XEXP (src, 0), SImode)) - return 1; - if (register_operand (XEXP (src, 0), DImode) - && arith_double_operand (XEXP (src, 1), DImode)) - return 1; - if (register_operand (XEXP (src, 1), DImode) - && arith_double_operand (XEXP (src, 0), DImode)) - return 1; - } - if (GET_CODE (src) == MINUS - && register_operand (XEXP (src, 0), SImode) - && small_int (XEXP (src, 1), VOIDmode)) - return 1; - if (GET_CODE (src) == MINUS - && register_operand (XEXP (src, 0), DImode) - && !register_operand (XEXP (src, 1), DImode) - && arith_double_operand (XEXP (src, 1), DImode)) - return 1; - return 0; -} - -int -short_branch (uid1, uid2) - int uid1, uid2; -{ - unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2]; - if (delta + 1024 < 2048) - return 1; - /* warning ("long branch, distance %d", delta); */ - return 0; -} - -/* Return non-zero if REG is not used after INSN. - We assume REG is a reload reg, and therefore does - not live past labels or calls or jumps. */ -int -reg_unused_after (reg, insn) - rtx reg; - rtx insn; -{ - enum rtx_code code, prev_code = UNKNOWN; - - while (insn = NEXT_INSN (insn)) - { - if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)]) - return 1; - - code = GET_CODE (insn); - if (GET_CODE (insn) == CODE_LABEL) - return 1; - - if (GET_RTX_CLASS (code) == 'i') - { - rtx set = single_set (insn); - int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set)); - if (set && in_src) - return 0; - if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) - return 1; - if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) - return 0; - } - prev_code = code; - } - return 1; -} - -/* Legitimize PIC addresses. If the address is already position-independent, - we return ORIG. Newly generated position-independent addresses go into a - reg. This is REG if non zero, otherwise we allocate register(s) as - necessary. If this is called during reload, and we need a second temp - register, then we use SCRATCH, which is provided via the - SECONDARY_INPUT_RELOAD_CLASS mechanism. */ - -rtx -legitimize_pic_address (orig, mode, reg, scratch) - rtx orig; - enum machine_mode mode; - rtx reg, scratch; -{ - if (GET_CODE (orig) == SYMBOL_REF) - { - rtx pic_ref, address; - rtx insn; - - if (reg == 0) - { - if (reload_in_progress || reload_completed) - abort (); - else - reg = gen_reg_rtx (Pmode); - } - - if (flag_pic == 2) - { - /* If not during reload, allocate another temp reg here for loading - in the address, so that these instructions can be optimized - properly. */ - rtx temp_reg = ((reload_in_progress || reload_completed) - ? reg : gen_reg_rtx (Pmode)); - - /* Must put the SYMBOL_REF inside an UNSPEC here so that cse - won't get confused into thinking that these two instructions - are loading in the true address of the symbol. If in the - future a PIC rtx exists, that should be used instead. */ - emit_insn (gen_rtx (SET, VOIDmode, temp_reg, - gen_rtx (HIGH, Pmode, - gen_rtx (UNSPEC, Pmode, - gen_rtvec (1, orig), - 0)))); - emit_insn (gen_rtx (SET, VOIDmode, temp_reg, - gen_rtx (LO_SUM, Pmode, temp_reg, - gen_rtx (UNSPEC, Pmode, - gen_rtvec (1, orig), - 0)))); - address = temp_reg; - } - else - address = orig; - - pic_ref = gen_rtx (MEM, Pmode, - gen_rtx (PLUS, Pmode, - pic_offset_table_rtx, address)); - current_function_uses_pic_offset_table = 1; - RTX_UNCHANGING_P (pic_ref) = 1; - insn = emit_move_insn (reg, pic_ref); - /* Put a REG_EQUAL note on this insn, so that it can be optimized - by loop. */ - REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig, - REG_NOTES (insn)); - return reg; - } - else if (GET_CODE (orig) == CONST) - { - rtx base, offset; - - if (GET_CODE (XEXP (orig, 0)) == PLUS - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) - return orig; - - if (reg == 0) - { - if (reload_in_progress || reload_completed) - abort (); - else - reg = gen_reg_rtx (Pmode); - } - - if (GET_CODE (XEXP (orig, 0)) == PLUS) - { - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, - reg, 0); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, - base == reg ? 0 : reg, 0); - } - else - abort (); - - if (GET_CODE (offset) == CONST_INT) - { - if (SMALL_INT (offset)) - return plus_constant_for_output (base, INTVAL (offset)); - else if (! reload_in_progress && ! reload_completed) - offset = force_reg (Pmode, offset); - /* We can't create any new registers during reload, so use the - SCRATCH reg provided by the reload_insi pattern. */ - else if (scratch) - { - emit_move_insn (scratch, offset); - offset = scratch; - } - else - /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS - macro needs to be adjusted so that a scratch reg is provided - for this address. */ - abort (); - } - return gen_rtx (PLUS, Pmode, base, offset); - } - else if (GET_CODE (orig) == LABEL_REF) - current_function_uses_pic_offset_table = 1; - - return orig; -} - -/* Set up PIC-specific rtl. This should not cause any insns - to be emitted. */ - -void -initialize_pic () -{ -} - -/* Emit special PIC prologues and epilogues. */ - -void -finalize_pic () -{ - /* The table we use to reference PIC data. */ - rtx global_offset_table; - /* Labels to get the PC in the prologue of this function. */ - rtx l1, l2; - rtx seq; - int orig_flag_pic = flag_pic; - - if (current_function_uses_pic_offset_table == 0) - return; - - if (! flag_pic) - abort (); - - flag_pic = 0; - l1 = gen_label_rtx (); - l2 = gen_label_rtx (); - - start_sequence (); - - emit_label (l1); - /* Note that we pun calls and jumps here! */ - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)), - gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2))))); - emit_label (l2); - - /* Initialize every time through, since we can't easily - know this to be permanent. */ - global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_"); - pic_pc_rtx = gen_rtx (CONST, Pmode, - gen_rtx (MINUS, Pmode, - global_offset_table, - gen_rtx (CONST, Pmode, - gen_rtx (MINUS, Pmode, - gen_rtx (LABEL_REF, VOIDmode, l1), - pc_rtx)))); - - emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx, - gen_rtx (HIGH, Pmode, pic_pc_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, - pic_offset_table_rtx, - gen_rtx (LO_SUM, Pmode, - pic_offset_table_rtx, pic_pc_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, - pic_offset_table_rtx, - gen_rtx (PLUS, Pmode, - pic_offset_table_rtx, gen_rtx (REG, Pmode, 15)))); - /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */ - LABEL_PRESERVE_P (l1) = 1; - LABEL_PRESERVE_P (l2) = 1; - flag_pic = orig_flag_pic; - - seq = gen_sequence (); - end_sequence (); - emit_insn_after (seq, get_insns ()); - - /* Need to emit this whether or not we obey regdecls, - since setjmp/longjmp can cause life info to screw up. */ - emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); -} - -/* For the SPARC, REG and REG+CONST is cost 0, REG+REG is cost 1, - and addresses involving symbolic constants are cost 2. - - We make REG+REG slightly more expensive because it might keep - a register live for longer than we might like. - - PIC addresses are very expensive. - - It is no coincidence that this has the same structure - as GO_IF_LEGITIMATE_ADDRESS. */ -int -sparc_address_cost (X) - rtx X; -{ -#if 0 - /* Handled before calling here. */ - if (GET_CODE (X) == REG) - { return 1; } -#endif - if (GET_CODE (X) == PLUS) - { - if (GET_CODE (XEXP (X, 0)) == REG - && GET_CODE (XEXP (X, 1)) == REG) - return 2; - return 1; - } - else if (GET_CODE (X) == LO_SUM) - return 1; - else if (GET_CODE (X) == HIGH) - return 2; - return 4; -} - -/* Emit insns to move operands[1] into operands[0]. - - Return 1 if we have written out everything that needs to be done to - do the move. Otherwise, return 0 and the caller will emit the move - normally. - - SCRATCH_REG if non zero can be used as a scratch register for the move - operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */ - -int -emit_move_sequence (operands, mode, scratch_reg) - rtx *operands; - enum machine_mode mode; - rtx scratch_reg; -{ - register rtx operand0 = operands[0]; - register rtx operand1 = operands[1]; - - /* Handle most common case first: storing into a register. */ - if (register_operand (operand0, mode)) - { - if (register_operand (operand1, mode) - || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) - || (GET_CODE (operand1) == CONST_DOUBLE - && arith_double_operand (operand1, DImode)) - || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode) - /* Only `general_operands' can come here, so MEM is ok. */ - || GET_CODE (operand1) == MEM) - { - /* Run this case quickly. */ - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - return 1; - } - } - else if (GET_CODE (operand0) == MEM) - { - if (register_operand (operand1, mode) || operand1 == const0_rtx) - { - /* Run this case quickly. */ - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - return 1; - } - if (! reload_in_progress) - { - operands[0] = validize_mem (operand0); - operands[1] = operand1 = force_reg (mode, operand1); - } - } - - /* Simplify the source if we need to. Must handle DImode HIGH operators - here because such a move needs a clobber added. */ - if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) - || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode)) - { - if (flag_pic && symbolic_operand (operand1, mode)) - { - rtx temp_reg = reload_in_progress ? operand0 : 0; - - operands[1] = legitimize_pic_address (operand1, mode, temp_reg, - scratch_reg); - } - else if (GET_CODE (operand1) == CONST_INT - ? (! SMALL_INT (operand1) - && (INTVAL (operand1) & 0x3ff) != 0) - : (GET_CODE (operand1) == CONST_DOUBLE - ? ! arith_double_operand (operand1, DImode) - : 1)) - { - /* For DImode values, temp must be operand0 because of the way - HI and LO_SUM work. The LO_SUM operator only copies half of - the LSW from the dest of the HI operator. If the LO_SUM dest is - not the same as the HI dest, then the MSW of the LO_SUM dest will - never be set. - - ??? The real problem here is that the ...(HI:DImode pattern emits - multiple instructions, and the ...(LO_SUM:DImode pattern emits - one instruction. This fails, because the compiler assumes that - LO_SUM copies all bits of the first operand to its dest. Better - would be to have the HI pattern emit one instruction and the - LO_SUM pattern multiple instructions. Even better would be - to use four rtl insns. */ - rtx temp = ((reload_in_progress || mode == DImode) - ? operand0 : gen_reg_rtx (mode)); - - emit_insn (gen_rtx (SET, VOIDmode, temp, - gen_rtx (HIGH, mode, operand1))); - operands[1] = gen_rtx (LO_SUM, mode, temp, operand1); - } - } - - if (GET_CODE (operand1) == LABEL_REF && flag_pic) - { - /* The procedure for doing this involves using a call instruction to - get the pc into o7. We need to indicate this explicitly because - the tablejump pattern assumes that it can use this value also. */ - emit_insn (gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, - operand1), - gen_rtx (SET, VOIDmode, - gen_rtx (REG, mode, 15), - pc_rtx)))); - return 1; - } - - /* Now have insn-emit do whatever it normally does. */ - return 0; -} - -/* Return the best assembler insn template - for moving operands[1] into operands[0] as a fullword. */ - -char * -singlemove_string (operands) - rtx *operands; -{ - if (GET_CODE (operands[0]) == MEM) - { - if (GET_CODE (operands[1]) != MEM) - return "st %r1,%0"; - else - abort (); - } - else if (GET_CODE (operands[1]) == MEM) - return "ld %1,%0"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - int i; - union real_extract u; - union float_extract { float f; int i; } v; - - /* Must be SFmode, otherwise this doesn't make sense. */ - if (GET_MODE (operands[1]) != SFmode) - abort (); - - bcopy (&CONST_DOUBLE_LOW (operands[1]), &u, sizeof u); - v.f = REAL_VALUE_TRUNCATE (SFmode, u.d); - i = v.i; - - operands[1] = gen_rtx (CONST_INT, VOIDmode, i); - - if (CONST_OK_FOR_LETTER_P (i, 'I')) - return "mov %1,%0"; - else if ((i & 0x000003FF) != 0) - return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; - else - return "sethi %%hi(%a1),%0"; - } - else if (GET_CODE (operands[1]) == CONST_INT - && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) - { - int i = INTVAL (operands[1]); - - /* If all low order 10 bits are clear, then we only need a single - sethi insn to load the constant. */ - if ((i & 0x000003FF) != 0) - return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; - else - return "sethi %%hi(%a1),%0"; - } - /* Operand 1 must be a register, or a 'I' type CONST_INT. */ - return "mov %1,%0"; -} - -/* Return non-zero if it is OK to assume that the given memory operand is - aligned at least to a 8-byte boundary. This should only be called - for memory accesses whose size is 8 bytes or larger. */ - -int -mem_aligned_8 (mem) - register rtx mem; -{ - register rtx addr; - register rtx base; - register rtx offset; - - if (GET_CODE (mem) != MEM) - return 0; /* It's gotta be a MEM! */ - - addr = XEXP (mem, 0); - - /* Now that all misaligned double parms are copied on function entry, - we can assume any 64-bit object is 64-bit aligned except those which - are at unaligned offsets from the stack or frame pointer. If the - TARGET_UNALIGNED_DOUBLES switch is given, we do not make this - assumption. */ - - /* See what register we use in the address. */ - base = 0; - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - { - base = XEXP (addr, 0); - offset = XEXP (addr, 1); - } - } - else if (GET_CODE (addr) == REG) - { - base = addr; - offset = const0_rtx; - } - - /* If it's the stack or frame pointer, check offset alignment. - We can have improper alignment in the function entry code. */ - if (base - && (REGNO (base) == FRAME_POINTER_REGNUM - || REGNO (base) == STACK_POINTER_REGNUM)) - { - if ((INTVAL (offset) & 0x7) == 0) - return 1; - } - /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES - is true, in which case we can only assume that an access is aligned if - it is to an aggregate, it is to a constant address, or the address - involves a LO_SUM. */ - else if (! TARGET_UNALIGNED_DOUBLES || MEM_IN_STRUCT_P (mem) - || CONSTANT_P (addr) || GET_CODE (addr) == LO_SUM) - return 1; - - /* An obviously unaligned address. */ - return 0; -} - -enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }; - -/* Output assembler code to perform a doubleword move insn - with operands OPERANDS. This is very similar to the following - output_move_quad function. */ - -char * -output_move_double (operands) - rtx *operands; -{ - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - register enum optype optype0; - register enum optype optype1; - rtx latehalf[2]; - rtx addreg0 = 0; - rtx addreg1 = 0; - - /* First classify both operands. */ - - if (REG_P (op0)) - optype0 = REGOP; - else if (offsettable_memref_p (op0)) - optype0 = OFFSOP; - else if (GET_CODE (op0) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (op1)) - optype1 = REGOP; - else if (CONSTANT_P (op1)) - optype1 = CNSTOP; - else if (offsettable_memref_p (op1)) - optype1 = OFFSOP; - else if (GET_CODE (op1) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP - || (optype0 == MEM && optype1 == MEM)) - abort (); - - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the second word. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (op0, 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (op1, 0)); - - /* Ok, we can do one word at a time. - Set up in LATEHALF the operands to use for the - high-numbered (least significant) word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ - - if (optype0 == REGOP) - latehalf[0] = gen_rtx (REG, SImode, REGNO (op0) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (op0, 4); - else - latehalf[0] = op0; - - if (optype1 == REGOP) - latehalf[1] = gen_rtx (REG, SImode, REGNO (op1) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (op1, 4); - else if (optype1 == CNSTOP) - split_double (op1, &operands[1], &latehalf[1]); - else - latehalf[1] = op1; - - /* Easy case: try moving both words at once. Check for moving between - an even/odd register pair and a memory location. */ - if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP - && (REGNO (op0) & 1) == 0) - || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP - && (REGNO (op1) & 1) == 0)) - { - register rtx mem; - - if (optype0 == REGOP) - mem = op1; - else - mem = op0; - - if (mem_aligned_8 (mem)) - return (mem == op1 ? "ldd %1,%0" : "std %1,%0"); - } - - /* If the first move would clobber the source of the second one, - do them in the other order. */ - - /* Overlapping registers. */ - if (optype0 == REGOP && optype1 == REGOP - && REGNO (op0) == REGNO (latehalf[1])) - { - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Do low-numbered word. */ - return singlemove_string (operands); - } - /* Loading into a register which overlaps a register used in the address. */ - else if (optype0 == REGOP && optype1 != REGOP - && reg_overlap_mentioned_p (op0, op1)) - { - /* ??? This fails if the address is a double register address, each - of which is clobbered by operand 0. */ - /* Do the late half first. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Then clobber. */ - return singlemove_string (operands); - } - - /* Normal case: do the two words, low-numbered first. */ - - output_asm_insn (singlemove_string (operands), operands); - - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - output_asm_insn ("add %0,-0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,-0x4,%0", &addreg1); - - return ""; -} - -/* Output assembler code to perform a quadword move insn - with operands OPERANDS. This is very similar to the preceding - output_move_double function. */ - -char * -output_move_quad (operands) - rtx *operands; -{ - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - register enum optype optype0; - register enum optype optype1; - rtx wordpart[4][2]; - rtx addreg0 = 0; - rtx addreg1 = 0; - - /* First classify both operands. */ - - if (REG_P (op0)) - optype0 = REGOP; - else if (offsettable_memref_p (op0)) - optype0 = OFFSOP; - else if (GET_CODE (op0) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (op1)) - optype1 = REGOP; - else if (CONSTANT_P (op1)) - optype1 = CNSTOP; - else if (offsettable_memref_p (op1)) - optype1 = OFFSOP; - else if (GET_CODE (op1) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ - - if (optype0 == RNDOP || optype1 == RNDOP - || (optype0 == MEM && optype1 == MEM)) - abort (); - - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the later words. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (op0, 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (op1, 0)); - - /* Ok, we can do one word at a time. - Set up in wordpart the operands to use for each word of the arguments. */ - - if (optype0 == REGOP) - { - wordpart[0][0] = gen_rtx (REG, SImode, REGNO (op0) + 0); - wordpart[1][0] = gen_rtx (REG, SImode, REGNO (op0) + 1); - wordpart[2][0] = gen_rtx (REG, SImode, REGNO (op0) + 2); - wordpart[3][0] = gen_rtx (REG, SImode, REGNO (op0) + 3); - } - else if (optype0 == OFFSOP) - { - wordpart[0][0] = adj_offsettable_operand (op0, 0); - wordpart[1][0] = adj_offsettable_operand (op0, 4); - wordpart[2][0] = adj_offsettable_operand (op0, 8); - wordpart[3][0] = adj_offsettable_operand (op0, 12); - } - else - { - wordpart[0][0] = op0; - wordpart[1][0] = op0; - wordpart[2][0] = op0; - wordpart[3][0] = op0; - } - - if (optype1 == REGOP) - { - wordpart[0][1] = gen_rtx (REG, SImode, REGNO (op1) + 0); - wordpart[1][1] = gen_rtx (REG, SImode, REGNO (op1) + 1); - wordpart[2][1] = gen_rtx (REG, SImode, REGNO (op1) + 2); - wordpart[3][1] = gen_rtx (REG, SImode, REGNO (op1) + 3); - } - else if (optype1 == OFFSOP) - { - wordpart[0][1] = adj_offsettable_operand (op1, 0); - wordpart[1][1] = adj_offsettable_operand (op1, 4); - wordpart[2][1] = adj_offsettable_operand (op1, 8); - wordpart[3][1] = adj_offsettable_operand (op1, 12); - } - else if (optype1 == CNSTOP) - { - /* This case isn't implemented yet, because there is no internal - representation for quad-word constants, and there is no split_quad - function. */ -#if 0 - split_quad (op1, &wordpart[0][1], &wordpart[1][1], - &wordpart[2][1], &wordpart[3][1]); -#else - abort (); -#endif - } - else - { - wordpart[0][1] = op1; - wordpart[1][1] = op1; - wordpart[2][1] = op1; - wordpart[3][1] = op1; - } - - /* Easy case: try moving the quad as two pairs. Check for moving between - an even/odd register pair and a memory location. */ - /* ??? Should also handle the case of non-offsettable addresses here. - We can at least do the first pair as a ldd/std, and then do the third - and fourth words individually. */ - if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0) - || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0)) - { - rtx mem; - - if (optype0 == REGOP) - mem = op1; - else - mem = op0; - - if (mem_aligned_8 (mem)) - { - operands[2] = adj_offsettable_operand (mem, 8); - if (mem == op1) - return "ldd %1,%0;ldd %2,%S0"; - else - return "std %1,%0;std %S1,%2"; - } - } - - /* If the first move would clobber the source of the second one, - do them in the other order. */ - - /* Overlapping registers. */ - if (optype0 == REGOP && optype1 == REGOP - && (REGNO (op0) == REGNO (wordpart[1][3]) - || REGNO (op0) == REGNO (wordpart[1][2]) - || REGNO (op0) == REGNO (wordpart[1][1]))) - { - /* Do fourth word. */ - output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); - /* Do the third word. */ - output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); - /* Do the second word. */ - output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); - /* Do lowest-numbered word. */ - return singlemove_string (wordpart[0]); - } - /* Loading into a register which overlaps a register used in the address. */ - if (optype0 == REGOP && optype1 != REGOP - && reg_overlap_mentioned_p (op0, op1)) - { - /* ??? Not implemented yet. This is a bit complicated, because we - must load which ever part overlaps the address last. If the address - is a double-reg address, then there are two parts which need to - be done last, which is impossible. We would need a scratch register - in that case. */ - abort (); - } - - /* Normal case: move the four words in lowest to higest address order. */ - - output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]); - - /* Make any unoffsettable addresses point at the second word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - - /* Do the second word. */ - output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); - - /* Make any unoffsettable addresses point at the third word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - - /* Do the third word. */ - output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); - - /* Make any unoffsettable addresses point at the fourth word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - - /* Do the fourth word. */ - output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); - - /* Undo the adds we just did. */ - if (addreg0) - output_asm_insn ("add %0,-0xc,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,-0xc,%0", &addreg1); - - return ""; -} - -/* Output assembler code to perform a doubleword move insn with operands - OPERANDS, one of which must be a floating point register. */ - -char * -output_fp_move_double (operands) - rtx *operands; -{ - if (FP_REG_P (operands[0])) - { - if (FP_REG_P (operands[1])) - return "fmovs %1,%0\n\tfmovs %R1,%R0"; - else if (GET_CODE (operands[1]) == REG) - abort (); - else - return output_move_double (operands); - } - else if (FP_REG_P (operands[1])) - { - if (GET_CODE (operands[0]) == REG) - abort (); - else - return output_move_double (operands); - } - else abort (); -} - -/* Output assembler code to perform a quadword move insn with operands - OPERANDS, one of which must be a floating point register. */ - -char * -output_fp_move_quad (operands) - rtx *operands; -{ - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - - if (FP_REG_P (op0)) - { - if (FP_REG_P (op1)) - return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0"; - else if (GET_CODE (op1) == REG) - abort (); - else - return output_move_quad (operands); - } - else if (FP_REG_P (op1)) - { - if (GET_CODE (op0) == REG) - abort (); - else - return output_move_quad (operands); - } - else - abort (); -} - -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. */ - -static rtx -find_addr_reg (addr) - rtx addr; -{ - while (GET_CODE (addr) == PLUS) - { - /* We absolutely can not fudge the frame pointer here, because the - frame pointer must always be 8 byte aligned. It also confuses - debuggers. */ - if (GET_CODE (XEXP (addr, 0)) == REG - && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG - && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - abort (); - } - if (GET_CODE (addr) == REG) - return addr; - abort (); -} - -void -output_sized_memop (opname, mode, signedp) - char *opname; - enum machine_mode mode; - int signedp; -{ - static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" }; - static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" }; - static char *st_size_suffix[] = { "b", "h", "", "?", "d" }; - char **opnametab, *modename; - - if (opname[0] == 'l') - if (signedp) - opnametab = ld_size_suffix_s; - else - opnametab = ld_size_suffix_u; - else - opnametab = st_size_suffix; - modename = opnametab[GET_MODE_SIZE (mode) >> 1]; - - fprintf (asm_out_file, "\t%s%s", opname, modename); -} - -void -output_move_with_extension (operands) - rtx *operands; -{ - if (GET_MODE (operands[2]) == HImode) - output_asm_insn ("sll %2,0x10,%0", operands); - else if (GET_MODE (operands[2]) == QImode) - output_asm_insn ("sll %2,0x18,%0", operands); - else - abort (); -} - -#if 0 -/* ??? These are only used by the movstrsi pattern, but we get better code - in general without that, because emit_block_move can do just as good a - job as this function does when alignment and size are known. When they - aren't known, a call to strcpy may be faster anyways, because it is - likely to be carefully crafted assembly language code, and below we just - do a byte-wise copy. - - Also, emit_block_move expands into multiple read/write RTL insns, which - can then be optimized, whereas our movstrsi pattern can not be optimized - at all. */ - -/* Load the address specified by OPERANDS[3] into the register - specified by OPERANDS[0]. - - OPERANDS[3] may be the result of a sum, hence it could either be: - - (1) CONST - (2) REG - (2) REG + CONST_INT - (3) REG + REG + CONST_INT - (4) REG + REG (special case of 3). - - Note that (3) is not a legitimate address. - All cases are handled here. */ - -void -output_load_address (operands) - rtx *operands; -{ - rtx base, offset; - - if (CONSTANT_P (operands[3])) - { - output_asm_insn ("set %3,%0", operands); - return; - } - - if (REG_P (operands[3])) - { - if (REGNO (operands[0]) != REGNO (operands[3])) - output_asm_insn ("mov %3,%0", operands); - return; - } - - if (GET_CODE (operands[3]) != PLUS) - abort (); - - base = XEXP (operands[3], 0); - offset = XEXP (operands[3], 1); - - if (GET_CODE (base) == CONST_INT) - { - rtx tmp = base; - base = offset; - offset = tmp; - } - - if (GET_CODE (offset) != CONST_INT) - { - /* Operand is (PLUS (REG) (REG)). */ - base = operands[3]; - offset = const0_rtx; - } - - if (REG_P (base)) - { - operands[6] = base; - operands[7] = offset; - if (SMALL_INT (offset)) - output_asm_insn ("add %6,%7,%0", operands); - else - output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands); - } - else if (GET_CODE (base) == PLUS) - { - operands[6] = XEXP (base, 0); - operands[7] = XEXP (base, 1); - operands[8] = offset; - - if (SMALL_INT (offset)) - output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands); - else - output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands); - } - else - abort (); -} - -/* Output code to place a size count SIZE in register REG. - ALIGN is the size of the unit of transfer. - - Because block moves are pipelined, we don't include the - first element in the transfer of SIZE to REG. */ - -static void -output_size_for_block_move (size, reg, align) - rtx size, reg; - rtx align; -{ - rtx xoperands[3]; - - xoperands[0] = reg; - xoperands[1] = size; - xoperands[2] = align; - if (GET_CODE (size) == REG) - output_asm_insn ("sub %1,%2,%0", xoperands); - else - { - xoperands[1] - = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align)); - output_asm_insn ("set %1,%0", xoperands); - } -} - -/* Emit code to perform a block move. - - OPERANDS[0] is the destination. - OPERANDS[1] is the source. - OPERANDS[2] is the size. - OPERANDS[3] is the alignment safe to use. - OPERANDS[4] is a register we can safely clobber as a temp. */ - -char * -output_block_move (operands) - rtx *operands; -{ - /* A vector for our computed operands. Note that load_output_address - makes use of (and can clobber) up to the 8th element of this vector. */ - rtx xoperands[10]; - rtx zoperands[10]; - static int movstrsi_label = 0; - int i; - rtx temp1 = operands[4]; - rtx sizertx = operands[2]; - rtx alignrtx = operands[3]; - int align = INTVAL (alignrtx); - char label3[30], label5[30]; - - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - xoperands[2] = temp1; - - /* We can't move more than this many bytes at a time because we have only - one register, %g1, to move them through. */ - if (align > UNITS_PER_WORD) - { - align = UNITS_PER_WORD; - alignrtx = gen_rtx (CONST_INT, VOIDmode, UNITS_PER_WORD); - } - - /* We consider 8 ld/st pairs, for a total of 16 inline insns to be - reasonable here. (Actually will emit a maximum of 18 inline insns for - the case of size == 31 and align == 4). */ - - if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8 - && memory_address_p (QImode, plus_constant_for_output (xoperands[0], - INTVAL (sizertx))) - && memory_address_p (QImode, plus_constant_for_output (xoperands[1], - INTVAL (sizertx)))) - { - int size = INTVAL (sizertx); - int offset = 0; - - /* We will store different integers into this particular RTX. */ - xoperands[2] = rtx_alloc (CONST_INT); - PUT_MODE (xoperands[2], VOIDmode); - - /* This case is currently not handled. Abort instead of generating - bad code. */ - if (align > 4) - abort (); - - if (align >= 4) - { - for (i = (size >> 2) - 1; i >= 0; i--) - { - INTVAL (xoperands[2]) = (i << 2) + offset; - output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]", - xoperands); - } - offset += (size & ~0x3); - size = size & 0x3; - if (size == 0) - return ""; - } - - if (align >= 2) - { - for (i = (size >> 1) - 1; i >= 0; i--) - { - INTVAL (xoperands[2]) = (i << 1) + offset; - output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]", - xoperands); - } - offset += (size & ~0x1); - size = size & 0x1; - if (size == 0) - return ""; - } - - if (align >= 1) - { - for (i = size - 1; i >= 0; i--) - { - INTVAL (xoperands[2]) = i + offset; - output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]", - xoperands); - } - return ""; - } - - /* We should never reach here. */ - abort (); - } - - /* If the size isn't known to be a multiple of the alignment, - we have to do it in smaller pieces. If we could determine that - the size was a multiple of 2 (or whatever), we could be smarter - about this. */ - if (GET_CODE (sizertx) != CONST_INT) - align = 1; - else - { - int size = INTVAL (sizertx); - while (size % align) - align >>= 1; - } - - if (align != INTVAL (alignrtx)) - alignrtx = gen_rtx (CONST_INT, VOIDmode, align); - - xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); - xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align); - xoperands[5] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); - - ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3])); - ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5])); - - /* This is the size of the transfer. Emit code to decrement the size - value by ALIGN, and store the result in the temp1 register. */ - output_size_for_block_move (sizertx, temp1, alignrtx); - - /* Must handle the case when the size is zero or negative, so the first thing - we do is compare the size against zero, and only copy bytes if it is - zero or greater. Note that we have already subtracted off the alignment - once, so we must copy 1 alignment worth of bytes if the size is zero - here. - - The SUN assembler complains about labels in branch delay slots, so we - do this before outputting the load address, so that there will always - be a harmless insn between the branch here and the next label emitted - below. */ - - { - char pattern[100]; - - sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]); - output_asm_insn (pattern, xoperands); - } - - zoperands[0] = operands[0]; - zoperands[3] = plus_constant_for_output (operands[0], align); - output_load_address (zoperands); - - /* ??? This might be much faster if the loops below were preconditioned - and unrolled. - - That is, at run time, copy enough bytes one at a time to ensure that the - target and source addresses are aligned to the the largest possible - alignment. Then use a preconditioned unrolled loop to copy say 16 - bytes at a time. Then copy bytes one at a time until finish the rest. */ - - /* Output the first label separately, so that it is spaced properly. */ - - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3])); - - { - char pattern[200]; - register char *ld_suffix = (align == 1) ? "ub" : (align == 2) ? "uh" : ""; - register char *st_suffix = (align == 1) ? "b" : (align == 2) ? "h" : ""; - - sprintf (pattern, "ld%s [%%1+%%2],%%%%g1\n\tsubcc %%2,%%4,%%2\n\tbge %s\n\tst%s %%%%g1,[%%0+%%2]\n%s:", ld_suffix, &label3[1], st_suffix, &label5[1]); - output_asm_insn (pattern, xoperands); - } - - return ""; -} -#endif - -/* Output reasonable peephole for set-on-condition-code insns. - Note that these insns assume a particular way of defining - labels. Therefore, *both* sparc.h and this function must - be changed if a new syntax is needed. */ - -char * -output_scc_insn (operands, insn) - rtx operands[]; - rtx insn; -{ - static char string[100]; - rtx label = 0, next = insn; - int need_label = 0; - - /* Try doing a jump optimization which jump.c can't do for us - because we did not expose that setcc works by using branches. - - If this scc insn is followed by an unconditional branch, then have - the jump insn emitted here jump to that location, instead of to - the end of the scc sequence as usual. */ - - do - { - if (GET_CODE (next) == CODE_LABEL) - label = next; - next = NEXT_INSN (next); - if (next == 0) - break; - } - while (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL); - - /* If we are in a sequence, and the following insn is a sequence also, - then just following the current insn's next field will take us to the - first insn of the next sequence, which is the wrong place. We don't - want to optimize with a branch that has had its delay slot filled. - Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next - which fails only if NEXT is such a branch. */ - - if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next) - && (! final_sequence || NEXT_INSN (PREV_INSN (next)) == next)) - label = JUMP_LABEL (next); - /* If not optimizing, jump label fields are not set. To be safe, always - check here to whether label is still zero. */ - if (label == 0) - { - label = gen_label_rtx (); - need_label = 1; - } - - LABEL_NUSES (label) += 1; - - operands[2] = label; - - /* If we are in a delay slot, assume it is the delay slot of an fpcc - insn since our type isn't allowed anywhere else. */ - - /* ??? Fpcc instructions no longer have delay slots, so this code is - probably obsolete. */ - - /* The fastest way to emit code for this is an annulled branch followed - by two move insns. This will take two cycles if the branch is taken, - and three cycles if the branch is not taken. - - However, if we are in the delay slot of another branch, this won't work, - because we can't put a branch in the delay slot of another branch. - The above sequence would effectively take 3 or 4 cycles respectively - since a no op would have be inserted between the two branches. - In this case, we want to emit a move, annulled branch, and then the - second move. This sequence always takes 3 cycles, and hence is faster - when we are in a branch delay slot. */ - - if (final_sequence) - { - strcpy (string, "mov 0,%0\n\t"); - strcat (string, output_cbranch (operands[1], 2, 0, 1, 0)); - strcat (string, "\n\tmov 1,%0"); - } - else - { - strcpy (string, output_cbranch (operands[1], 2, 0, 1, 0)); - strcat (string, "\n\tmov 1,%0\n\tmov 0,%0"); - } - - if (need_label) - strcat (string, "\n%l2:"); - - return string; -} - -/* Vectors to keep interesting information about registers where - it can easily be got. */ - -/* Modes for condition codes. */ -#define C_MODES \ - ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) \ - | (1 << (int) CCFPmode) | (1 << (int) CCFPEmode)) - -/* Modes for single-word (and smaller) quantities. */ -#define S_MODES \ - ((1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \ - | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \ - | (1 << (int) CQImode) | (1 << (int) CHImode)) - -/* Modes for double-word (and smaller) quantities. */ -#define D_MODES \ - (S_MODES | (1 << (int) DImode) | (1 << (int) DFmode) \ - | (1 << (int) CSImode) | (1 << (int) SCmode)) - -/* Modes for quad-word quantities. */ -#define T_MODES \ - (D_MODES | (1 << (int) TImode) | (1 << (int) TFmode) \ - | (1 << (int) DCmode) | (1 << (int) CDImode)) - -/* Modes for single-float quantities. We must allow any single word or - smaller quantity. This is because the fix/float conversion instructions - take integer inputs/outputs from the float registers. */ -#define SF_MODES (S_MODES) - -/* Modes for double-float quantities. */ -#define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode)) - -/* Modes for quad-float quantities. */ -#define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode)) - -/* Value is 1 if register/mode pair is acceptable on sparc. - The funny mixture of D and T modes is because integer operations - do not specially operate on tetra quantities, so non-quad-aligned - registers can hold quadword quantities (except %o4 and %i4 because - they cross fixed registers. */ - -int hard_regno_mode_ok[] = { - C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, - T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, - T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, - T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, - - TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, - TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, - TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, - TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES}; - -#ifdef __GNUC__ -inline -#endif -static int -save_regs (file, low, high, base, offset, n_fregs) - FILE *file; - int low, high; - char *base; - int offset; - int n_fregs; -{ - int i; - - for (i = low; i < high; i += 2) - { - if (regs_ever_live[i] && ! call_used_regs[i]) - if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tstd %s,[%s+%d]\n", - reg_names[i], base, offset + 4 * n_fregs), - n_fregs += 2; - else - fprintf (file, "\tst %s,[%s+%d]\n", - reg_names[i], base, offset + 4 * n_fregs), - n_fregs += 2; - else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tst %s,[%s+%d]\n", - reg_names[i+1], base, offset + 4 * n_fregs), - n_fregs += 2; - } - return n_fregs; -} - -#ifdef __GNUC__ -inline -#endif -static int -restore_regs (file, low, high, base, offset, n_fregs) - FILE *file; - int low, high; - char *base; - int offset; -{ - int i; - - for (i = low; i < high; i += 2) - { - if (regs_ever_live[i] && ! call_used_regs[i]) - if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tldd [%s+%d], %s\n", - base, offset + 4 * n_fregs, reg_names[i]), - n_fregs += 2; - else - fprintf (file, "\tld [%s+%d],%s\n", - base, offset + 4 * n_fregs, reg_names[i]), - n_fregs += 2; - else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tld [%s+%d],%s\n", - base, offset + 4 * n_fregs, reg_names[i+1]), - n_fregs += 2; - } - return n_fregs; -} - -/* Static variables we want to share between prologue and epilogue. */ - -/* Number of live floating point registers needed to be saved. */ -static int num_fregs; - -int -compute_frame_size (size, leaf_function) - int size; - int leaf_function; -{ - int fregs_ever_live = 0; - int n_fregs = 0, i; - int outgoing_args_size = (current_function_outgoing_args_size - + REG_PARM_STACK_SPACE (current_function_decl)); - - apparent_fsize = ((size) + 7 - STARTING_FRAME_OFFSET) & -8; - for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2) - fregs_ever_live |= regs_ever_live[i]|regs_ever_live[i+1]; - - if (TARGET_EPILOGUE && fregs_ever_live) - { - for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2) - if ((regs_ever_live[i] && ! call_used_regs[i]) - || (regs_ever_live[i+1] && ! call_used_regs[i+1])) - n_fregs += 2; - } - - /* Set up values for use in `function_epilogue'. */ - num_fregs = n_fregs; - - apparent_fsize += (outgoing_args_size+7) & -8; - if (leaf_function && n_fregs == 0 - && apparent_fsize == (REG_PARM_STACK_SPACE (current_function_decl) - - STARTING_FRAME_OFFSET)) - apparent_fsize = 0; - - actual_fsize = apparent_fsize + n_fregs*4; - - /* Make sure nothing can clobber our register windows. - If a SAVE must be done, or there is a stack-local variable, - the register window area must be allocated. */ - if (leaf_function == 0 || size > 0) - actual_fsize += (16 * UNITS_PER_WORD)+8; - - return actual_fsize; -} - -/* Output code for the function prologue. */ - -void -output_function_prologue (file, size, leaf_function) - FILE *file; - int size; - int leaf_function; -{ - /* ??? This should be %sp+actual_fsize for a leaf function. I think it - works only because it is never used. */ - if (leaf_function) - frame_base_name = "%sp+80"; - else - frame_base_name = "%fp"; - - /* Need to use actual_fsize, since we are also allocating - space for our callee (and our own register save area). */ - actual_fsize = compute_frame_size (size, leaf_function); - - fprintf (file, "\t!#PROLOGUE# 0\n"); - if (actual_fsize == 0) - /* do nothing. */ ; - else if (actual_fsize <= 4096) - { - if (! leaf_function) - fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); - else - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize); - } - else if (actual_fsize <= 8192) - { - /* For frames in the range 4097..8192, we can use just two insns. */ - if (! leaf_function) - { - fprintf (file, "\tsave %%sp,-4096,%%sp\n"); - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); - } - else - { - fprintf (file, "\tadd %%sp,-4096,%%sp\n"); - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); - } - } - else - { - if (! leaf_function) - { - fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); - if ((actual_fsize & 0x3ff) != 0) - fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize); - fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); - } - else - { - fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); - if ((actual_fsize & 0x3ff) != 0) - fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize); - fprintf (file, "\tadd %%sp,%%g1,%%sp\n"); - } - } - - /* If doing anything with PIC, do it now. */ - if (! flag_pic) - fprintf (file, "\t!#PROLOGUE# 1\n"); - - /* Figure out where to save any special registers. */ - if (num_fregs) - { - int offset, n_fregs = num_fregs; - - /* ??? This should always be -apparent_fsize. */ - if (! leaf_function) - offset = -apparent_fsize; - else - offset = 0; - - if (TARGET_EPILOGUE && ! leaf_function) - n_fregs = save_regs (file, 0, 16, frame_base_name, offset, 0); - else if (leaf_function) - n_fregs = save_regs (file, 0, 32, frame_base_name, offset, 0); - if (TARGET_EPILOGUE) - save_regs (file, 32, FIRST_PSEUDO_REGISTER, - frame_base_name, offset, n_fregs); - } - - leaf_label = 0; - if (leaf_function && actual_fsize != 0) - { - /* warning ("leaf procedure with frame size %d", actual_fsize); */ - if (! TARGET_EPILOGUE) - leaf_label = gen_label_rtx (); - } -} - -/* Output code for the function epilogue. */ - -void -output_function_epilogue (file, size, leaf_function) - FILE *file; - int size; - int leaf_function; -{ - char *ret; - - if (leaf_label) - { - emit_label_after (leaf_label, get_last_insn ()); - final_scan_insn (get_last_insn (), file, 0, 0, 1); - } - - if (num_fregs) - { - int offset, n_fregs = num_fregs; - - /* ??? This should always be -apparent_fsize. */ - if (! leaf_function) - offset = -apparent_fsize; - else - offset = 0; - - if (TARGET_EPILOGUE && ! leaf_function) - n_fregs = restore_regs (file, 0, 16, frame_base_name, offset, 0); - else if (leaf_function) - n_fregs = restore_regs (file, 0, 32, frame_base_name, offset, 0); - if (TARGET_EPILOGUE) - restore_regs (file, 32, FIRST_PSEUDO_REGISTER, - frame_base_name, offset, n_fregs); - } - - /* Work out how to skip the caller's unimp instruction if required. */ - if (leaf_function) - ret = (current_function_returns_struct ? "jmp %o7+12" : "retl"); - else - ret = (current_function_returns_struct ? "jmp %i7+12" : "ret"); - - if (TARGET_EPILOGUE || leaf_label) - { - int old_target_epilogue = TARGET_EPILOGUE; - target_flags &= ~old_target_epilogue; - - if (! leaf_function) - { - /* If we wound up with things in our delay slot, flush them here. */ - if (current_function_epilogue_delay_list) - { - rtx insn = emit_jump_insn_after (gen_rtx (RETURN, VOIDmode), - get_last_insn ()); - PATTERN (insn) = gen_rtx (PARALLEL, VOIDmode, - gen_rtvec (2, - PATTERN (XEXP (current_function_epilogue_delay_list, 0)), - PATTERN (insn))); - final_scan_insn (insn, file, 1, 0, 1); - } - else - fprintf (file, "\t%s\n\trestore\n", ret); - } - /* All of the following cases are for leaf functions. */ - else if (current_function_epilogue_delay_list) - { - /* eligible_for_epilogue_delay_slot ensures that if this is a - leaf function, then we will only have insn in the delay slot - if the frame size is zero, thus no adjust for the stack is - needed here. */ - if (actual_fsize != 0) - abort (); - fprintf (file, "\t%s\n", ret); - final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), - file, 1, 0, 1); - } - /* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to - avoid generating confusing assembly language output. */ - else if (actual_fsize == 0) - fprintf (file, "\t%s\n\tnop\n", ret); - else if (actual_fsize <= 4096) - fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize); - else if (actual_fsize <= 8192) - fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n", - ret, actual_fsize - 4096); - else if ((actual_fsize & 0x3ff) == 0) - fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", - actual_fsize, ret); - else - fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", - actual_fsize, actual_fsize, ret); - target_flags |= old_target_epilogue; - } -} - -/* Do what is necessary for `va_start'. The argument is ignored; - We look at the current function to determine if stdarg or varargs - is used and return the address of the first unnamed parameter. */ - -rtx -sparc_builtin_saveregs (arglist) - tree arglist; -{ - tree fntype = TREE_TYPE (current_function_decl); - int stdarg = (TYPE_ARG_TYPES (fntype) != 0 - && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) - != void_type_node)); - int first_reg = current_function_args_info; - rtx address; - int regno; - -#if 0 /* This code seemed to have no effect except to make - varargs not work right when va_list wasn't the first arg. */ - if (! stdarg) - first_reg = 0; -#endif - - for (regno = first_reg; regno < NPARM_REGS; regno++) - emit_move_insn (gen_rtx (MEM, word_mode, - gen_rtx (PLUS, Pmode, - frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET - + UNITS_PER_WORD * regno))), - gen_rtx (REG, word_mode, BASE_INCOMING_ARG_REG (word_mode) - + regno)); - - address = gen_rtx (PLUS, Pmode, - frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET - + UNITS_PER_WORD * first_reg)); - - return address; -} - -/* Return the string to output a conditional branch to LABEL, which is - the operand number of the label. OP is the conditional expression. The - mode of register 0 says what kind of comparison we made. - - REVERSED is non-zero if we should reverse the sense of the comparison. - - ANNUL is non-zero if we should generate an annulling branch. - - NOOP is non-zero if we have to follow this branch by a noop. */ - -char * -output_cbranch (op, label, reversed, annul, noop) - rtx op; - int label; - int reversed, annul, noop; -{ - static char string[20]; - enum rtx_code code = GET_CODE (op); - enum machine_mode mode = GET_MODE (XEXP (op, 0)); - static char labelno[] = " %lX"; - - /* ??? FP branches can not be preceded by another floating point insn. - Because there is currently no concept of pre-delay slots, we can fix - this only by always emitting a nop before a floating point branch. */ - - if (mode == CCFPmode || mode == CCFPEmode) - strcpy (string, "nop\n\t"); - - /* If not floating-point or if EQ or NE, we can just reverse the code. */ - if (reversed - && ((mode != CCFPmode && mode != CCFPEmode) || code == EQ || code == NE)) - code = reverse_condition (code), reversed = 0; - - /* Start by writing the branch condition. */ - switch (code) - { - case NE: - if (mode == CCFPmode || mode == CCFPEmode) - strcat (string, "fbne"); - else - strcpy (string, "bne"); - break; - - case EQ: - if (mode == CCFPmode || mode == CCFPEmode) - strcat (string, "fbe"); - else - strcpy (string, "be"); - break; - - case GE: - if (mode == CCFPmode || mode == CCFPEmode) - { - if (reversed) - strcat (string, "fbul"); - else - strcat (string, "fbge"); - } - else if (mode == CC_NOOVmode) - strcpy (string, "bpos"); - else - strcpy (string, "bge"); - break; - - case GT: - if (mode == CCFPmode || mode == CCFPEmode) - { - if (reversed) - strcat (string, "fbule"); - else - strcat (string, "fbg"); - } - else - strcpy (string, "bg"); - break; - - case LE: - if (mode == CCFPmode || mode == CCFPEmode) - { - if (reversed) - strcat (string, "fbug"); - else - strcat (string, "fble"); - } - else - strcpy (string, "ble"); - break; - - case LT: - if (mode == CCFPmode || mode == CCFPEmode) - { - if (reversed) - strcat (string, "fbuge"); - else - strcat (string, "fbl"); - } - else if (mode == CC_NOOVmode) - strcpy (string, "bneg"); - else - strcpy (string, "bl"); - break; - - case GEU: - strcpy (string, "bgeu"); - break; - - case GTU: - strcpy (string, "bgu"); - break; - - case LEU: - strcpy (string, "bleu"); - break; - - case LTU: - strcpy (string, "blu"); - break; - } - - /* Now add the annulling, the label, and a possible noop. */ - if (annul) - strcat (string, ",a"); - - labelno[3] = label + '0'; - strcat (string, labelno); - - if (noop) - strcat (string, "\n\tnop"); - - return string; -} - -/* Output assembler code to return from a function. */ - -char * -output_return (operands) - rtx *operands; -{ - if (leaf_label) - { - operands[0] = leaf_label; - return "b,a %l0"; - } - else if (leaf_function) - { - /* If we didn't allocate a frame pointer for the current function, - the stack pointer might have been adjusted. Output code to - restore it now. */ - - operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize); - - /* Use sub of negated value in first two cases instead of add to - allow actual_fsize == 4096. */ - - if (actual_fsize <= 4096) - { - if (current_function_returns_struct) - return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp"; - else - return "retl\n\tsub %%sp,-%0,%%sp"; - } - else if (actual_fsize <= 8192) - { - operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096); - if (current_function_returns_struct) - return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp"; - else - return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp"; - } - else if (current_function_returns_struct) - { - if ((actual_fsize & 0x3ff) != 0) - return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; - else - return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; - } - else - { - if ((actual_fsize & 0x3ff) != 0) - return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; - else - return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; - } - } - else - { - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore"; - else - return "ret\n\trestore"; - } -} - -/* Leaf functions and non-leaf functions have different needs. */ - -static int -reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER; - -static int -reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER; - -static int *reg_alloc_orders[] = { - reg_leaf_alloc_order, - reg_nonleaf_alloc_order}; - -void -order_regs_for_local_alloc () -{ - static int last_order_nonleaf = 1; - - if (regs_ever_live[15] != last_order_nonleaf) - { - last_order_nonleaf = !last_order_nonleaf; - bcopy (reg_alloc_orders[last_order_nonleaf], reg_alloc_order, - FIRST_PSEUDO_REGISTER * sizeof (int)); - } -} - -/* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1. - This makes them candidates for using ldd and std insns. - - Note reg1 and reg2 *must* be hard registers. To be sure we will - abort if we are passed pseudo registers. */ - -int -registers_ok_for_ldd_peep (reg1, reg2) - rtx reg1, reg2; -{ - - /* We might have been passed a SUBREG. */ - if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) - return 0; - - if (REGNO (reg1) % 2 != 0) - return 0; - - return (REGNO (reg1) == REGNO (reg2) - 1); - -} - -/* Return 1 if addr1 and addr2 are suitable for use in an ldd or - std insn. - - This can only happen when addr1 and addr2 are consecutive memory - locations (addr1 + 4 == addr2). addr1 must also be aligned on a - 64 bit boundary (addr1 % 8 == 0). - - We know %sp and %fp are kept aligned on a 64 bit boundary. Other - registers are assumed to *never* be properly aligned and are - rejected. - - Knowing %sp and %fp are kept aligned on a 64 bit boundary, we - need only check that the offset for addr1 % 8 == 0. */ - -int -addrs_ok_for_ldd_peep (addr1, addr2) - rtx addr1, addr2; -{ - int reg1, offset1; - - /* Extract a register number and offset (if used) from the first addr. */ - if (GET_CODE (addr1) == PLUS) - { - /* If not a REG, return zero. */ - if (GET_CODE (XEXP (addr1, 0)) != REG) - return 0; - else - { - reg1 = REGNO (XEXP (addr1, 0)); - /* The offset must be constant! */ - if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) - return 0; - offset1 = INTVAL (XEXP (addr1, 1)); - } - } - else if (GET_CODE (addr1) != REG) - return 0; - else - { - reg1 = REGNO (addr1); - /* This was a simple (mem (reg)) expression. Offset is 0. */ - offset1 = 0; - } - - /* Make sure the second address is a (mem (plus (reg) (const_int). */ - if (GET_CODE (addr2) != PLUS) - return 0; - - if (GET_CODE (XEXP (addr2, 0)) != REG - || GET_CODE (XEXP (addr2, 1)) != CONST_INT) - return 0; - - /* Only %fp and %sp are allowed. Additionally both addresses must - use the same register. */ - if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM) - return 0; - - if (reg1 != REGNO (XEXP (addr2, 0))) - return 0; - - /* The first offset must be evenly divisible by 8 to ensure the - address is 64 bit aligned. */ - if (offset1 % 8 != 0) - return 0; - - /* The offset for the second addr must be 4 more than the first addr. */ - if (INTVAL (XEXP (addr2, 1)) != offset1 + 4) - return 0; - - /* All the tests passed. addr1 and addr2 are valid for ldd and std - instructions. */ - return 1; -} - -/* Return 1 if reg is a pseudo, or is the first register in - a hard register pair. This makes it a candidate for use in - ldd and std insns. */ - -int -register_ok_for_ldd (reg) - rtx reg; -{ - - /* We might have been passed a SUBREG. */ - if (GET_CODE (reg) != REG) - return 0; - - if (REGNO (reg) < FIRST_PSEUDO_REGISTER) - return (REGNO (reg) % 2 == 0); - else - return 1; - -} - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and X is null. */ - -void -print_operand (file, x, code) - FILE *file; - rtx x; - int code; -{ - switch (code) - { - case '#': - /* Output a 'nop' if there's nothing for the delay slot. */ - if (dbr_sequence_length () == 0) - fputs ("\n\tnop", file); - return; - case '*': - /* Output an annul flag if there's nothing for the delay slot and we - are optimizing. This is always used with '(' below. */ - /* Sun OS 4.1.1 dbx can't handle an annulled unconditional branch; - this is a dbx bug. So, we only do this when optimizing. */ - if (dbr_sequence_length () == 0 && optimize) - fputs (",a", file); - return; - case '(': - /* Output a 'nop' if there's nothing for the delay slot and we are - not optimizing. This is always used with '*' above. */ - if (dbr_sequence_length () == 0 && ! optimize) - fputs ("\n\tnop", file); - return; - case 'Y': - /* Adjust the operand to take into account a RESTORE operation. */ - if (GET_CODE (x) != REG) - output_operand_lossage ("Invalid %%Y operand"); - else if (REGNO (x) < 8) - fputs (reg_names[REGNO (x)], file); - else if (REGNO (x) >= 24 && REGNO (x) < 32) - fputs (reg_names[REGNO (x)-16], file); - else - output_operand_lossage ("Invalid %%Y operand"); - return; - case 'R': - /* Print out the second register name of a register pair or quad. - I.e., R (%o0) => %o1. */ - fputs (reg_names[REGNO (x)+1], file); - return; - case 'S': - /* Print out the third register name of a register quad. - I.e., S (%o0) => %o2. */ - fputs (reg_names[REGNO (x)+2], file); - return; - case 'T': - /* Print out the fourth register name of a register quad. - I.e., T (%o0) => %o3. */ - fputs (reg_names[REGNO (x)+3], file); - return; - case 'm': - /* Print the operand's address only. */ - output_address (XEXP (x, 0)); - return; - case 'r': - /* In this case we need a register. Use %g0 if the - operand is const0_rtx. */ - if (x == const0_rtx - || (GET_MODE (x) != VOIDmode && x == CONST0_RTX (GET_MODE (x)))) - { - fputs ("%g0", file); - return; - } - else - break; - - case 'A': - switch (GET_CODE (x)) - { - case IOR: fputs ("or", file); break; - case AND: fputs ("and", file); break; - case XOR: fputs ("xor", file); break; - default: output_operand_lossage ("Invalid %%A operand"); - } - return; - - case 'B': - switch (GET_CODE (x)) - { - case IOR: fputs ("orn", file); break; - case AND: fputs ("andn", file); break; - case XOR: fputs ("xnor", file); break; - default: output_operand_lossage ("Invalid %%B operand"); - } - return; - - case 'b': - { - /* Print a sign-extended character. */ - int i = INTVAL (x) & 0xff; - if (i & 0x80) - i |= 0xffffff00; - fprintf (file, "%d", i); - return; - } - - case 0: - /* Do nothing special. */ - break; - - default: - /* Undocumented flag. */ - output_operand_lossage ("invalid operand output code"); - } - - if (GET_CODE (x) == REG) - fputs (reg_names[REGNO (x)], file); - else if (GET_CODE (x) == MEM) - { - fputc ('[', file); - if (CONSTANT_P (XEXP (x, 0))) - /* Poor Sun assembler doesn't understand absolute addressing. */ - fputs ("%g0+", file); - output_address (XEXP (x, 0)); - fputc (']', file); - } - else if (GET_CODE (x) == HIGH) - { - fputs ("%hi(", file); - output_addr_const (file, XEXP (x, 0)); - fputc (')', file); - } - else if (GET_CODE (x) == LO_SUM) - { - print_operand (file, XEXP (x, 0), 0); - fputs ("+%lo(", file); - output_addr_const (file, XEXP (x, 1)); - fputc (')', file); - } - else if (GET_CODE (x) == CONST_DOUBLE - && (GET_MODE (x) == VOIDmode - || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)) - { - if (CONST_DOUBLE_HIGH (x) == 0) - fprintf (file, "%u", CONST_DOUBLE_LOW (x)); - else if (CONST_DOUBLE_HIGH (x) == -1 - && CONST_DOUBLE_LOW (x) < 0) - fprintf (file, "%d", CONST_DOUBLE_LOW (x)); - else - output_operand_lossage ("long long constant not a valid immediate operand"); - } - else if (GET_CODE (x) == CONST_DOUBLE) - output_operand_lossage ("floating point constant not a valid immediate operand"); - else { output_addr_const (file, x); } -} - -/* This function outputs assembler code for VALUE to FILE, where VALUE is - a 64 bit (DImode) value. */ - -/* ??? If there is a 64 bit counterpart to .word that the assembler - understands, then using that would simply this code greatly. */ - -void -output_double_int (file, value) - FILE *file; - rtx value; -{ - if (GET_CODE (value) == CONST_INT) - { - if (INTVAL (value) < 0) - ASM_OUTPUT_INT (file, constm1_rtx); - else - ASM_OUTPUT_INT (file, const0_rtx); - ASM_OUTPUT_INT (file, value); - } - else if (GET_CODE (value) == CONST_DOUBLE) - { - ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_HIGH (value))); - ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (value))); - } - else if (GET_CODE (value) == SYMBOL_REF - || GET_CODE (value) == CONST - || GET_CODE (value) == PLUS) - { - /* Addresses are only 32 bits. */ - ASM_OUTPUT_INT (file, const0_rtx); - ASM_OUTPUT_INT (file, value); - } - else - abort (); -} - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2) -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -unsigned long -sparc_type_code (type) - register tree type; -{ - register unsigned long qualifiers = 0; - register unsigned shift = 6; - - for (;;) - { - switch (TREE_CODE (type)) - { - case ERROR_MARK: - return qualifiers; - - case ARRAY_TYPE: - qualifiers |= (3 << shift); - shift += 2; - type = TREE_TYPE (type); - break; - - case FUNCTION_TYPE: - case METHOD_TYPE: - qualifiers |= (2 << shift); - shift += 2; - type = TREE_TYPE (type); - break; - - case POINTER_TYPE: - case REFERENCE_TYPE: - case OFFSET_TYPE: - qualifiers |= (1 << shift); - shift += 2; - type = TREE_TYPE (type); - break; - - case RECORD_TYPE: - return (qualifiers | 8); - - case UNION_TYPE: - return (qualifiers | 9); - - case ENUMERAL_TYPE: - return (qualifiers | 10); - - case VOID_TYPE: - return (qualifiers | 16); - - case INTEGER_TYPE: - /* Carefully distinguish all the standard types of C, - without messing up if the language is not C. - Note that we check only for the names that contain spaces; - other names might occur by coincidence in other languages. */ - if (TYPE_NAME (type) != 0 - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) != 0 - && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - - if (!strcmp (name, "unsigned char")) - return (qualifiers | 12); - if (!strcmp (name, "signed char")) - return (qualifiers | 2); - if (!strcmp (name, "unsigned int")) - return (qualifiers | 14); - if (!strcmp (name, "short int")) - return (qualifiers | 3); - if (!strcmp (name, "short unsigned int")) - return (qualifiers | 13); - if (!strcmp (name, "long int")) - return (qualifiers | 5); - if (!strcmp (name, "long unsigned int")) - return (qualifiers | 15); - if (!strcmp (name, "long long int")) - return (qualifiers | 5); /* Who knows? */ - if (!strcmp (name, "long long unsigned int")) - return (qualifiers | 15); /* Who knows? */ - } - - /* Most integer types will be sorted out above, however, for the - sake of special `array index' integer types, the following code - is also provided. */ - - if (TYPE_PRECISION (type) == INT_TYPE_SIZE) - return (qualifiers | (TREE_UNSIGNED (type) ? 14 : 4)); - - if (TYPE_PRECISION (type) == LONG_TYPE_SIZE) - return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5)); - - if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE) - return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5)); - - if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE) - return (qualifiers | (TREE_UNSIGNED (type) ? 13 : 3)); - - if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE) - return (qualifiers | (TREE_UNSIGNED (type) ? 12 : 2)); - - abort (); - - case REAL_TYPE: - /* Carefully distinguish all the standard types of C, - without messing up if the language is not C. */ - if (TYPE_NAME (type) != 0 - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) != 0 - && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - - if (!strcmp (name, "long double")) - return (qualifiers | 7); /* Who knows? */ - } - - if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE) - return (qualifiers | 7); - if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE) - return (qualifiers | 6); - if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE) - return (qualifiers | 7); /* Who knows? */ - abort (); - - case COMPLEX_TYPE: /* GNU Fortran COMPLEX type. */ - /* ??? We need to distinguish between double and float complex types, - but I don't know how yet because I can't reach this code from - existing front-ends. */ - return (qualifiers | 7); /* Who knows? */ - - case CHAR_TYPE: /* GNU Pascal CHAR type. Not used in C. */ - case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */ - case FILE_TYPE: /* GNU Pascal FILE type. */ - case STRING_TYPE: /* GNU Fortran STRING type. */ - case LANG_TYPE: /* ? */ - abort (); - - default: - abort (); /* Not a type! */ - } - } -} - -/* Subroutines to support a flat (single) register window calling - convention. */ - -/* Single-register window sparc stack frames look like: - - Before call After call - +-----------------------+ +-----------------------+ - high | | | | - mem. | | | | - | caller's temps. | | caller's temps. | - | | | | - +-----------------------+ +-----------------------+ - | | | | - | arguments on stack. | | arguments on stack. | - | |FP+92->| | - +-----------------------+ +-----------------------+ - | 6 words to save | | 6 words to save | - | arguments passed | | arguments passed | - | in registers, even | | in registers, even | - SP+68->| if not passed. |FP+68->| if not passed. | - +-----------------------+ +-----------------------+ - | 1 word struct addr |FP+64->| 1 word struct addr | - +-----------------------+ +-----------------------+ - | | | | - | 16 word reg save area | | 16 word reg save area | - SP->| | FP->| | - +-----------------------+ +-----------------------+ - | 4 word area for | - FP-16->| fp/alu reg moves | - +-----------------------+ - | | - | local variables | - | | - +-----------------------+ - | | - | fp register save | - | | - +-----------------------+ - | | - | gp register save | - | | - +-----------------------+ - | | - | alloca allocations | - | | - +-----------------------+ - | | - | arguments on stack | - SP+92->| | - +-----------------------+ - | 6 words to save | - | arguments passed | - | in registers, even | - low SP+68->| if not passed. | - memory +-----------------------+ - SP+64->| 1 word struct addr | - +-----------------------+ - | | - I 16 word reg save area | - SP->| | - +-----------------------+ */ - -/* Structure to be filled in by sparc_frw_compute_frame_size with register - save masks, and offsets for the current function. */ - -struct sparc_frame_info -{ - unsigned long total_size; /* # bytes that the entire frame takes up. */ - unsigned long var_size; /* # bytes that variables take up. */ - unsigned long args_size; /* # bytes that outgoing arguments take up. */ - unsigned long extra_size; /* # bytes of extra gunk. */ - unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ - unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ - unsigned long mask; /* Mask of saved gp registers. */ - unsigned long fmask; /* Mask of saved fp registers. */ - unsigned long gp_sp_offset; /* Offset from new sp to store gp regs. */ - unsigned long fp_sp_offset; /* Offset from new sp to store fp regs. */ - int initialized; /* Nonzero if frame size already calculated. */ -}; - -/* Current frame information calculated by sparc_frw_compute_frame_size. */ -struct sparc_frame_info current_frame_info; - -/* Zero structure to initialize current_frame_info. */ -struct sparc_frame_info zero_frame_info; - -/* Tell prologue and epilogue if register REGNO should be saved / restored. */ - -#define MUST_SAVE_REGISTER(regno) \ - ((regs_ever_live[regno] && !call_used_regs[regno]) \ - || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \ - || (regno == 15 && regs_ever_live[15])) - -/* Return the bytes needed to compute the frame pointer from the current - stack pointer. */ - -unsigned long -sparc_frw_compute_frame_size (size) - int size; /* # of var. bytes allocated. */ -{ - int regno; - unsigned long total_size; /* # bytes that the entire frame takes up. */ - unsigned long var_size; /* # bytes that variables take up. */ - unsigned long args_size; /* # bytes that outgoing arguments take up. */ - unsigned long extra_size; /* # extra bytes. */ - unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ - unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ - unsigned long mask; /* Mask of saved gp registers. */ - unsigned long fmask; /* Mask of saved fp registers. */ - - /* This is the size of the 16 word reg save area, 1 word struct addr - area, and 4 word fp/alu register copy area. */ - extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0); - var_size = size; - /* Also include the size needed for the 6 parameter registers. */ - args_size = current_function_outgoing_args_size + 24; - total_size = var_size + args_size + extra_size; - gp_reg_size = 0; - fp_reg_size = 0; - mask = 0; - fmask = 0; - - /* Calculate space needed for gp registers. */ - for (regno = 1; regno <= 31; regno++) - { - if (MUST_SAVE_REGISTER (regno)) - { - if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1)) - { - if (gp_reg_size % 8 != 0) - gp_reg_size += UNITS_PER_WORD; - gp_reg_size += 2 * UNITS_PER_WORD; - mask |= 3 << regno; - regno++; - } - else - { - gp_reg_size += UNITS_PER_WORD; - mask |= 1 << regno; - } - } - } - /* Add extra word in case we have to align the space to a double word - boundary. */ - if (gp_reg_size != 0) - gp_reg_size += UNITS_PER_WORD; - - /* Calculate space needed for fp registers. */ - for (regno = 32; regno <= 63; regno++) - { - if (regs_ever_live[regno] && !call_used_regs[regno]) - { - fp_reg_size += UNITS_PER_WORD; - fmask |= 1 << (regno - 32); - } - } - - total_size += gp_reg_size + fp_reg_size; - - if (total_size == extra_size) - total_size = extra_size = 0; - - total_size = SPARC_STACK_ALIGN (total_size); - - /* Save other computed information. */ - current_frame_info.total_size = total_size; - current_frame_info.var_size = var_size; - current_frame_info.args_size = args_size; - current_frame_info.extra_size = extra_size; - current_frame_info.gp_reg_size = gp_reg_size; - current_frame_info.fp_reg_size = fp_reg_size; - current_frame_info.mask = mask; - current_frame_info.fmask = fmask; - current_frame_info.initialized = reload_completed; - - if (mask) - { - unsigned long offset = args_size; - if (extra_size) - offset += FIRST_PARM_OFFSET(0); - current_frame_info.gp_sp_offset = offset; - } - - if (fmask) - { - unsigned long offset = args_size + gp_reg_size; - if (extra_size) - offset += FIRST_PARM_OFFSET(0); - current_frame_info.fp_sp_offset = offset; - } - - /* Ok, we're done. */ - return total_size; -} - -/* Common code to save/restore registers. */ - -void -sparc_frw_save_restore (file, word_op, doubleword_op) - FILE *file; /* Stream to write to. */ - char *word_op; /* Operation to do for one word. */ - char *doubleword_op; /* Operation to do for doubleword. */ -{ - int regno; - unsigned long mask = current_frame_info.mask; - unsigned long fmask = current_frame_info.fmask; - unsigned long gp_offset; - unsigned long fp_offset; - unsigned long max_offset; - char *base_reg; - - if (mask == 0 && fmask == 0) - return; - - base_reg = reg_names[STACK_POINTER_REGNUM]; - gp_offset = current_frame_info.gp_sp_offset; - fp_offset = current_frame_info.fp_sp_offset; - max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset; - - /* Deal with calling functions with a large structure. */ - if (max_offset >= 4096) - { - char *temp = "%g2"; - fprintf (file, "\tset %ld,%s\n", max_offset, temp); - fprintf (file, "\tadd %s,%s,%s\n", temp, base_reg, temp); - base_reg = temp; - gp_offset = max_offset - gp_offset; - fp_offset = max_offset - fp_offset; - } - - /* Save registers starting from high to low. The debuggers prefer - at least the return register be stored at func+4, and also it - allows us not to need a nop in the epilog if at least one - register is reloaded in addition to return address. */ - - if (mask || frame_pointer_needed) - { - for (regno = 1; regno <= 31; regno++) - { - if ((mask & (1L << regno)) != 0 - || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) - { - if ((regno & 0x1) == 0 && ((mask & (1L << regno+1)) != 0)) - { - if (gp_offset % 8 != 0) - gp_offset += UNITS_PER_WORD; - - if (word_op[0] == 's') - fprintf (file, "\t%s %s,[%s+%d]\n", - doubleword_op, reg_names[regno], - base_reg, gp_offset); - else - fprintf (file, "\t%s [%s+%d],%s\n", - doubleword_op, base_reg, gp_offset, - reg_names[regno]); - - gp_offset += 2 * UNITS_PER_WORD; - regno++; - } - else - { - if (word_op[0] == 's') - fprintf (file, "\t%s %s,[%s+%d]\n", - word_op, reg_names[regno], - base_reg, gp_offset); - else - fprintf (file, "\t%s [%s+%d],%s\n", - word_op, base_reg, gp_offset, reg_names[regno]); - - gp_offset += UNITS_PER_WORD; - } - } - } - } - - if (fmask) - { - for (regno = 32; regno <= 63; regno++) - { - if ((fmask & (1L << (regno - 32))) != 0) - { - if (word_op[0] == 's') - fprintf (file, "\t%s %s,[%s+%d]\n", - word_op, reg_names[regno], - base_reg, gp_offset); - else - fprintf (file, "\t%s [%s+%d],%s\n", - word_op, base_reg, gp_offset, reg_names[regno]); - - fp_offset += UNITS_PER_WORD; - } - } - } -} - -/* Set up the stack and frame (if desired) for the function. */ - -void -sparc_frw_output_function_prologue (file, size, ignored) - FILE *file; - int size; -{ - extern char call_used_regs[]; - int tsize; - char *sp_str = reg_names[STACK_POINTER_REGNUM]; - - /* ??? This should be %sp+actual_fsize for a leaf function. I think it - works only because it is never used. */ - frame_base_name - = (!frame_pointer_needed) ? "%sp+80" : reg_names[FRAME_POINTER_REGNUM]; - - fprintf (file, "\t!#PROLOGUE# 0\n"); - - size = SPARC_STACK_ALIGN (size); - tsize = (! current_frame_info.initialized - ? sparc_frw_compute_frame_size (size) - : current_frame_info.total_size); - - if (tsize > 0) - { - if (tsize <= 4095) - fprintf (file, - "\tsub %s,%d,%s\t\t!# vars= %d, regs= %d/%d, args = %d, extra= %d\n", - sp_str, tsize, sp_str, current_frame_info.var_size, - current_frame_info.gp_reg_size / 4, - current_frame_info.fp_reg_size / 8, - current_function_outgoing_args_size, - current_frame_info.extra_size); - else - fprintf (file, - "\tset %d,%s\n\tsub\t%s,%s,%s\t\t!# vars= %d, regs= %d/%d, args = %d, sfo= %d\n", - tsize, "%g1", sp_str, "%g1", - sp_str, current_frame_info.var_size, - current_frame_info.gp_reg_size / 4, - current_frame_info.fp_reg_size / 8, - current_function_outgoing_args_size, - current_frame_info.extra_size); - } - - sparc_frw_save_restore (file, "st", "std"); - - if (frame_pointer_needed) - { - if (tsize <= 4095) - fprintf (file, "\tadd %s,%d,%s\t!# set up frame pointer\n", sp_str, - tsize, frame_base_name); - else - fprintf (file, "\tadd %s,%s,%s\t!# set up frame pointer\n", sp_str, - "%g1", frame_base_name); - } -} - -/* Do any necessary cleanup after a function to restore stack, frame, - and regs. */ - -void -sparc_frw_output_function_epilogue (file, size, ignored1, ignored2) - FILE *file; - int size; -{ - extern FILE *asm_out_data_file, *asm_out_file; - extern char call_used_regs[]; - extern int frame_pointer_needed; - int tsize; - char *sp_str = reg_names[STACK_POINTER_REGNUM]; - char *t1_str = "%g1"; - rtx epilogue_delay = current_function_epilogue_delay_list; - int noepilogue = FALSE; - - /* The epilogue does not depend on any registers, but the stack - registers, so we assume that if we have 1 pending nop, it can be - ignored, and 2 it must be filled (2 nops occur for integer - multiply and divide). */ - - size = SPARC_STACK_ALIGN (size); - tsize = (!current_frame_info.initialized - ? sparc_frw_compute_frame_size (size) - : current_frame_info.total_size); - - if (tsize == 0 && epilogue_delay == 0) - { - rtx insn = get_last_insn (); - - /* If the last insn was a BARRIER, we don't have to write any code - because a jump (aka return) was put there. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn && GET_CODE (insn) == BARRIER) - noepilogue = TRUE; - } - - if (!noepilogue) - { - /* In the reload sequence, we don't need to fill the load delay - slots for most of the loads, also see if we can fill the final - delay slot if not otherwise filled by the reload sequence. */ - - if (tsize > 4095) - fprintf (file, "\tset %d,%s\n", tsize, t1_str); - - if (frame_pointer_needed) - { - char *fp_str = reg_names[FRAME_POINTER_REGNUM]; - if (tsize > 4095) - fprintf (file,"\tsub %s,%s,%s\t\t!# sp not trusted here\n", - fp_str, t1_str, sp_str); - else - fprintf (file,"\tsub %s,%d,%s\t\t!# sp not trusted here\n", - fp_str, tsize, sp_str); - } - - sparc_frw_save_restore (file, "ld", "ldd"); - - if (current_function_returns_struct) - fprintf (file, "\tjmp %%o7+12\n"); - else - fprintf (file, "\tretl\n"); - - /* If the only register saved is the return address, we need a - nop, unless we have an instruction to put into it. Otherwise - we don't since reloading multiple registers doesn't reference - the register being loaded. */ - - if (epilogue_delay) - { - if (tsize) - abort (); - final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1); - } - - else if (tsize > 4095) - fprintf (file, "\tadd %s,%s,%s\n", sp_str, t1_str, sp_str); - - else if (tsize > 0) - fprintf (file, "\tadd %s,%d,%s\n", sp_str, tsize, sp_str); - - else - fprintf (file, "\tnop\n"); - } - - /* Reset state info for each function. */ - current_frame_info = zero_frame_info; -} - -/* Define the number of delay slots needed for the function epilogue. - - On the sparc, we need a slot if either no stack has been allocated, - or the only register saved is the return register. */ - -int -sparc_frw_epilogue_delay_slots () -{ - if (!current_frame_info.initialized) - (void) sparc_frw_compute_frame_size (get_frame_size ()); - - if (current_frame_info.total_size == 0) - return 1; - - return 0; -} - -/* Return true is TRIAL is a valid insn for the epilogue delay slot. - Any single length instruction which doesn't reference the stack or frame - pointer is OK. */ - -int -sparc_frw_eligible_for_epilogue_delay (trial, slot) - rtx trial; - int slot; -{ - if (get_attr_length (trial) == 1 - && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial)) - && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial))) - return 1; - return 0; -} diff --git a/gnu/usr.bin/gcc2/arch/sparc/config.h b/gnu/usr.bin/gcc2/arch/sparc/config.h deleted file mode 100644 index 5056c6add9e..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Configuration for GNU C-compiler for Sun Sparc. - Copyright (C) 1988 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com). - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Doubles are stored in memory with the high order word first. This - matters when cross-compiling. */ -#define HOST_WORDS_BIG_ENDIAN 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If compiled with Sun CC, the use of alloca requires this #include. */ -#ifndef __GNUC__ -#include "alloca.h" -#endif - -/* If compiled with GNU C, use the built-in alloca. */ -#ifdef __GNUC__ -/* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ -#define alloca(x) __builtin_alloca(x) -#endif diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-attr.h b/gnu/usr.bin/gcc2/arch/sparc/insn-attr.h deleted file mode 100644 index c491dff7818..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-attr.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Generated automatically by the program `genattr' -from the machine description file `md'. */ - -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif -#define HAVE_ATTR_alternative -#define get_attr_alternative(insn) which_alternative -#define HAVE_ATTR_type -enum attr_type {TYPE_MOVE, TYPE_UNARY, TYPE_BINARY, TYPE_COMPARE, TYPE_LOAD, TYPE_STORE, TYPE_UNCOND_BRANCH, TYPE_BRANCH, TYPE_CALL, TYPE_CALL_NO_DELAY_SLOT, TYPE_ADDRESS, TYPE_FPLOAD, TYPE_FPSTORE, TYPE_FP, TYPE_FPCMP, TYPE_FPMUL, TYPE_FPDIV, TYPE_FPSQRT, TYPE_MULTI, TYPE_MISC}; -extern enum attr_type get_attr_type (); - -#define HAVE_ATTR_use_clobbered -enum attr_use_clobbered {USE_CLOBBERED_FALSE, USE_CLOBBERED_TRUE}; -extern enum attr_use_clobbered get_attr_use_clobbered (); - -#define HAVE_ATTR_length -extern int get_attr_length (); -extern void init_lengths (); -extern void shorten_branches PROTO((rtx)); -extern int insn_default_length PROTO((rtx)); -extern int insn_variable_length_p PROTO((rtx)); -extern int insn_current_length PROTO((rtx)); - -extern int *insn_addresses; -extern int insn_current_address; - -#define HAVE_ATTR_in_call_delay -enum attr_in_call_delay {IN_CALL_DELAY_FALSE, IN_CALL_DELAY_TRUE}; -extern enum attr_in_call_delay get_attr_in_call_delay (); - -#define DELAY_SLOTS -extern int num_delay_slots PROTO((rtx)); -extern int eligible_for_delay PROTO((rtx, int, rtx, int)); - -extern int const_num_delay_slots PROTO((rtx)); - -#define HAVE_ATTR_in_branch_delay -enum attr_in_branch_delay {IN_BRANCH_DELAY_FALSE, IN_BRANCH_DELAY_TRUE}; -extern enum attr_in_branch_delay get_attr_in_branch_delay (); - -#define HAVE_ATTR_in_uncond_branch_delay -enum attr_in_uncond_branch_delay {IN_UNCOND_BRANCH_DELAY_FALSE, IN_UNCOND_BRANCH_DELAY_TRUE}; -extern enum attr_in_uncond_branch_delay get_attr_in_uncond_branch_delay (); - -#define HAVE_ATTR_in_annul_branch_delay -enum attr_in_annul_branch_delay {IN_ANNUL_BRANCH_DELAY_FALSE, IN_ANNUL_BRANCH_DELAY_TRUE}; -extern enum attr_in_annul_branch_delay get_attr_in_annul_branch_delay (); - -#define ANNUL_IFFALSE_SLOTS -extern int eligible_for_annul_false (); -#define INSN_SCHEDULING - -extern int result_ready_cost PROTO((rtx)); -extern int function_units_used PROTO((rtx)); - -extern struct function_unit_desc -{ - char *name; - int bitmask; - int multiplicity; - int simultaneity; - int default_cost; - int max_issue_delay; - int (*ready_cost_function) (); - int (*conflict_cost_function) (); - int max_blockage; - unsigned int (*blockage_range_function) (); - int (*blockage_function) (); -} function_units[]; - -#define FUNCTION_UNITS_SIZE 3 -#define MIN_MULTIPLICITY 1 -#define MAX_MULTIPLICITY 1 -#define MIN_SIMULTANEITY 1 -#define MAX_SIMULTANEITY 1 -#define MIN_READY_COST 2 -#define MAX_READY_COST 63 -#define MIN_ISSUE_DELAY 1 -#define MAX_ISSUE_DELAY 1 -#define MIN_BLOCKAGE 2 -#define MAX_BLOCKAGE 63 -#define BLOCKAGE_BITS 7 -#define INSN_QUEUE_SIZE 64 - -#define ATTR_FLAG_forward 0x1 -#define ATTR_FLAG_backward 0x2 -#define ATTR_FLAG_likely 0x4 -#define ATTR_FLAG_very_likely 0x8 -#define ATTR_FLAG_unlikely 0x10 -#define ATTR_FLAG_very_unlikely 0x20 diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-attrtab.c b/gnu/usr.bin/gcc2/arch/sparc/insn-attrtab.c deleted file mode 100644 index ffc257cedc8..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-attrtab.c +++ /dev/null @@ -1,3812 +0,0 @@ -/* Generated automatically by the program `genattrtab' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "regs.h" -#include "real.h" -#include "output.h" -#include "insn-attr.h" - -#define operands recog_operand - -int -insn_current_length (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } -} - -int -insn_variable_length_p (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } -} - -int -insn_default_length (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (symbolic_memory_operand (operands[1], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 1) - { - if (symbolic_memory_operand (operands[1], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else if (which_alternative != 0) - { - if (symbolic_memory_operand (operands[0], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else - { - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 2; - } - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 3) || (which_alternative == 2)) - { - if (symbolic_memory_operand (operands[1], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else if ((which_alternative != 0) && (which_alternative != 1)) - { - if (symbolic_memory_operand (operands[0], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else if (which_alternative == 1) - { - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 2; - } - } - else - { - return 1; - } - - case 89: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 2; - } - else if ((which_alternative == 1) || ((which_alternative == 2) || (which_alternative == 3))) - { - return 3; - } - else if (which_alternative == 4) - { - return 2; - } - else if (which_alternative == 5) - { - return 3; - } - else - { - return 3; - } - - case 85: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else if (which_alternative == 2) - { - return 2; - } - else if (which_alternative == 3) - { - return 3; - } - else - { - return 3; - } - - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else if ((which_alternative == 2) || (which_alternative == 3)) - { - return 2; - } - else if ((which_alternative == 4) || ((which_alternative == 5) || (which_alternative == 6))) - { - return 3; - } - else - { - return 3; - } - - case 79: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 4; - } - else if ((which_alternative == 2) || ((which_alternative == 3) || (which_alternative == 4))) - { - return 5; - } - else - { - return 5; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 2; - } - } - else if (which_alternative == 1) - { - return 1; - } - else if (which_alternative == 2) - { - if (symbolic_memory_operand (operands[1], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else - { - return 1; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - if ((which_alternative == 0) || (which_alternative == 2)) - { - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 2; - } - } - else - { - return 1; - } - } - else if (which_alternative == 2) - { - return 1; - } - else - { - if ((which_alternative == 3) || (which_alternative == 4)) - { - if (symbolic_memory_operand (operands[1], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - else - { - if (symbolic_memory_operand (operands[0], VOIDmode)) - { - return 2; - } - else - { - return 1; - } - } - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return 1; - } - else - { - return 3; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 2; - } - - case 232: - return 8; - - case 267: - case 266: - case 265: - case 264: - case 263: - case 262: - case 226: - case 225: - case 223: - case 231: - case 211: - case 206: - case 174: - case 169: - case 161: - case 157: - case 154: - case 151: - case 148: - case 145: - case 139: - case 138: - case 136: - case 135: - case 128: - case 124: - case 94: - case 76: - case 72: - case 68: - case 61: - case 30: - case 29: - case 28: - case 27: - case 26: - case 25: - case 24: - case 23: - return 2; - - case 210: - case 205: - case 60: - return 4; - - case 202: - case 143: - case 142: - case 81: - case 77: - return 5; - - case 196: - case 193: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 2; - } - - case 195: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 4; - } - - case 141: - case 140: - return 6; - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 2; - } - else if (which_alternative == 1) - { - return 1; - } - else - { - return 1; - } - - case 87: - case 82: - case 44: - return 3; - - case 80: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 4; - } - else if (which_alternative == 1) - { - return 5; - } - else - { - return 5; - } - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 1; - - } -} - -int -result_ready_cost (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 200: - case 199: - case 198: - return 63 /* 0x3f */; - - case 191: - case 190: - case 189: - return 37 /* 0x25 */; - - case 188: - case 187: - case 186: - case 185: - case 184: - return 7; - - case 197: - case 196: - case 195: - case 194: - case 193: - case 192: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - return 5; - - case 100: - case 98: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 2; - } - else - { - return 1; - } - - case 110: - case 108: - case 106: - case 96: - return 2; - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 1) - { - return 2; - } - else - { - return 1; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 5; - } - else if ((which_alternative == 3) || (which_alternative == 2)) - { - return 2; - } - else - { - return 1; - } - - case 89: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 4) - { - return 5; - } - else if ((which_alternative == 2) || (which_alternative == 5)) - { - return 2; - } - else - { - return 1; - } - - case 85: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative != 0) && ((which_alternative != 2) && (which_alternative != 3))) - { - return 2; - } - else - { - return 1; - } - - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 2) - { - return 5; - } - else if ((which_alternative == 7) || ((which_alternative == 1) || (which_alternative == 6))) - { - return 2; - } - else - { - return 1; - } - - case 80: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative != 0) && (which_alternative != 1)) - { - return 2; - } - else - { - return 1; - } - - case 79: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 5; - } - else if ((which_alternative != 1) && ((which_alternative != 2) && (which_alternative != 3))) - { - return 2; - } - else - { - return 1; - } - - case 90: - case 82: - case 77: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 2; - } - else - { - return 1; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 2) - { - return 2; - } - else - { - return 1; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 1) - { - return 5; - } - else if ((which_alternative == 3) || (which_alternative == 4)) - { - return 2; - } - else - { - return 1; - } - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 1; - - } -} - -int -fp_mds_unit_ready_cost (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 191: - case 190: - case 189: - return 37 /* 0x25 */; - - case 188: - case 187: - case 186: - case 185: - case 184: - return 7; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 63 /* 0x3f */; - - } -} - -unsigned int -fp_mds_unit_blockage_range (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 191: - case 190: - case 189: - return 2424869 /* 0x250025 */; - - case 188: - case 187: - case 186: - case 185: - case 184: - return 458759 /* 0x70007 */; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 4128831 /* 0x3f003f */; - - } -} - -int -fp_alu_unit_ready_cost (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 5; - - } -} - -int -memory_unit_ready_cost (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 2; - - } -} - -int -function_units_used (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 200: - case 199: - case 198: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - return 2; - - case 197: - case 196: - case 195: - case 194: - case 193: - case 192: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - return 1; - - case 100: - case 98: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 110: - case 108: - case 106: - case 96: - return 0; - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 1) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 2) || (which_alternative == 3)) - { - return 0; - } - else if (which_alternative == 0) - { - return 1; - } - else - { - return -1 /* 0xffffffff */; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 1) || (which_alternative == 0)) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 89: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 5) || (which_alternative == 2)) - { - return 0; - } - else if (which_alternative == 4) - { - return 1; - } - else - { - return -1 /* 0xffffffff */; - } - - case 85: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative != 0) && ((which_alternative != 2) && (which_alternative != 3))) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 1) || ((which_alternative == 6) || (which_alternative == 7))) - { - return 0; - } - else if (which_alternative == 2) - { - return 1; - } - else - { - return -1 /* 0xffffffff */; - } - - case 80: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative != 0) && (which_alternative != 1)) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 79: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && (which_alternative != 3)))) - { - return 0; - } - else if (which_alternative == 0) - { - return 1; - } - else - { - return -1 /* 0xffffffff */; - } - - case 82: - case 77: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 2) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 2) - { - return 0; - } - else - { - return -1 /* 0xffffffff */; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 3) || (which_alternative == 4)) - { - return 0; - } - else if (which_alternative == 1) - { - return 1; - } - else - { - return -1 /* 0xffffffff */; - } - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return -1 /* 0xffffffff */; - - } -} - -int -num_delay_slots (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 228: - case 221: - case 218: - case 216: - case 215: - case 214: - case 212: - case 56: - case 55: - return 1; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } -} - -enum attr_in_annul_branch_delay -get_attr_in_annul_branch_delay (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return IN_ANNUL_BRANCH_DELAY_TRUE; - } - else - { - return IN_ANNUL_BRANCH_DELAY_FALSE; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return IN_ANNUL_BRANCH_DELAY_TRUE; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return IN_ANNUL_BRANCH_DELAY_FALSE; - - } -} - -enum attr_in_uncond_branch_delay -get_attr_in_uncond_branch_delay (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return IN_UNCOND_BRANCH_DELAY_TRUE; - } - else - { - return IN_UNCOND_BRANCH_DELAY_FALSE; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return IN_UNCOND_BRANCH_DELAY_TRUE; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return IN_UNCOND_BRANCH_DELAY_FALSE; - - } -} - -enum attr_in_branch_delay -get_attr_in_branch_delay (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return IN_BRANCH_DELAY_TRUE; - } - else - { - return IN_BRANCH_DELAY_FALSE; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return IN_BRANCH_DELAY_TRUE; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return IN_BRANCH_DELAY_FALSE; - - } -} - -enum attr_in_call_delay -get_attr_in_call_delay (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return IN_CALL_DELAY_TRUE; - } - else - { - return IN_CALL_DELAY_FALSE; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return IN_CALL_DELAY_TRUE; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return IN_CALL_DELAY_FALSE; - - } -} - -enum attr_type -get_attr_type (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return TYPE_MOVE; - } - else if (which_alternative == 2) - { - return TYPE_LOAD; - } - else - { - return TYPE_STORE; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_MOVE; - } - else if (which_alternative == 1) - { - return TYPE_FP; - } - else if (which_alternative == 2) - { - return TYPE_MOVE; - } - else if ((which_alternative == 3) || (which_alternative == 4)) - { - return TYPE_LOAD; - } - else if (which_alternative == 5) - { - return TYPE_STORE; - } - else - { - return TYPE_STORE; - } - - case 79: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_FP; - } - else if (which_alternative == 1) - { - return TYPE_MOVE; - } - else if (which_alternative == 2) - { - return TYPE_FPSTORE; - } - else if (which_alternative == 3) - { - return TYPE_STORE; - } - else if (which_alternative == 4) - { - return TYPE_FPLOAD; - } - else - { - return TYPE_LOAD; - } - - case 80: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_MOVE; - } - else if (which_alternative == 1) - { - return TYPE_STORE; - } - else - { - return TYPE_LOAD; - } - - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_FPSTORE; - } - else if (which_alternative == 1) - { - return TYPE_FPLOAD; - } - else if (which_alternative == 2) - { - return TYPE_FP; - } - else if (which_alternative == 3) - { - return TYPE_MOVE; - } - else if (which_alternative == 4) - { - return TYPE_FPSTORE; - } - else if (which_alternative == 5) - { - return TYPE_STORE; - } - else if (which_alternative == 6) - { - return TYPE_FPLOAD; - } - else - { - return TYPE_LOAD; - } - - case 85: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_STORE; - } - else if (which_alternative == 1) - { - return TYPE_LOAD; - } - else if (which_alternative == 2) - { - return TYPE_MOVE; - } - else if (which_alternative == 3) - { - return TYPE_STORE; - } - else - { - return TYPE_LOAD; - } - - case 89: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_MOVE; - } - else if (which_alternative == 1) - { - return TYPE_STORE; - } - else if (which_alternative == 2) - { - return TYPE_LOAD; - } - else if (which_alternative == 3) - { - return TYPE_MULTI; - } - else if (which_alternative == 4) - { - return TYPE_FP; - } - else if (which_alternative == 5) - { - return TYPE_FPLOAD; - } - else - { - return TYPE_FPSTORE; - } - - case 77: - case 82: - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_LOAD; - } - else if (which_alternative == 1) - { - return TYPE_FPLOAD; - } - else - { - return TYPE_STORE; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_FP; - } - else if (which_alternative == 1) - { - return TYPE_MOVE; - } - else if (which_alternative == 2) - { - return TYPE_FPLOAD; - } - else if (which_alternative == 3) - { - return TYPE_LOAD; - } - else if (which_alternative == 4) - { - return TYPE_FPSTORE; - } - else - { - return TYPE_STORE; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_MOVE; - } - else if (which_alternative == 1) - { - return TYPE_LOAD; - } - else - { - return TYPE_STORE; - } - - case 98: - case 100: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return TYPE_UNARY; - } - else - { - return TYPE_LOAD; - } - - case 31: - case 32: - case 35: - case 36: - case 230: - case 231: - return TYPE_MISC; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - case 44: - case 60: - case 202: - case 205: - case 206: - case 210: - case 211: - case 223: - case 225: - case 226: - case 232: - case 262: - case 263: - case 264: - case 265: - case 266: - case 267: - return TYPE_MULTI; - - case 198: - case 199: - case 200: - return TYPE_FPSQRT; - - case 189: - case 190: - case 191: - return TYPE_FPDIV; - - case 184: - case 185: - case 186: - case 187: - case 188: - return TYPE_FPMUL; - - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - return TYPE_FPCMP; - - case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: - case 119: - case 120: - case 121: - case 122: - case 123: - case 178: - case 179: - case 180: - case 181: - case 182: - case 183: - case 192: - case 193: - case 194: - case 195: - case 196: - case 197: - return TYPE_FP; - - case 219: - return TYPE_CALL_NO_DELAY_SLOT; - - case 218: - case 221: - return TYPE_CALL; - - case 55: - case 56: - return TYPE_BRANCH; - - case 212: - case 214: - case 215: - case 216: - case 228: - return TYPE_UNCOND_BRANCH; - - case 68: - case 72: - case 76: - case 81: - case 87: - case 94: - return TYPE_STORE; - - case 96: - case 106: - case 108: - case 110: - return TYPE_LOAD; - - case 16: - case 101: - case 103: - case 126: - case 130: - case 163: - case 165: - case 167: - case 171: - case 176: - return TYPE_COMPARE; - - case 23: - case 24: - case 25: - case 26: - case 33: - case 34: - case 37: - case 39: - case 42: - case 43: - case 102: - case 104: - case 169: - case 170: - case 172: - case 174: - case 175: - case 177: - return TYPE_UNARY; - - case 61: - case 62: - case 63: - case 64: - return TYPE_MOVE; - - default: - return TYPE_BINARY; - - } -} - -enum attr_use_clobbered -get_attr_use_clobbered (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return USE_CLOBBERED_FALSE; - - } -} - -int -eligible_for_delay (delay_insn, slot, candidate_insn, flags) - rtx delay_insn; - int slot; - rtx candidate_insn; - int flags; -{ - rtx insn; - - if (slot >= 1) - abort (); - - insn = delay_insn; - switch (recog_memoized (insn)) - { - case 221: - case 218: - slot += 1 * 1; - break; - break; - - case 228: - case 216: - case 215: - case 214: - case 212: - slot += 3 * 1; - break; - break; - - case 56: - case 55: - slot += 2 * 1; - break; - break; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - slot += 0 * 1; - break; - break; - - } - - if (slot < 1) - abort (); - - insn = candidate_insn; - switch (slot) - { - case 3: - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 0; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return 1; - } - else - { - return 0; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return 1; - } - else - { - return 0; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 1; - } - else - { - return 0; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else - { - return 0; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return 1; - } - else - { - return 0; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return 1; - } - else - { - return 0; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return 1; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - case 2: - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 0; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return 1; - } - else - { - return 0; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return 1; - } - else - { - return 0; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 1; - } - else - { - return 0; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else - { - return 0; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return 1; - } - else - { - return 0; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return 1; - } - else - { - return 0; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return 1; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - case 1: - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 0; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return 1; - } - else - { - return 0; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative != 0) && ((which_alternative != 1) && ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && (((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode))))) || ((which_alternative == 2) || (which_alternative == 3))))))) || (((which_alternative == 0) || (which_alternative == 1)) && ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))))) - { - return 1; - } - else - { - return 0; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 1; - } - else - { - return 0; - } - - case 85: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 1) || (which_alternative == 0)) - { - return 1; - } - else - { - return 0; - } - - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else - { - return 0; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative != 0) && ((which_alternative != 1) && ((! (symbolic_memory_operand (operands[1], VOIDmode))) || (which_alternative != 2)))) || (((which_alternative == 0) || (which_alternative == 1)) && (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))))) - { - return 1; - } - else - { - return 0; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((((which_alternative == 3) || (which_alternative == 4)) && ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))))) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))))) || ((((which_alternative == 5) || (which_alternative == 6)) && ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || (((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 4)) && ((which_alternative != 5) && (which_alternative != 6))) && (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode))))))))))))) - { - return 1; - } - else - { - return 0; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return 1; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - default: - abort (); - } -} - -int -eligible_for_annul_false (delay_insn, slot, candidate_insn, flags) - rtx delay_insn; - int slot; - rtx candidate_insn; - int flags; -{ - rtx insn; - - if (slot >= 1) - abort (); - - insn = delay_insn; - switch (recog_memoized (insn)) - { - case 221: - case 218: - slot += 1 * 1; - break; - break; - - case 228: - case 216: - case 215: - case 214: - case 212: - slot += 3 * 1; - break; - break; - - case 56: - case 55: - slot += 2 * 1; - break; - break; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - slot += 0 * 1; - break; - break; - - } - - if (slot < 1) - abort (); - - insn = candidate_insn; - switch (slot) - { - case 3: - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - case 2: - switch (recog_memoized (insn)) - { - case 196: - case 195: - case 193: - case 192: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative == 0) - { - return 1; - } - else - { - return 0; - } - - case 110: - case 108: - case 106: - case 96: - insn_extract (insn); - if (! (symbolic_memory_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 93: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 1) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))))) - { - return 1; - } - else - { - return 0; - } - - case 92: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((((which_alternative == 3) || (which_alternative == 2)) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative != 0) && ((which_alternative != 1) && ((which_alternative != 2) && ((which_alternative != 3) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))) || (((which_alternative == 1) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative != 3) && (which_alternative != 2)) && ((which_alternative == 0) || ((which_alternative == 2) || (which_alternative == 3))))))) - { - return 1; - } - else - { - return 0; - } - - case 90: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (which_alternative != 0) - { - return 1; - } - else - { - return 0; - } - - case 85: - case 84: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if ((which_alternative == 0) || (which_alternative == 1)) - { - return 1; - } - else - { - return 0; - } - - case 74: - case 70: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || (((which_alternative == 2) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || ((which_alternative != 0) && (which_alternative != 2)))) - { - return 1; - } - else - { - return 0; - } - - case 59: - insn_extract (insn); - if (! constrain_operands (INSN_CODE (insn), reload_completed)) - fatal_insn_not_found (insn); - if (((which_alternative == 0) && ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode)))) || ((which_alternative == 1) || ((which_alternative == 2) || (((which_alternative == 3) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 4) && (! (symbolic_memory_operand (operands[1], VOIDmode)))) || (((which_alternative == 5) && (! (symbolic_memory_operand (operands[0], VOIDmode)))) || ((which_alternative == 6) && (! (symbolic_memory_operand (operands[0], VOIDmode)))))))))) - { - return 1; - } - else - { - return 0; - } - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: - case 227: - case 208: - case 207: - case 203: - case 168: - case 166: - case 164: - case 162: - case 158: - case 155: - case 152: - case 149: - case 146: - case 133: - case 132: - case 131: - case 129: - case 127: - case 125: - case 111: - case 41: - case 40: - case 38: - insn_extract (insn); - if ((arith_operand (operands[2], VOIDmode)) || (arith_double_operand (operands[2], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 177: - case 175: - case 172: - case 170: - case 104: - case 102: - case 43: - case 42: - case 39: - case 37: - case 34: - case 33: - insn_extract (insn); - if ((arith_operand (operands[1], VOIDmode)) || (arith_double_operand (operands[1], VOIDmode))) - { - return 1; - } - else - { - return 0; - } - - case 230: - case 200: - case 199: - case 198: - case 197: - case 194: - case 191: - case 190: - case 189: - case 188: - case 187: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 176: - case 171: - case 167: - case 165: - case 163: - case 130: - case 126: - case 123: - case 122: - case 121: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 103: - case 101: - case 100: - case 98: - case 75: - case 71: - case 67: - case 66: - case 65: - case 64: - case 63: - case 62: - case 36: - case 35: - case 32: - case 31: - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - return 1; - - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - case 1: - switch (recog_memoized (insn)) - { - case -1: - if (GET_CODE (PATTERN (insn)) != ASM_INPUT - && asm_noperands (PATTERN (insn)) < 0) - fatal_insn_not_found (insn); - default: - return 0; - - } - default: - abort (); - } -} - -struct function_unit_desc function_units[] = { - {"memory", 1, 1, 1, 1, 1, memory_unit_ready_cost, 0, 2, 0, 0}, - {"fp_alu", 2, 1, 1, 1, 1, fp_alu_unit_ready_cost, 0, 5, 0, 0}, - {"fp_mds", 4, 1, 1, 1, 1, fp_mds_unit_ready_cost, 0, 63, fp_mds_unit_blockage_range, 0}, -}; - -int -const_num_delay_slots (insn) - rtx insn; -{ - switch (recog_memoized (insn)) - { - default: - return 1; - } -} diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-codes.h b/gnu/usr.bin/gcc2/arch/sparc/insn-codes.h deleted file mode 100644 index b3148b2d39e..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-codes.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Generated automatically by the program `gencodes' -from the machine description file `md'. */ - -#ifndef MAX_INSN_CODE - -enum insn_code { - CODE_FOR_cmpsi = 0, - CODE_FOR_cmpsf = 1, - CODE_FOR_cmpdf = 2, - CODE_FOR_cmptf = 3, - CODE_FOR_seq_special = 4, - CODE_FOR_sne_special = 5, - CODE_FOR_seq = 6, - CODE_FOR_sne = 7, - CODE_FOR_sgt = 8, - CODE_FOR_slt = 9, - CODE_FOR_sge = 10, - CODE_FOR_sle = 11, - CODE_FOR_sgtu = 12, - CODE_FOR_sltu = 13, - CODE_FOR_sgeu = 14, - CODE_FOR_sleu = 15, - CODE_FOR_beq = 45, - CODE_FOR_bne = 46, - CODE_FOR_bgt = 47, - CODE_FOR_bgtu = 48, - CODE_FOR_blt = 49, - CODE_FOR_bltu = 50, - CODE_FOR_bge = 51, - CODE_FOR_bgeu = 52, - CODE_FOR_ble = 53, - CODE_FOR_bleu = 54, - CODE_FOR_movsi = 57, - CODE_FOR_reload_insi = 58, - CODE_FOR_movhi = 69, - CODE_FOR_movqi = 73, - CODE_FOR_movtf = 78, - CODE_FOR_movdf = 83, - CODE_FOR_movdi = 88, - CODE_FOR_movsf = 91, - CODE_FOR_zero_extendhisi2 = 95, - CODE_FOR_zero_extendqihi2 = 97, - CODE_FOR_zero_extendqisi2 = 99, - CODE_FOR_extendhisi2 = 105, - CODE_FOR_extendqihi2 = 107, - CODE_FOR_extendqisi2 = 109, - CODE_FOR_extendsfdf2 = 112, - CODE_FOR_extendsftf2 = 113, - CODE_FOR_extenddftf2 = 114, - CODE_FOR_truncdfsf2 = 115, - CODE_FOR_trunctfsf2 = 116, - CODE_FOR_trunctfdf2 = 117, - CODE_FOR_floatsisf2 = 118, - CODE_FOR_floatsidf2 = 119, - CODE_FOR_floatsitf2 = 120, - CODE_FOR_fix_truncsfsi2 = 121, - CODE_FOR_fix_truncdfsi2 = 122, - CODE_FOR_fix_trunctfsi2 = 123, - CODE_FOR_adddi3 = 124, - CODE_FOR_addsi3 = 125, - CODE_FOR_subdi3 = 128, - CODE_FOR_subsi3 = 129, - CODE_FOR_mulsi3 = 132, - CODE_FOR_mulsidi3 = 134, - CODE_FOR_const_mulsidi3 = 136, - CODE_FOR_umulsidi3 = 137, - CODE_FOR_const_umulsidi3 = 139, - CODE_FOR_divsi3 = 140, - CODE_FOR_udivsi3 = 142, - CODE_FOR_anddi3 = 144, - CODE_FOR_andsi3 = 146, - CODE_FOR_iordi3 = 150, - CODE_FOR_iorsi3 = 152, - CODE_FOR_xordi3 = 156, - CODE_FOR_xorsi3 = 158, - CODE_FOR_negdi2 = 169, - CODE_FOR_negsi2 = 170, - CODE_FOR_one_cmpldi2 = 173, - CODE_FOR_one_cmplsi2 = 175, - CODE_FOR_addtf3 = 178, - CODE_FOR_adddf3 = 179, - CODE_FOR_addsf3 = 180, - CODE_FOR_subtf3 = 181, - CODE_FOR_subdf3 = 182, - CODE_FOR_subsf3 = 183, - CODE_FOR_multf3 = 184, - CODE_FOR_muldf3 = 185, - CODE_FOR_mulsf3 = 186, - CODE_FOR_divtf3 = 189, - CODE_FOR_divdf3 = 190, - CODE_FOR_divsf3 = 191, - CODE_FOR_negtf2 = 192, - CODE_FOR_negdf2 = 193, - CODE_FOR_negsf2 = 194, - CODE_FOR_abstf2 = 195, - CODE_FOR_absdf2 = 196, - CODE_FOR_abssf2 = 197, - CODE_FOR_sqrttf2 = 198, - CODE_FOR_sqrtdf2 = 199, - CODE_FOR_sqrtsf2 = 200, - CODE_FOR_ashldi3 = 201, - CODE_FOR_ashlsi3 = 203, - CODE_FOR_lshldi3 = 204, - CODE_FOR_ashrsi3 = 207, - CODE_FOR_lshrsi3 = 208, - CODE_FOR_lshrdi3 = 209, - CODE_FOR_jump = 212, - CODE_FOR_tablejump = 213, - CODE_FOR_pic_tablejump = 214, - CODE_FOR_call = 217, - CODE_FOR_call_value = 220, - CODE_FOR_untyped_call = 222, - CODE_FOR_untyped_return = 224, - CODE_FOR_update_return = 225, - CODE_FOR_return = 226, - CODE_FOR_nop = 227, - CODE_FOR_indirect_jump = 228, - CODE_FOR_nonlocal_goto = 229, - CODE_FOR_flush_register_windows = 230, - CODE_FOR_goto_handler_and_restore = 231, - CODE_FOR_ffssi2 = 232, - CODE_FOR_nothing }; - -#define MAX_INSN_CODE ((int) CODE_FOR_nothing) -#endif /* MAX_INSN_CODE */ diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-config.h b/gnu/usr.bin/gcc2/arch/sparc/insn-config.h deleted file mode 100644 index cd4e670ee0a..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-config.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Generated automatically by the program `genconfig' -from the machine description file `md'. */ - - -#define MAX_RECOG_OPERANDS 10 - -#define MAX_DUP_OPERANDS 2 -#ifndef MAX_INSNS_PER_SPLIT -#define MAX_INSNS_PER_SPLIT 2 -#endif -#define REGISTER_CONSTRAINTS -#define HAVE_lo_sum diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-emit.c b/gnu/usr.bin/gcc2/arch/sparc/insn-emit.c deleted file mode 100644 index bf6cbe2e895..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-emit.c +++ /dev/null @@ -1,2595 +0,0 @@ -/* Generated automatically by the program `genemit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "expr.h" -#include "real.h" -#include "output.h" -#include "insn-config.h" - -#include "insn-flags.h" - -#include "insn-codes.h" - -extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS]; - -extern rtx recog_operand[]; -#define operands emit_operand - -#define FAIL goto _fail - -#define DONE goto _done - -rtx -gen_cmpsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CCmode, 0), gen_rtx (COMPARE, CCmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_cmpsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0), gen_rtx (COMPARE, CCFPmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_cmpdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0), gen_rtx (COMPARE, CCFPmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_cmptf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0), gen_rtx (COMPARE, CCFPmode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_seq_special (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operand3; - rtx operands[4]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; -{ operands[3] = gen_reg_rtx (SImode); } - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, gen_rtx (XOR, SImode, operand1, operand2))); - emit (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (EQ, SImode, operand3, const0_rtx)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, CCmode, 0))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sne_special (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operand3; - rtx operands[4]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; -{ operands[3] = gen_reg_rtx (SImode); } - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, gen_rtx (XOR, SImode, operand1, operand2))); - emit (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (NE, SImode, operand3, const0_rtx)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, CCmode, 0))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_seq (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ if (GET_MODE (sparc_compare_op0) == SImode) - { - emit_insn (gen_seq_special (operands[0], sparc_compare_op0, - sparc_compare_op1)); - DONE; - } - else - operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (EQ, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sne (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ if (GET_MODE (sparc_compare_op0) == SImode) - { - emit_insn (gen_sne_special (operands[0], sparc_compare_op0, - sparc_compare_op1)); - DONE; - } - else - operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (NE, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sgt (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GT, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_slt (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LT, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sge (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GE, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sle (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LE, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sgtu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ - rtx tem; - - /* We can do ltu easily, so if both operands are registers, swap them and - do a LTU. */ - if ((GET_CODE (sparc_compare_op0) == REG - || GET_CODE (sparc_compare_op0) == SUBREG) - && (GET_CODE (sparc_compare_op1) == REG - || GET_CODE (sparc_compare_op1) == SUBREG)) - { - tem = sparc_compare_op0; - sparc_compare_op0 = sparc_compare_op1; - sparc_compare_op1 = tem; - emit_insn (gen_sltu (operands[0])); - DONE; - } - - operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GTU, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sltu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LTU, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sgeu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GEU, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_sleu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ - rtx tem; - - /* We can do geu easily, so if both operands are registers, swap them and - do a GEU. */ - if ((GET_CODE (sparc_compare_op0) == REG - || GET_CODE (sparc_compare_op0) == SUBREG) - && (GET_CODE (sparc_compare_op1) == REG - || GET_CODE (sparc_compare_op1) == SUBREG)) - { - tem = sparc_compare_op0; - sparc_compare_op0 = sparc_compare_op1; - sparc_compare_op1 = tem; - emit_insn (gen_sgeu (operands[0])); - DONE; - } - - operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LEU, SImode, operand1, const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_beq (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (EQ, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bne (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (NE, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bgt (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GT, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bgtu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GTU, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_blt (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LT, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bltu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LTU, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bge (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GE, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bgeu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (GEU, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_ble (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); } - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LE, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_bleu (operand0) - rtx operand0; -{ - rtx operand1; - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - -{ operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (IF_THEN_ELSE, VOIDmode, gen_rtx (LEU, VOIDmode, operand1, const0_rtx), gen_rtx (LABEL_REF, VOIDmode, operand0), pc_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movsi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, SImode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_reload_insi (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (emit_move_sequence (operands, SImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - emit_insn (gen_rtx (CLOBBER, VOIDmode, operand2)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movhi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, HImode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movqi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, QImode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movtf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, TFmode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movdf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, DFmode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_86 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; - rtx operand5; - rtx _val = 0; - start_sequence (); - -{ operands[2] = operand_subword (operands[0], 0, 0, DFmode); - operands[3] = operand_subword (operands[1], 0, 0, DFmode); - operands[4] = operand_subword (operands[0], 1, 0, DFmode); - operands[5] = operand_subword (operands[1], 1, 0, DFmode); } - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - operand5 = operands[5]; - emit_insn (gen_rtx (SET, VOIDmode, operand2, operand3)); - emit_insn (gen_rtx (SET, VOIDmode, operand4, operand5)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movdi (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, DImode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_movsf (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - if (emit_move_sequence (operands, SFmode, NULL_RTX)) - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_zero_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_16)); - emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, SImode, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_zero_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, HImode, operand1)); -} - -rtx -gen_zero_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, SImode, operand1)); -} - -rtx -gen_extendhisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_16)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extendqihi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - if (GET_CODE (operand0) == SUBREG) - operand0 = XEXP (operand0, 0); - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_24)); - if (GET_MODE (operand0) != SImode) - operand0 = gen_rtx (SUBREG, SImode, operand0, 0); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, HImode, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extendqisi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_24)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (SIGN_EXTEND, SImode, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_extendsfdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, DFmode, operand1)); -} - -rtx -gen_extendsftf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, TFmode, operand1)); -} - -rtx -gen_extenddftf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_EXTEND, TFmode, operand1)); -} - -rtx -gen_truncdfsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, SFmode, operand1)); -} - -rtx -gen_trunctfsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, SFmode, operand1)); -} - -rtx -gen_trunctfdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT_TRUNCATE, DFmode, operand1)); -} - -rtx -gen_floatsisf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, SFmode, operand1)); -} - -rtx -gen_floatsidf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, DFmode, operand1)); -} - -rtx -gen_floatsitf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FLOAT, TFmode, operand1)); -} - -rtx -gen_fix_truncsfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, SFmode, operand1))); -} - -rtx -gen_fix_truncdfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, DFmode, operand1))); -} - -rtx -gen_fix_trunctfsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (FIX, SImode, gen_rtx (FIX, TFmode, operand1))); -} - -rtx -gen_adddi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, DImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))); -} - -rtx -gen_addsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, operand1, operand2)); -} - -rtx -gen_subdi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, DImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))); -} - -rtx -gen_subsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SImode, operand1, operand2)); -} - -rtx -gen_mulsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SImode, operand1, operand2)); -} - -rtx -gen_mulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[2])) - { - emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2])); - DONE; - } -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DImode, gen_rtx (SIGN_EXTEND, DImode, operand1), gen_rtx (SIGN_EXTEND, DImode, operand2)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_const_mulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DImode, gen_rtx (SIGN_EXTEND, DImode, operand1), operand2)); -} - -rtx -gen_umulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (CONSTANT_P (operands[2])) - { - emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2])); - DONE; - } -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DImode, gen_rtx (ZERO_EXTEND, DImode, operand1), gen_rtx (ZERO_EXTEND, DImode, operand2)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_const_umulsidi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DImode, gen_rtx (ZERO_EXTEND, DImode, operand1), operand2)); -} - -rtx -gen_divsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_udivsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (UDIV, SImode, operand1, operand2)); -} - -rtx -gen_anddi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, DImode, operand1, operand2)); -} - -rtx -gen_andsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, SImode, operand1, operand2)); -} - -rtx -gen_split_147 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; - rtx _val = 0; - start_sequence (); - -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, operand4)); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (AND, SImode, gen_rtx (NOT, SImode, operand3), operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_iordi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, DImode, operand1, operand2)); -} - -rtx -gen_iorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, SImode, operand1, operand2)); -} - -rtx -gen_split_153 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; - rtx _val = 0; - start_sequence (); - -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, operand4)); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (IOR, SImode, gen_rtx (NOT, SImode, operand3), operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_xordi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, DImode, operand1, operand2)); -} - -rtx -gen_xorsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, SImode, operand1, operand2)); -} - -rtx -gen_split_159 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; - rtx _val = 0; - start_sequence (); - -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, operand4)); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, SImode, gen_rtx (XOR, SImode, operand3, operand1)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_160 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; - rtx _val = 0; - start_sequence (); - -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, operand4)); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (XOR, SImode, operand3, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_negdi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, DImode, operand1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))); -} - -rtx -gen_negsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SImode, operand1)); -} - -rtx -gen_one_cmpldi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, DImode, operand1)); -} - -rtx -gen_one_cmplsi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NOT, SImode, operand1)); -} - -rtx -gen_addtf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, TFmode, operand1, operand2)); -} - -rtx -gen_adddf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, DFmode, operand1, operand2)); -} - -rtx -gen_addsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SFmode, operand1, operand2)); -} - -rtx -gen_subtf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, TFmode, operand1, operand2)); -} - -rtx -gen_subdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, DFmode, operand1, operand2)); -} - -rtx -gen_subsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SFmode, operand1, operand2)); -} - -rtx -gen_multf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, TFmode, operand1, operand2)); -} - -rtx -gen_muldf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, DFmode, operand1, operand2)); -} - -rtx -gen_mulsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (MULT, SFmode, operand1, operand2)); -} - -rtx -gen_divtf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, TFmode, operand1, operand2)); -} - -rtx -gen_divdf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, DFmode, operand1, operand2)); -} - -rtx -gen_divsf3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (DIV, SFmode, operand1, operand2)); -} - -rtx -gen_negtf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, TFmode, operand1)); -} - -rtx -gen_negdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, DFmode, operand1)); -} - -rtx -gen_negsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SFmode, operand1)); -} - -rtx -gen_abstf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, TFmode, operand1)); -} - -rtx -gen_absdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, DFmode, operand1)); -} - -rtx -gen_abssf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ABS, SFmode, operand1)); -} - -rtx -gen_sqrttf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SQRT, TFmode, operand1)); -} - -rtx -gen_sqrtdf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SQRT, DFmode, operand1)); -} - -rtx -gen_sqrtsf2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (SQRT, SFmode, operand1)); -} - -rtx -gen_ashldi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[1]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[1]) == 0 - && CONST_DOUBLE_LOW (operands[1]) == 1) - operands[1] = const1_rtx; - else if (operands[1] != const1_rtx) - FAIL; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, DImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_ashlsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFT, SImode, operand1, operand2)); -} - -rtx -gen_lshldi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFT, DImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_ashrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (ASHIFTRT, SImode, operand1, operand2)); -} - -rtx -gen_lshrsi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - return gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, SImode, operand1, operand2)); -} - -rtx -gen_lshrdi3 (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (LSHIFTRT, DImode, operand1, operand2)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, operand0)); -} - -rtx -gen_tablejump (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - /* We need to use the PC value in %o7 that was set up when the address - of the label was loaded into a register, so we need different RTL. */ - if (flag_pic) - { - emit_insn (gen_pic_tablejump (operands[0], operands[1])); - DONE; - } -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, operand0), - gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, operand1))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_pic_tablejump (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, pc_rtx, operand0), - gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, operand1)), - gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 15)))); -} - -rtx -gen_call (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - rtx operands[4]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - operands[3] = operand3; - -{ - rtx fn_rtx, nregs_rtx; - - if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) - { - /* This is really a PIC sequence. We want to represent - it as a funny jump so it's delay slots can be filled. - - ??? But if this really *is* a CALL, will not it clobber the - call-clobbered registers? We lose this if it is a JUMP_INSN. - Why cannot we have delay slots filled if it were a CALL? */ - - if (INTVAL (operands[3]) > 0) - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, pc_rtx, - XEXP (operands[0], 0)), - operands[3], - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - else - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, - XEXP (operands[0], 0)), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - goto finish_call; - } - - fn_rtx = operands[0]; - - /* Count the number of parameter registers being used by this call. - if that argument is NULL, it means we are using them all, which - means 6 on the sparc. */ -#if 0 - if (operands[2]) - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8); - else - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); -#else - nregs_rtx = const0_rtx; -#endif - - if (INTVAL (operands[3]) > 0) - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), - operands[3], - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - else - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - - finish_call: -#if 0 - /* If this call wants a structure value, - emit an unimp insn to let the called function know about this. */ - if (INTVAL (operands[3]) > 0) - { - rtx insn = emit_insn (operands[3]); - SCHED_GROUP_P (insn) = 1; - } -#endif - - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_call_insn (gen_rtx (CALL, VOIDmode, operand0, operand3)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_call_value (operand0, operand1, operand2, operand3, operand4) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx operand4; -{ - rtx operands[5]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - operands[3] = operand3; - operands[4] = operand4; - -{ - rtx fn_rtx, nregs_rtx; - rtvec vec; - - fn_rtx = operands[1]; - -#if 0 - if (operands[3]) - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8); - else - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); -#else - nregs_rtx = const0_rtx; -#endif - - vec = gen_rtvec (2, - gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15))); - - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec)); - - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - operand4 = operands[4]; - emit_call_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (CALL, VOIDmode, operand1, operand4))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_untyped_call (operand0, operand1, operand2) - rtx operand0; - rtx operand1; - rtx operand2; -{ - rtx operands[3]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - -{ - operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0)); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (4, - gen_rtx (CALL, VOIDmode, operand0, const0_rtx), - operand1, - operand2, - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15))))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_untyped_return (operand0, operand1) - rtx operand0; - rtx operand1; -{ - rtx operands[2]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - -{ - rtx valreg1 = gen_rtx (REG, DImode, 24); - rtx valreg2 = gen_rtx (REG, DFmode, 32); - rtx result = operands[0]; - rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31)); - rtx value = gen_reg_rtx (SImode); - - /* Fetch the instruction where we will return to and see if it's an unimp - instruction (the most significant 10 bits will be zero). If so, - update the return address to skip the unimp instruction. */ - emit_move_insn (value, - gen_rtx (MEM, SImode, plus_constant (rtnreg, 8))); - emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); - emit_insn (gen_update_return (rtnreg, value)); - - /* Reload the function value registers. */ - emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0))); - emit_move_insn (valreg2, - change_address (result, DFmode, - plus_constant (XEXP (result, 0), 8))); - - /* Put USE insns before the return. */ - emit_insn (gen_rtx (USE, VOIDmode, valreg1)); - emit_insn (gen_rtx (USE, VOIDmode, valreg2)); - - /* Construct the return. */ - expand_null_return (); - - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - emit (operand0); - emit (operand1); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_update_return (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (UNSPEC, SImode, gen_rtvec (2, - operand0, - operand1), 0); -} - -rtx -gen_return () -{ - return gen_rtx (RETURN, VOIDmode); -} - -rtx -gen_nop () -{ - return const0_rtx; -} - -rtx -gen_indirect_jump (operand0) - rtx operand0; -{ - return gen_rtx (SET, VOIDmode, pc_rtx, operand0); -} - -rtx -gen_nonlocal_goto (operand0, operand1, operand2, operand3) - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; -{ - rtx operands[4]; - rtx _val = 0; - start_sequence (); - operands[0] = operand0; - operands[1] = operand1; - operands[2] = operand2; - operands[3] = operand3; - -{ - /* Trap instruction to flush all the registers window. */ - emit_insn (gen_flush_register_windows ()); - /* Load the fp value for the containing fn into %fp. - This is needed because operands[2] refers to %fp. - Virtual register instantiation fails if the virtual %fp isn't set from a - register. Thus we must copy operands[0] into a register if it isn't - already one. */ - if (GET_CODE (operands[0]) != REG) - operands[0] = force_reg (SImode, operands[0]); - emit_move_insn (virtual_stack_vars_rtx, operands[0]); - /* Find the containing function's current nonlocal goto handler, - which will do any cleanups and then jump to the label. */ - emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]); - /* Restore %fp from stack pointer value for containing function. - The restore insn that follows will move this to %sp, - and reload the appropriate value into %fp. */ - emit_move_insn (frame_pointer_rtx, operands[2]); - /* Put in the static chain register the nonlocal label address. */ - emit_move_insn (static_chain_rtx, operands[3]); - /* USE of frame_pointer_rtx added for consistency; not clear if - really needed. */ - emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8))); - /* Return, restoring reg window and jumping to goto handler. */ - emit_insn (gen_goto_handler_and_restore ()); - DONE; -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit (operand0); - emit (operand1); - emit (operand2); - emit (operand3); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_flush_register_windows () -{ - return gen_rtx (UNSPEC_VOLATILE, VOIDmode, gen_rtvec (1, - const0_rtx), 0); -} - -rtx -gen_goto_handler_and_restore () -{ - return gen_rtx (UNSPEC_VOLATILE, VOIDmode, gen_rtvec (1, - const0_rtx), 1); -} - -rtx -gen_ffssi2 (operand0, operand1) - rtx operand0; - rtx operand1; -{ - return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, operand0, gen_rtx (FFS, SImode, operand1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))); -} - -rtx -gen_split_233 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_insn (gen_rtx (SET, VOIDmode, operand3, gen_rtx (HIGH, SImode, operand1))); - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (GET_CODE (operand0), GET_MODE (operand0), - gen_rtx (LO_SUM, SImode, operand3, operand1)), operand2)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_234 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - -{ - operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]), - operands[3], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (GET_CODE (operand0), GET_MODE (operand0), - operand1), operand2)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_235 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - -{ - operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]), - operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GET_CODE (operand1), GET_MODE (operand1), - operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_236 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx operand3; - rtx _val = 0; - start_sequence (); - -{ - operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]), - operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - operand3 = operands[3]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GET_CODE (operand1), GET_MODE (operand1), - gen_rtx (GET_CODE (operand2), GET_MODE (operand2), - operand3)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_237 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (HIGH, SImode, operand1))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LO_SUM, SImode, operand0, operand1))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_238 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - -{ - operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0); -} - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_239 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (LTU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_240 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SImode, gen_rtx (LTU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_241 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (GEU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_242 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, SImode, gen_rtx (GEU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_243 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, gen_rtx (LTU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx), operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_244 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SImode, operand2, gen_rtx (LTU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_245 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (PLUS, SImode, gen_rtx (GEU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx), operand2))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - -rtx -gen_split_246 (operands) - rtx *operands; -{ - rtx operand0; - rtx operand1; - rtx operand2; - rtx _val = 0; - start_sequence (); - - operand0 = operands[0]; - operand1 = operands[1]; - operand2 = operands[2]; - emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, CC_NOOVmode, 0), gen_rtx (COMPARE, CC_NOOVmode, gen_rtx (NEG, SImode, operand1), const0_rtx))); - emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MINUS, SImode, operand2, gen_rtx (GEU, SImode, gen_rtx (REG, CCmode, 0), const0_rtx)))); - _done: - _val = gen_sequence (); - _fail: - end_sequence (); - return _val; -} - - - -void -add_clobbers (pattern, insn_code_number) - rtx pattern; - int insn_code_number; -{ - int i; - - switch (insn_code_number) - { - case 223: - XVECEXP (pattern, 0, 3) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)); - break; - - case 219: - XVECEXP (pattern, 0, 2) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)); - break; - - case 221: - case 218: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)); - break; - - case 141: - XVECEXP (pattern, 0, 2) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)); - break; - - case 202: - case 169: - case 128: - case 124: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)); - break; - - case 232: - case 211: - case 210: - case 206: - case 205: - case 140: - case 94: - case 87: - case 81: - case 76: - case 72: - case 68: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)); - break; - - case 30: - case 29: - case 28: - case 27: - case 26: - case 25: - case 24: - case 23: - XVECEXP (pattern, 0, 1) = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, CCmode, 0)); - break; - - default: - abort (); - } -} - -void -init_mov_optab () -{ -#ifdef HAVE_movcc_noov - if (HAVE_movcc_noov) - mov_optab->handlers[(int) CC_NOOVmode].insn_code = CODE_FOR_movcc_noov; -#endif -#ifdef HAVE_movccfp - if (HAVE_movccfp) - mov_optab->handlers[(int) CCFPmode].insn_code = CODE_FOR_movccfp; -#endif -#ifdef HAVE_movccfpe - if (HAVE_movccfpe) - mov_optab->handlers[(int) CCFPEmode].insn_code = CODE_FOR_movccfpe; -#endif -} diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-extract.c b/gnu/usr.bin/gcc2/arch/sparc/insn-extract.c deleted file mode 100644 index c8c3069ac9e..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-extract.c +++ /dev/null @@ -1,487 +0,0 @@ -/* Generated automatically by the program `genextract' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" - -static rtx junk; -extern rtx recog_operand[]; -extern rtx *recog_operand_loc[]; -extern rtx *recog_dup_loc[]; -extern char recog_dup_num[]; -extern -#ifdef __GNUC__ -__volatile__ -#endif -void fatal_insn_not_found (); - -void -insn_extract (insn) - rtx insn; -{ - register rtx *ro = recog_operand; - register rtx **ro_loc = recog_operand_loc; - rtx pat = PATTERN (insn); - switch (INSN_CODE (insn)) - { - case -1: - fatal_insn_not_found (insn); - - case 270: - case 269: - case 268: - case 261: - case 260: - case 259: - case 258: - case 257: - case 256: - case 255: - case 254: - case 253: - case 252: - case 251: - case 250: - case 249: - case 248: - case 247: -#if __GNUC__ > 1 && !defined (bcopy) -#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#endif - bcopy (&XVECEXP (pat, 0, 0), ro, - sizeof (rtx) * XVECLEN (pat, 0)); - break; - - case 267: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 1)); - break; - - case 232: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 228: - ro[0] = *(ro_loc[0] = &XEXP (pat, 1)); - break; - - case 231: - case 230: - case 227: - case 226: - break; - - case 225: - ro[0] = *(ro_loc[0] = &XVECEXP (pat, 0, 0)); - ro[1] = *(ro_loc[1] = &XVECEXP (pat, 0, 1)); - break; - - case 223: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XVECEXP (pat, 0, 1)); - ro[2] = *(ro_loc[2] = &XVECEXP (pat, 0, 2)); - break; - - case 219: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[2] = *(ro_loc[2] = &XVECEXP (pat, 0, 1)); - break; - - case 218: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 0), 1)); - break; - - case 216: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[0] = 0; - break; - - case 215: - case 214: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0)); - break; - - case 212: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 202: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - break; - - case 168: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 1); - recog_dup_num[0] = 3; - break; - - case 167: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 166: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0), 1)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 1); - recog_dup_num[1] = 2; - break; - - case 165: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XEXP (pat, 1), 0), 0), 1)); - break; - - case 164: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 1); - recog_dup_num[0] = 3; - break; - - case 163: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 141: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 2), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 1); - recog_dup_num[1] = 2; - break; - - case 211: - case 210: - case 206: - case 205: - case 140: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - ro[3] = *(ro_loc[3] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 155: - case 154: - case 149: - case 148: - case 139: - case 136: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 188: - case 187: - case 138: - case 135: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 143: - case 133: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - recog_dup_loc[0] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0), 1); - recog_dup_num[1] = 2; - break; - - case 131: - case 127: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 1)); - recog_dup_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[0] = 1; - recog_dup_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 1); - recog_dup_num[1] = 2; - break; - - case 130: - case 126: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - break; - - case 266: - case 128: - case 124: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - break; - - case 123: - case 122: - case 121: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - break; - - case 111: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 0), 2)); - break; - - case 104: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - recog_dup_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 1); - recog_dup_num[0] = 1; - break; - - case 177: - case 172: - case 102: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - recog_dup_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 1), 1), 0); - recog_dup_num[0] = 1; - break; - - case 176: - case 171: - case 103: - case 101: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - break; - - case 94: - case 87: - case 81: - case 76: - case 72: - case 68: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 0), 1)); - ro[2] = *(ro_loc[2] = &XEXP (XVECEXP (pat, 0, 1), 0)); - break; - - case 66: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XVECEXP (XEXP (XEXP (pat, 1), 1), 0, 0)); - break; - - case 208: - case 207: - case 203: - case 191: - case 190: - case 189: - case 186: - case 185: - case 184: - case 183: - case 182: - case 181: - case 180: - case 179: - case 178: - case 158: - case 157: - case 152: - case 151: - case 146: - case 145: - case 142: - case 132: - case 129: - case 125: - case 71: - case 67: - case 65: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 62: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XVECEXP (XEXP (XEXP (pat, 1), 0), 0, 0)); - break; - - case 265: - case 264: - case 263: - case 262: - case 60: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XVECEXP (pat, 0, 0), 1)); - break; - - case 56: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 2), 0)); - break; - - case 55: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - break; - - case 93: - case 92: - case 90: - case 89: - case 85: - case 84: - case 82: - case 80: - case 79: - case 77: - case 74: - case 70: - case 59: - case 44: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (pat, 1)); - break; - - case 41: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 1)); - break; - - case 162: - case 161: - case 75: - case 40: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - break; - - case 200: - case 199: - case 198: - case 197: - case 196: - case 195: - case 194: - case 193: - case 192: - case 175: - case 174: - case 170: - case 120: - case 119: - case 118: - case 117: - case 116: - case 115: - case 114: - case 113: - case 112: - case 110: - case 108: - case 106: - case 100: - case 98: - case 96: - case 64: - case 63: - case 61: - case 43: - case 39: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 0)); - break; - - case 38: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XEXP (pat, 1), 1), 1)); - break; - - case 34: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (pat, 1), 0), 1)); - break; - - case 42: - case 37: - case 33: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - break; - - case 36: - case 35: - case 32: - case 31: - ro[0] = *(ro_loc[0] = &XEXP (pat, 0)); - break; - - case 30: - case 28: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - break; - - case 221: - case 29: - case 27: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - ro[2] = *(ro_loc[2] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1)); - break; - - case 26: - case 24: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0)); - break; - - case 169: - case 25: - case 23: - ro[0] = *(ro_loc[0] = &XEXP (XVECEXP (pat, 0, 0), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0)); - break; - - case 22: - case 21: - case 20: - case 19: - case 18: - case 17: - case 16: - ro[0] = *(ro_loc[0] = &XEXP (XEXP (pat, 1), 0)); - ro[1] = *(ro_loc[1] = &XEXP (XEXP (pat, 1), 1)); - break; - - default: - abort (); - } -} diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-flags.h b/gnu/usr.bin/gcc2/arch/sparc/insn-flags.h deleted file mode 100644 index e2de7d7da64..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-flags.h +++ /dev/null @@ -1,360 +0,0 @@ -/* Generated automatically by the program `genflags' -from the machine description file `md'. */ - -#define HAVE_cmpsi 1 -#define HAVE_cmpsf (TARGET_FPU) -#define HAVE_cmpdf (TARGET_FPU) -#define HAVE_cmptf (TARGET_FPU) -#define HAVE_seq_special 1 -#define HAVE_sne_special 1 -#define HAVE_seq 1 -#define HAVE_sne 1 -#define HAVE_sgt 1 -#define HAVE_slt 1 -#define HAVE_sge 1 -#define HAVE_sle 1 -#define HAVE_sgtu 1 -#define HAVE_sltu 1 -#define HAVE_sgeu 1 -#define HAVE_sleu 1 -#define HAVE_beq 1 -#define HAVE_bne 1 -#define HAVE_bgt 1 -#define HAVE_bgtu 1 -#define HAVE_blt 1 -#define HAVE_bltu 1 -#define HAVE_bge 1 -#define HAVE_bgeu 1 -#define HAVE_ble 1 -#define HAVE_bleu 1 -#define HAVE_movsi 1 -#define HAVE_reload_insi 1 -#define HAVE_movhi 1 -#define HAVE_movqi 1 -#define HAVE_movtf 1 -#define HAVE_movdf 1 -#define HAVE_movdi 1 -#define HAVE_movsf 1 -#define HAVE_zero_extendhisi2 1 -#define HAVE_zero_extendqihi2 1 -#define HAVE_zero_extendqisi2 1 -#define HAVE_extendhisi2 1 -#define HAVE_extendqihi2 1 -#define HAVE_extendqisi2 1 -#define HAVE_extendsfdf2 (TARGET_FPU) -#define HAVE_extendsftf2 (TARGET_FPU) -#define HAVE_extenddftf2 (TARGET_FPU) -#define HAVE_truncdfsf2 (TARGET_FPU) -#define HAVE_trunctfsf2 (TARGET_FPU) -#define HAVE_trunctfdf2 (TARGET_FPU) -#define HAVE_floatsisf2 (TARGET_FPU) -#define HAVE_floatsidf2 (TARGET_FPU) -#define HAVE_floatsitf2 (TARGET_FPU) -#define HAVE_fix_truncsfsi2 (TARGET_FPU) -#define HAVE_fix_truncdfsi2 (TARGET_FPU) -#define HAVE_fix_trunctfsi2 (TARGET_FPU) -#define HAVE_adddi3 1 -#define HAVE_addsi3 1 -#define HAVE_subdi3 1 -#define HAVE_subsi3 1 -#define HAVE_mulsi3 (TARGET_V8 || TARGET_SPARCLITE) -#define HAVE_mulsidi3 (TARGET_V8 || TARGET_SPARCLITE) -#define HAVE_const_mulsidi3 (TARGET_V8 || TARGET_SPARCLITE) -#define HAVE_umulsidi3 (TARGET_V8 || TARGET_SPARCLITE) -#define HAVE_const_umulsidi3 (TARGET_V8 || TARGET_SPARCLITE) -#define HAVE_divsi3 (TARGET_V8) -#define HAVE_udivsi3 (TARGET_V8) -#define HAVE_anddi3 1 -#define HAVE_andsi3 1 -#define HAVE_iordi3 1 -#define HAVE_iorsi3 1 -#define HAVE_xordi3 1 -#define HAVE_xorsi3 1 -#define HAVE_negdi2 1 -#define HAVE_negsi2 1 -#define HAVE_one_cmpldi2 1 -#define HAVE_one_cmplsi2 1 -#define HAVE_addtf3 (TARGET_FPU) -#define HAVE_adddf3 (TARGET_FPU) -#define HAVE_addsf3 (TARGET_FPU) -#define HAVE_subtf3 (TARGET_FPU) -#define HAVE_subdf3 (TARGET_FPU) -#define HAVE_subsf3 (TARGET_FPU) -#define HAVE_multf3 (TARGET_FPU) -#define HAVE_muldf3 (TARGET_FPU) -#define HAVE_mulsf3 (TARGET_FPU) -#define HAVE_divtf3 (TARGET_FPU) -#define HAVE_divdf3 (TARGET_FPU) -#define HAVE_divsf3 (TARGET_FPU) -#define HAVE_negtf2 (TARGET_FPU) -#define HAVE_negdf2 (TARGET_FPU) -#define HAVE_negsf2 (TARGET_FPU) -#define HAVE_abstf2 (TARGET_FPU) -#define HAVE_absdf2 (TARGET_FPU) -#define HAVE_abssf2 (TARGET_FPU) -#define HAVE_sqrttf2 (TARGET_FPU) -#define HAVE_sqrtdf2 (TARGET_FPU) -#define HAVE_sqrtsf2 (TARGET_FPU) -#define HAVE_ashldi3 1 -#define HAVE_ashlsi3 1 -#define HAVE_lshldi3 1 -#define HAVE_ashrsi3 1 -#define HAVE_lshrsi3 1 -#define HAVE_lshrdi3 1 -#define HAVE_jump 1 -#define HAVE_tablejump 1 -#define HAVE_pic_tablejump 1 -#define HAVE_call 1 -#define HAVE_call_value 1 -#define HAVE_untyped_call 1 -#define HAVE_untyped_return 1 -#define HAVE_update_return 1 -#define HAVE_return (! TARGET_EPILOGUE) -#define HAVE_nop 1 -#define HAVE_indirect_jump 1 -#define HAVE_nonlocal_goto 1 -#define HAVE_flush_register_windows 1 -#define HAVE_goto_handler_and_restore 1 -#define HAVE_ffssi2 (TARGET_SPARCLITE) - -#ifndef NO_MD_PROTOTYPES -extern rtx gen_cmpsi PROTO((rtx, rtx)); -extern rtx gen_cmpsf PROTO((rtx, rtx)); -extern rtx gen_cmpdf PROTO((rtx, rtx)); -extern rtx gen_cmptf PROTO((rtx, rtx)); -extern rtx gen_seq_special PROTO((rtx, rtx, rtx)); -extern rtx gen_sne_special PROTO((rtx, rtx, rtx)); -extern rtx gen_seq PROTO((rtx)); -extern rtx gen_sne PROTO((rtx)); -extern rtx gen_sgt PROTO((rtx)); -extern rtx gen_slt PROTO((rtx)); -extern rtx gen_sge PROTO((rtx)); -extern rtx gen_sle PROTO((rtx)); -extern rtx gen_sgtu PROTO((rtx)); -extern rtx gen_sltu PROTO((rtx)); -extern rtx gen_sgeu PROTO((rtx)); -extern rtx gen_sleu PROTO((rtx)); -extern rtx gen_beq PROTO((rtx)); -extern rtx gen_bne PROTO((rtx)); -extern rtx gen_bgt PROTO((rtx)); -extern rtx gen_bgtu PROTO((rtx)); -extern rtx gen_blt PROTO((rtx)); -extern rtx gen_bltu PROTO((rtx)); -extern rtx gen_bge PROTO((rtx)); -extern rtx gen_bgeu PROTO((rtx)); -extern rtx gen_ble PROTO((rtx)); -extern rtx gen_bleu PROTO((rtx)); -extern rtx gen_movsi PROTO((rtx, rtx)); -extern rtx gen_reload_insi PROTO((rtx, rtx, rtx)); -extern rtx gen_movhi PROTO((rtx, rtx)); -extern rtx gen_movqi PROTO((rtx, rtx)); -extern rtx gen_movtf PROTO((rtx, rtx)); -extern rtx gen_movdf PROTO((rtx, rtx)); -extern rtx gen_movdi PROTO((rtx, rtx)); -extern rtx gen_movsf PROTO((rtx, rtx)); -extern rtx gen_zero_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_zero_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_extendhisi2 PROTO((rtx, rtx)); -extern rtx gen_extendqihi2 PROTO((rtx, rtx)); -extern rtx gen_extendqisi2 PROTO((rtx, rtx)); -extern rtx gen_extendsfdf2 PROTO((rtx, rtx)); -extern rtx gen_extendsftf2 PROTO((rtx, rtx)); -extern rtx gen_extenddftf2 PROTO((rtx, rtx)); -extern rtx gen_truncdfsf2 PROTO((rtx, rtx)); -extern rtx gen_trunctfsf2 PROTO((rtx, rtx)); -extern rtx gen_trunctfdf2 PROTO((rtx, rtx)); -extern rtx gen_floatsisf2 PROTO((rtx, rtx)); -extern rtx gen_floatsidf2 PROTO((rtx, rtx)); -extern rtx gen_floatsitf2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncsfsi2 PROTO((rtx, rtx)); -extern rtx gen_fix_truncdfsi2 PROTO((rtx, rtx)); -extern rtx gen_fix_trunctfsi2 PROTO((rtx, rtx)); -extern rtx gen_adddi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subdi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_const_mulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_umulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_const_umulsidi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_udivsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_anddi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_andsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iordi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_iorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xordi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_xorsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_negdi2 PROTO((rtx, rtx)); -extern rtx gen_negsi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmpldi2 PROTO((rtx, rtx)); -extern rtx gen_one_cmplsi2 PROTO((rtx, rtx)); -extern rtx gen_addtf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_adddf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_addsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subtf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_subsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_multf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_muldf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_mulsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divtf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divdf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_divsf3 PROTO((rtx, rtx, rtx)); -extern rtx gen_negtf2 PROTO((rtx, rtx)); -extern rtx gen_negdf2 PROTO((rtx, rtx)); -extern rtx gen_negsf2 PROTO((rtx, rtx)); -extern rtx gen_abstf2 PROTO((rtx, rtx)); -extern rtx gen_absdf2 PROTO((rtx, rtx)); -extern rtx gen_abssf2 PROTO((rtx, rtx)); -extern rtx gen_sqrttf2 PROTO((rtx, rtx)); -extern rtx gen_sqrtdf2 PROTO((rtx, rtx)); -extern rtx gen_sqrtsf2 PROTO((rtx, rtx)); -extern rtx gen_ashldi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashlsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshldi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_ashrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrsi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_lshrdi3 PROTO((rtx, rtx, rtx)); -extern rtx gen_jump PROTO((rtx)); -extern rtx gen_tablejump PROTO((rtx, rtx)); -extern rtx gen_pic_tablejump PROTO((rtx, rtx)); -extern rtx gen_untyped_call PROTO((rtx, rtx, rtx)); -extern rtx gen_untyped_return PROTO((rtx, rtx)); -extern rtx gen_update_return PROTO((rtx, rtx)); -extern rtx gen_return PROTO((void)); -extern rtx gen_nop PROTO((void)); -extern rtx gen_indirect_jump PROTO((rtx)); -extern rtx gen_nonlocal_goto PROTO((rtx, rtx, rtx, rtx)); -extern rtx gen_flush_register_windows PROTO((void)); -extern rtx gen_goto_handler_and_restore PROTO((void)); -extern rtx gen_ffssi2 PROTO((rtx, rtx)); - -#ifdef MD_CALL_PROTOTYPES -extern rtx gen_call PROTO((rtx, rtx)); -extern rtx gen_call_value PROTO((rtx, rtx, rtx)); - -#else /* !MD_CALL_PROTOTYPES */ -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* !MD_CALL_PROTOTYPES */ - -#else /* NO_MD_PROTOTYPES */ -extern rtx gen_cmpsi (); -extern rtx gen_cmpsf (); -extern rtx gen_cmpdf (); -extern rtx gen_cmptf (); -extern rtx gen_seq_special (); -extern rtx gen_sne_special (); -extern rtx gen_seq (); -extern rtx gen_sne (); -extern rtx gen_sgt (); -extern rtx gen_slt (); -extern rtx gen_sge (); -extern rtx gen_sle (); -extern rtx gen_sgtu (); -extern rtx gen_sltu (); -extern rtx gen_sgeu (); -extern rtx gen_sleu (); -extern rtx gen_beq (); -extern rtx gen_bne (); -extern rtx gen_bgt (); -extern rtx gen_bgtu (); -extern rtx gen_blt (); -extern rtx gen_bltu (); -extern rtx gen_bge (); -extern rtx gen_bgeu (); -extern rtx gen_ble (); -extern rtx gen_bleu (); -extern rtx gen_movsi (); -extern rtx gen_reload_insi (); -extern rtx gen_movhi (); -extern rtx gen_movqi (); -extern rtx gen_movtf (); -extern rtx gen_movdf (); -extern rtx gen_movdi (); -extern rtx gen_movsf (); -extern rtx gen_zero_extendhisi2 (); -extern rtx gen_zero_extendqihi2 (); -extern rtx gen_zero_extendqisi2 (); -extern rtx gen_extendhisi2 (); -extern rtx gen_extendqihi2 (); -extern rtx gen_extendqisi2 (); -extern rtx gen_extendsfdf2 (); -extern rtx gen_extendsftf2 (); -extern rtx gen_extenddftf2 (); -extern rtx gen_truncdfsf2 (); -extern rtx gen_trunctfsf2 (); -extern rtx gen_trunctfdf2 (); -extern rtx gen_floatsisf2 (); -extern rtx gen_floatsidf2 (); -extern rtx gen_floatsitf2 (); -extern rtx gen_fix_truncsfsi2 (); -extern rtx gen_fix_truncdfsi2 (); -extern rtx gen_fix_trunctfsi2 (); -extern rtx gen_adddi3 (); -extern rtx gen_addsi3 (); -extern rtx gen_subdi3 (); -extern rtx gen_subsi3 (); -extern rtx gen_mulsi3 (); -extern rtx gen_mulsidi3 (); -extern rtx gen_const_mulsidi3 (); -extern rtx gen_umulsidi3 (); -extern rtx gen_const_umulsidi3 (); -extern rtx gen_divsi3 (); -extern rtx gen_udivsi3 (); -extern rtx gen_anddi3 (); -extern rtx gen_andsi3 (); -extern rtx gen_iordi3 (); -extern rtx gen_iorsi3 (); -extern rtx gen_xordi3 (); -extern rtx gen_xorsi3 (); -extern rtx gen_negdi2 (); -extern rtx gen_negsi2 (); -extern rtx gen_one_cmpldi2 (); -extern rtx gen_one_cmplsi2 (); -extern rtx gen_addtf3 (); -extern rtx gen_adddf3 (); -extern rtx gen_addsf3 (); -extern rtx gen_subtf3 (); -extern rtx gen_subdf3 (); -extern rtx gen_subsf3 (); -extern rtx gen_multf3 (); -extern rtx gen_muldf3 (); -extern rtx gen_mulsf3 (); -extern rtx gen_divtf3 (); -extern rtx gen_divdf3 (); -extern rtx gen_divsf3 (); -extern rtx gen_negtf2 (); -extern rtx gen_negdf2 (); -extern rtx gen_negsf2 (); -extern rtx gen_abstf2 (); -extern rtx gen_absdf2 (); -extern rtx gen_abssf2 (); -extern rtx gen_sqrttf2 (); -extern rtx gen_sqrtdf2 (); -extern rtx gen_sqrtsf2 (); -extern rtx gen_ashldi3 (); -extern rtx gen_ashlsi3 (); -extern rtx gen_lshldi3 (); -extern rtx gen_ashrsi3 (); -extern rtx gen_lshrsi3 (); -extern rtx gen_lshrdi3 (); -extern rtx gen_jump (); -extern rtx gen_tablejump (); -extern rtx gen_pic_tablejump (); -extern rtx gen_untyped_call (); -extern rtx gen_untyped_return (); -extern rtx gen_update_return (); -extern rtx gen_return (); -extern rtx gen_nop (); -extern rtx gen_indirect_jump (); -extern rtx gen_nonlocal_goto (); -extern rtx gen_flush_register_windows (); -extern rtx gen_goto_handler_and_restore (); -extern rtx gen_ffssi2 (); -extern rtx gen_call (); -extern rtx gen_call_value (); -#endif /* NO_MD_PROTOTYPES */ diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-opinit.c b/gnu/usr.bin/gcc2/arch/sparc/insn-opinit.c deleted file mode 100644 index 9e59c002345..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-opinit.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Generated automatically by the program `genopinit' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "flags.h" -#include "insn-flags.h" -#include "insn-codes.h" -#include "insn-config.h" -#include "recog.h" -#include "expr.h" -#include "reload.h" - -void -init_all_optabs () -{ - cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi; - if (HAVE_cmpsf) - cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf; - if (HAVE_cmpdf) - cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf; - if (HAVE_cmptf) - cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf; - setcc_gen_code[(int) EQ] = CODE_FOR_seq; - setcc_gen_code[(int) NE] = CODE_FOR_sne; - setcc_gen_code[(int) GT] = CODE_FOR_sgt; - setcc_gen_code[(int) LT] = CODE_FOR_slt; - setcc_gen_code[(int) GE] = CODE_FOR_sge; - setcc_gen_code[(int) LE] = CODE_FOR_sle; - setcc_gen_code[(int) GTU] = CODE_FOR_sgtu; - setcc_gen_code[(int) LTU] = CODE_FOR_sltu; - setcc_gen_code[(int) GEU] = CODE_FOR_sgeu; - setcc_gen_code[(int) LEU] = CODE_FOR_sleu; - bcc_gen_fctn[(int) EQ] = gen_beq; - bcc_gen_fctn[(int) NE] = gen_bne; - bcc_gen_fctn[(int) GT] = gen_bgt; - bcc_gen_fctn[(int) GTU] = gen_bgtu; - bcc_gen_fctn[(int) LT] = gen_blt; - bcc_gen_fctn[(int) LTU] = gen_bltu; - bcc_gen_fctn[(int) GE] = gen_bge; - bcc_gen_fctn[(int) GEU] = gen_bgeu; - bcc_gen_fctn[(int) LE] = gen_ble; - bcc_gen_fctn[(int) LEU] = gen_bleu; - mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi; - reload_in_optab[(int) SImode] = CODE_FOR_reload_insi; - mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi; - mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi; - mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf; - mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf; - mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi; - mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf; - extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2; - extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2; - extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2; - extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2; - extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2; - extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2; - if (HAVE_extendsfdf2) - extendtab[(int) DFmode][(int) SFmode][0] = CODE_FOR_extendsfdf2; - if (HAVE_extendsftf2) - extendtab[(int) TFmode][(int) SFmode][0] = CODE_FOR_extendsftf2; - if (HAVE_extenddftf2) - extendtab[(int) TFmode][(int) DFmode][0] = CODE_FOR_extenddftf2; - if (HAVE_floatsisf2) - floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2; - if (HAVE_floatsidf2) - floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2; - if (HAVE_floatsitf2) - floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2; - if (HAVE_fix_truncsfsi2) - fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2; - if (HAVE_fix_truncdfsi2) - fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2; - if (HAVE_fix_trunctfsi2) - fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2; - add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3; - add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3; - sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3; - sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3; - if (HAVE_mulsi3) - smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3; - if (HAVE_mulsidi3) - smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3; - if (HAVE_umulsidi3) - umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3; - if (HAVE_divsi3) - sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3; - if (HAVE_udivsi3) - udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3; - and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3; - and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3; - ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3; - ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3; - xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3; - xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3; - neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2; - neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2; - one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2; - one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2; - if (HAVE_addtf3) - add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3; - if (HAVE_adddf3) - add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3; - if (HAVE_addsf3) - add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3; - if (HAVE_subtf3) - sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3; - if (HAVE_subdf3) - sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3; - if (HAVE_subsf3) - sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3; - if (HAVE_multf3) - smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3; - if (HAVE_muldf3) - smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3; - if (HAVE_mulsf3) - smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3; - if (HAVE_divtf3) - flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3; - if (HAVE_divdf3) - flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3; - if (HAVE_divsf3) - flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3; - if (HAVE_negtf2) - neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2; - if (HAVE_negdf2) - neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2; - if (HAVE_negsf2) - neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2; - if (HAVE_abstf2) - abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2; - if (HAVE_absdf2) - abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2; - if (HAVE_abssf2) - abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2; - if (HAVE_sqrttf2) - sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2; - if (HAVE_sqrtdf2) - sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2; - if (HAVE_sqrtsf2) - sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2; - ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3; - ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3; - lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3; - ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3; - lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3; - lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3; - if (HAVE_ffssi2) - ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2; -} diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-output.c b/gnu/usr.bin/gcc2/arch/sparc/insn-output.c deleted file mode 100644 index d20cdc8a760..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-output.c +++ /dev/null @@ -1,3890 +0,0 @@ -/* Generated automatically by the program `genoutput' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "real.h" -#include "insn-config.h" - -#include "conditions.h" -#include "insn-flags.h" -#include "insn-attr.h" - -#include "insn-codes.h" - -#include "recog.h" - -#include -#include "output.h" - -static char * -output_44 (operands, insn) - rtx *operands; - rtx insn; -{ - return output_scc_insn (operands, insn); -} - -static char * -output_55 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return output_cbranch (operands[0], 1, 0, - final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); -} -} - -static char * -output_56 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return output_cbranch (operands[0], 1, 1, - final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); -} -} - -static char * -output_59 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_59[] = { - "mov %1,%0", - "fmovs %1,%0", - "sethi %%hi(%a1),%0", - "ld %1,%0", - "ld %1,%0", - "st %r1,%0", - "st %r1,%0", - }; - return strings_59[which_alternative]; -} - -static char * -output_61 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - - if (GET_CODE (op1) == CONST_INT) - { - operands[0] = operand_subword (op0, 1, 0, DImode); - output_asm_insn ("sethi %%hi(%a1),%0", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - if (INTVAL (op1) < 0) - return "mov -1,%0"; - else - return "mov 0,%0"; - } - else if (GET_CODE (op1) == CONST_DOUBLE) - { - operands[0] = operand_subword (op0, 1, 0, DImode); - operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); - output_asm_insn ("sethi %%hi(%a1),%0", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); - return singlemove_string (operands); - } - else - abort (); - return ""; -} -} - -static char * -output_65 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* Don't output a 64 bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); - return "or %R1,%%lo(%a2),%R0"; -} -} - -static char * -output_70 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_70[] = { - "mov %1,%0", - "sethi %%hi(%a1),%0", - "lduh %1,%0", - "sth %r1,%0", - }; - return strings_70[which_alternative]; -} - -static char * -output_74 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_74[] = { - "mov %1,%0", - "sethi %%hi(%a1),%0", - "ldub %1,%0", - "stb %r1,%0", - }; - return strings_74[which_alternative]; -} - -static char * -output_77 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - switch (which_alternative) - { - case 0: - return output_move_quad (operands); - case 1: - return output_fp_move_quad (operands); - case 2: - operands[1] = adj_offsettable_operand (operands[0], 4); - operands[2] = adj_offsettable_operand (operands[0], 8); - operands[3] = adj_offsettable_operand (operands[0], 12); - return "st %%g0,%0\n\tst %%g0,%1\n\tst %%g0,%2\n\tst %%g0,%3"; - } -} -} - -static char * -output_79 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -} -} - -static char * -output_80 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -} -} - -static char * -output_81 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - output_asm_insn ("sethi %%hi(%a0),%2", operands); - if (which_alternative == 0) - return "std %1,[%2+%%lo(%a0)]\n\tstd %S1,[%2+%%lo(%a0+8)]"; - else - return "st %%g0,[%2+%%lo(%a0)]\n\tst %%g0,[%2+%%lo(%a0+4)]\n\t st %%g0,[%2+%%lo(%a0+8)]\n\tst %%g0,[%2+%%lo(%a0+12)]"; -} -} - -static char * -output_82 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - switch (which_alternative) - { - case 0: - return output_move_double (operands); - case 1: - return output_fp_move_double (operands); - case 2: - operands[1] = adj_offsettable_operand (operands[0], 4); - return "st %%g0,%0\n\tst %%g0,%1"; - } -} -} - -static char * -output_84 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -} -} - -static char * -output_85 (operands, insn) - rtx *operands; - rtx insn; -{ - return output_move_double (operands); -} - -static char * -output_87 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - output_asm_insn ("sethi %%hi(%a0),%2", operands); - if (which_alternative == 0) - return "std %1,[%2+%%lo(%a0)]"; - else - return "st %%g0,[%2+%%lo(%a0)]\n\tst %%g0,[%2+%%lo(%a0+4)]"; -} -} - -static char * -output_89 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -} -} - -static char * -output_90 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - switch (which_alternative) - { - case 0: - return singlemove_string (operands); - case 1: - return "ld %1,%0"; - case 2: - return "st %%g0,%0"; - } -} -} - -static char * -output_92 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_92[] = { - "fmovs %1,%0", - "mov %1,%0", - "ld %1,%0", - "ld %1,%0", - "st %r1,%0", - "st %r1,%0", - }; - return strings_92[which_alternative]; -} - -static char * -output_93 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_93[] = { - "mov %1,%0", - "ld %1,%0", - "st %r1,%0", - }; - return strings_93[which_alternative]; -} - -static char * -output_98 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_98[] = { - "and %1,0xff,%0", - "ldub %1,%0", - }; - return strings_98[which_alternative]; -} - -static char * -output_100 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_100[] = { - "and %1,0xff,%0", - "ldub %1,%0", - }; - return strings_100[which_alternative]; -} - -static char * -output_111 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - int len = INTVAL (operands[1]); - int pos = 32 - INTVAL (operands[2]) - len; - unsigned mask = ((1 << len) - 1) << pos; - - operands[1] = gen_rtx (CONST_INT, VOIDmode, mask); - return "andcc %0,%1,%%g0"; -} -} - -static char * -output_124 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return "addcc %R1,%2,%R0\n\taddx %1,-1,%0"; - return "addcc %R1,%2,%R0\n\taddx %1,0,%0"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "addcc %R1,%2,%R0\n\taddx %1,-1,%0"; - return "addcc %R1,%2,%R0\n\taddx %1,0,%0"; - } - return "addcc %R1,%R2,%R0\n\taddx %1,%2,%0"; -} -} - -static char * -output_128 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return "subcc %R1,%2,%R0\n\tsubx %1,-1,%0"; - return "subcc %R1,%2,%R0\n\tsubx %1,0,%0"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "subcc %R1,%2,%R0\n\tsubx %1,-1,%0"; - return "subcc %R1,%2,%R0\n\tsubx %1,0,%0"; - } - return "subcc %R1,%R2,%R0\n\tsubx %1,%2,%0"; -} -} - -static char * -output_145 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return "mov %1,%0\n\tand %R1,%2,%R0"; - return "mov 0,%0\n\tand %R1,%2,%R0"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "mov %1,%0\n\tand %R1,%2,%R0"; - return "mov 0,%0\n\tand %R1,%2,%R0"; - } - return "and %1,%2,%0\n\tand %R1,%R2,%R0"; -} -} - -static char * -output_151 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return "mov -1,%0\n\tor %R1,%2,%R0"; - return "mov %1,%0\n\tor %R1,%2,%R0"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "mov -1,%0\n\tor %R1,%2,%R0"; - return "mov %1,%0\n\tor %R1,%2,%R0"; - } - return "or %1,%2,%0\n\tor %R1,%R2,%R0"; -} -} - -static char * -output_157 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return "xor %1,-1,%0\n\txor %R1,%2,%R0"; - return "mov %1,%0\n\txor %R1,%2,%R0"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "xor %1,-1,%0\n\txor %R1,%2,%R0"; - return "mov %1,%0\n\txor %R1,%2,%R0"; - } - return "xor %1,%2,%0\n\txor %R1,%R2,%R0"; -} -} - -static char * -output_174 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - rtx op1 = operands[1]; - - if (GET_CODE (op1) == CONST_INT) - { - int sign = INTVAL (op1); - if (sign < 0) - return "xnor %%g0,%1,%R0\n\txnor %%g0,-1,%0"; - return "xnor %%g0,%1,%R0\n\txnor %%g0,0,%0"; - } - else if (GET_CODE (op1) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op1); - operands[1] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return "xnor %%g0,%1,%R0\n\txnor %%g0,-1,%0"; - return "xnor %%g0,%1,%R0\n\txnor %%g0,0,%0"; - } - return "xnor %%g0,%1,%0\n\txnor %%g0,%R1,%R0"; -} -} - -static char * -output_192 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_192[] = { - "fnegs %0,%0", - "fnegs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0", - }; - return strings_192[which_alternative]; -} - -static char * -output_193 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_193[] = { - "fnegs %0,%0", - "fnegs %1,%0\n\tfmovs %R1,%R0", - }; - return strings_193[which_alternative]; -} - -static char * -output_195 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_195[] = { - "fabss %0,%0", - "fabss %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0", - }; - return strings_195[which_alternative]; -} - -static char * -output_196 (operands, insn) - rtx *operands; - rtx insn; -{ - static /*const*/ char *const strings_196[] = { - "fabss %0,%0", - "fabss %1,%0\n\tfmovs %R1,%R0", - }; - return strings_196[which_alternative]; -} - -static char * -output_205 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[4] = GEN_INT (32 - INTVAL (operands[2])); - return "srl %R1,%4,%3\n\tsll %R1,%2,%R0\n\tsll %1,%2,%0\n\tor %3,%0,%0"; -} -} - -static char * -output_206 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[4] = GEN_INT (INTVAL (operands[2]) - 32); - return "sll %R1,%4,%0\n\tmov %%g0,%R0"; -} -} - -static char * -output_210 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[4] = GEN_INT (32 - INTVAL (operands[2])); - return "sll %1,%4,%3\n\tsrl %1,%2,%0\n\tsrl %R1,%2,%R0\n\tor %3,%R0,%R0"; -} -} - -static char * -output_211 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[4] = GEN_INT (INTVAL (operands[2]) - 32); - return "srl %1,%4,%R0\n\tmov %%g0,%0"; -} -} - -static char * -output_218 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "call %a0,%1%#"; -} -} - -static char * -output_219 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "call %a0,%1\n\tnop\n\tunimp %2"; -} -} - -static char * -output_221 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "call %a1,%2%#"; -} -} - -static char * -output_223 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - operands[2] = adj_offsettable_operand (operands[1], 8); - return "call %a0,0\n\tnop\n\tnop\n\tstd %%o0,%1\n\tst %%f0,%2"; -} -} - -static char * -output_226 (operands, insn) - rtx *operands; - rtx insn; -{ - return output_return (operands); -} - -static char * -output_258 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - warning ("bad peephole"); - if (! MEM_VOLATILE_P (operands[1])) - abort (); - return "ldsh %1,%2"; -} -} - -static char * -output_259 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - warning ("bad peephole"); - if (! MEM_VOLATILE_P (operands[1])) - abort (); - return "ldsb %1,%2"; -} -} - -static char * -output_260 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - /* Go by way of output_move_double in case the register in operand 2 - is not properly aligned for ldd. */ - operands[1] = gen_rtx (MEM, DFmode, - gen_rtx (LO_SUM, SImode, operands[0], operands[1])); - operands[0] = operands[2]; - return output_move_double (operands); -} -} - -static char * -output_262 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore %%g0,%1,%Y0"; - else - return "ret\n\trestore %%g0,%1,%Y0"; -} -} - -static char * -output_263 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore %%g0,%1,%Y0"; - else - return "ret\n\trestore %%g0,%1,%Y0"; -} -} - -static char * -output_264 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore %%g0,%1,%Y0"; - else - return "ret\n\trestore %%g0,%1,%Y0"; -} -} - -static char * -output_265 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore %%g0,%1,%Y0"; - else - return "ret\n\trestore %%g0,%1,%Y0"; -} -} - -static char * -output_266 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - if (current_function_returns_struct) - return "jmp %%i7+12\n\trestore %r1,%2,%Y0"; - else - return "ret\n\trestore %r1,%2,%Y0"; -} -} - -static char * -output_268 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "call %a1,%2\n\tadd %%o7,(%l3-.-4),%%o7"; -} -} - -static char * -output_269 (operands, insn) - rtx *operands; - rtx insn; -{ - -{ - return "call %a0,%1\n\tadd %%o7,(%l2-.-4),%%o7"; -} -} - -char * const insn_template[] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "cmp %r0,%1", - "fcmped %0,%1", - "fcmpes %0,%1", - "fcmpeq %0,%1", - "fcmpd %0,%1", - "fcmps %0,%1", - "fcmpq %0,%1", - "subcc %%g0,%1,%%g0\n\taddx %%g0,0,%0", - "subcc %%g0,%1,%%g0\n\tsubx %%g0,0,%0", - "subcc %%g0,%1,%%g0\n\tsubx %%g0,-1,%0", - "subcc %%g0,%1,%%g0\n\taddx %%g0,-1,%0", - "subcc %%g0,%1,%%g0\n\taddx %2,0,%0", - "subcc %%g0,%1,%%g0\n\tsubx %2,0,%0", - "subcc %%g0,%1,%%g0\n\tsubx %2,-1,%0", - "subcc %%g0,%1,%%g0\n\taddx %2,-1,%0", - "addx %%g0,0,%0", - "subx %%g0,0,%0", - "subx %%g0,%1,%0", - "subx %%g0,%1,%0", - "subx %%g0,-1,%0", - "addx %%g0,-1,%0", - "addx %%g0,%1,%0", - "addx %1,%2,%0", - "subx %1,0,%0", - "subx %1,%2,%0", - "subx %1,%2,%0", - "subx %1,-1,%0", - "addx %1,-1,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "\n1:\n\tcall 2f\n\tsethi %%hi(%l1-1b),%0\n2:\tor %0,%%lo(%l1-1b),%0\n\tadd %0,%%o7,%0", - 0, - "sethi %%hi(%a1),%0", - "sethi %%hi(%a1),%0", - "sethi %%hi(%a1),%0", - 0, - "or %1,%%lo(%a2),%0", - "or %1,%%lo(%a2),%0", - "sethi %%hi(%a0),%2\n\tst %r1,[%2+%%lo(%a0)]", - 0, - 0, - "or %1,%%lo(%a2),%0", - "sethi %%hi(%a0),%2\n\tsth %r1,[%2+%%lo(%a0)]", - 0, - 0, - "or %1,%%lo(%a2),%0", - "sethi %%hi(%a0),%2\n\tstb %r1,[%2+%%lo(%a0)]", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "sethi %%hi(%a0),%2\n\tst %r1,[%2+%%lo(%a0)]", - 0, - "lduh %1,%0", - 0, - 0, - 0, - 0, - "andcc %0,0xff,%%g0", - "andcc %1,0xff,%0", - "andcc %0,0xff,%%g0", - "andcc %1,0xff,%0", - 0, - "ldsh %1,%0", - 0, - "ldsb %1,%0", - 0, - "ldsb %1,%0", - 0, - "fstod %1,%0", - "fstoq %1,%0", - "fdtoq %1,%0", - "fdtos %1,%0", - "fqtos %1,%0", - "fqtod %1,%0", - "fitos %1,%0", - "fitod %1,%0", - "fitoq %1,%0", - "fstoi %1,%0", - "fdtoi %1,%0", - "fqtoi %1,%0", - 0, - "add %1,%2,%0", - "addcc %0,%1,%%g0", - "addcc %1,%2,%0", - 0, - "sub %1,%2,%0", - "subcc %0,%1,%%g0", - "subcc %1,%2,%0", - "smul %1,%2,%0", - "smulcc %1,%2,%0", - 0, - "smul %1,%2,%R0\n\trd %%y,%0", - "smul %1,%2,%R0\n\trd %%y,%0", - 0, - "umul %1,%2,%R0\n\trd %%y,%0", - "umul %1,%2,%R0\n\trd %%y,%0", - "sra %1,31,%3\n\twr %%g0,%3,%%y\n\tnop\n\tnop\n\tnop\n\tsdiv %1,%2,%0", - "sra %1,31,%3\n\twr %%g0,%3,%%y\n\tnop\n\tnop\n\tnop\n\tsdivcc %1,%2,%0", - "wr %%g0,%%g0,%%y\n\tnop\n\tnop\n\tnop\n\tudiv %1,%2,%0", - "wr %%g0,%%g0,%%y\n\tnop\n\tnop\n\tnop\n\tudivcc %1,%2,%0", - 0, - 0, - "and %1,%2,%0", - 0, - "andn %2,%1,%0\n\tandn %R2,%R1,%R0", - "andn %2,%1,%0", - 0, - 0, - "or %1,%2,%0", - 0, - "orn %2,%1,%0\n\torn %R2,%R1,%R0", - "orn %2,%1,%0", - 0, - 0, - "xor %r1,%2,%0", - 0, - 0, - "xnor %1,%2,%0\n\txnor %R1,%R2,%R0", - "xnor %r1,%2,%0", - "%A2cc %0,%1,%%g0", - "%A3cc %1,%2,%0", - "xnorcc %r0,%1,%%g0", - "xnorcc %r1,%2,%0", - "%B2cc %r1,%0,%%g0", - "%B3cc %r2,%1,%0", - "subcc %%g0,%R1,%R0\n\tsubx %%g0,%1,%0", - "sub %%g0,%1,%0", - "subcc %%g0,%0,%%g0", - "subcc %%g0,%1,%0", - 0, - 0, - "xnor %%g0,%1,%0", - "xnorcc %%g0,%0,%%g0", - "xnorcc %%g0,%1,%0", - "faddq %1,%2,%0", - "faddd %1,%2,%0", - "fadds %1,%2,%0", - "fsubq %1,%2,%0", - "fsubd %1,%2,%0", - "fsubs %1,%2,%0", - "fmulq %1,%2,%0", - "fmuld %1,%2,%0", - "fmuls %1,%2,%0", - "fsmuld %1,%2,%0", - "fdmulq %1,%2,%0", - "fdivq %1,%2,%0", - "fdivd %1,%2,%0", - "fdivs %1,%2,%0", - 0, - 0, - "fnegs %1,%0", - 0, - 0, - "fabss %1,%0", - "fsqrtq %1,%0", - "fsqrtd %1,%0", - "fsqrts %1,%0", - 0, - "subcc %1,32,%%g0\n\taddx %%g0,0,%R0\n\txor %R0,1,%0\n\tsll %R0,%1,%R0\n\tsll %0,%1,%0", - "sll %1,%2,%0", - 0, - 0, - 0, - "sra %1,%2,%0", - "srl %1,%2,%0", - 0, - 0, - 0, - "b%* %l0%(", - 0, - "jmp %%o7+%0%#", - "jmp %a0%#", - "call %l0%#", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "cmp %1,0\n\tbe,a .+8\n\tadd %0,4,%0", - 0, - "nop", - "jmp %a0%#", - 0, - "ta 3", - "jmp %%o0+0\n\trestore", - "sub %%g0,%1,%0\n\tand %0,%1,%0\n\tscan %0,0,%0\n\tmov 32,%2\n\tsub %2,%0,%0\n\tsra %0,31,%2\n\tand %2,31,%2\n\tadd %2,%0,%0", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "ldd %1,%0", - "std %1,%0", - "ldd %1,%0", - "std %1,%0", - "ldd %3,%2", - "std %3,%2", - "ldd %3,%2", - "std %3,%2", - "orcc %1,%%g0,%0", - "ldsh %1,%0\n\torcc %0,%%g0,%2", - "ldsb %1,%0\n\torcc %0,%%g0,%2", - 0, - 0, - 0, - "ld [%0+%%lo(%a1)],%2", - 0, - 0, - 0, - 0, - 0, - "ret\n\tfmovs %0,%%f0", - 0, - 0, - "subxcc %r1,0,%0", - }; - -char *(*const insn_outfun[])() = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_44, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_55, - output_56, - 0, - 0, - output_59, - 0, - output_61, - 0, - 0, - 0, - output_65, - 0, - 0, - 0, - 0, - output_70, - 0, - 0, - 0, - output_74, - 0, - 0, - output_77, - 0, - output_79, - output_80, - output_81, - output_82, - 0, - output_84, - output_85, - 0, - output_87, - 0, - output_89, - output_90, - 0, - output_92, - output_93, - 0, - 0, - 0, - 0, - output_98, - 0, - output_100, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_111, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_124, - 0, - 0, - 0, - output_128, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_145, - 0, - 0, - 0, - 0, - 0, - output_151, - 0, - 0, - 0, - 0, - 0, - output_157, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_174, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_192, - output_193, - 0, - output_195, - output_196, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_205, - output_206, - 0, - 0, - 0, - output_210, - output_211, - 0, - 0, - 0, - 0, - 0, - 0, - output_218, - output_219, - 0, - output_221, - 0, - output_223, - 0, - 0, - output_226, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - output_258, - output_259, - output_260, - 0, - output_262, - output_263, - output_264, - output_265, - output_266, - 0, - output_268, - output_269, - 0, - }; - -rtx (*const insn_gen_function[]) () = - { - gen_cmpsi, - gen_cmpsf, - gen_cmpdf, - gen_cmptf, - gen_seq_special, - gen_sne_special, - gen_seq, - gen_sne, - gen_sgt, - gen_slt, - gen_sge, - gen_sle, - gen_sgtu, - gen_sltu, - gen_sgeu, - gen_sleu, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_beq, - gen_bne, - gen_bgt, - gen_bgtu, - gen_blt, - gen_bltu, - gen_bge, - gen_bgeu, - gen_ble, - gen_bleu, - 0, - 0, - gen_movsi, - gen_reload_insi, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_movhi, - 0, - 0, - 0, - gen_movqi, - 0, - 0, - 0, - 0, - gen_movtf, - 0, - 0, - 0, - 0, - gen_movdf, - 0, - 0, - 0, - 0, - gen_movdi, - 0, - 0, - gen_movsf, - 0, - 0, - 0, - gen_zero_extendhisi2, - 0, - gen_zero_extendqihi2, - 0, - gen_zero_extendqisi2, - 0, - 0, - 0, - 0, - 0, - gen_extendhisi2, - 0, - gen_extendqihi2, - 0, - gen_extendqisi2, - 0, - 0, - gen_extendsfdf2, - gen_extendsftf2, - gen_extenddftf2, - gen_truncdfsf2, - gen_trunctfsf2, - gen_trunctfdf2, - gen_floatsisf2, - gen_floatsidf2, - gen_floatsitf2, - gen_fix_truncsfsi2, - gen_fix_truncdfsi2, - gen_fix_trunctfsi2, - gen_adddi3, - gen_addsi3, - 0, - 0, - gen_subdi3, - gen_subsi3, - 0, - 0, - gen_mulsi3, - 0, - gen_mulsidi3, - 0, - gen_const_mulsidi3, - gen_umulsidi3, - 0, - gen_const_umulsidi3, - gen_divsi3, - 0, - gen_udivsi3, - 0, - gen_anddi3, - 0, - gen_andsi3, - 0, - 0, - 0, - gen_iordi3, - 0, - gen_iorsi3, - 0, - 0, - 0, - gen_xordi3, - 0, - gen_xorsi3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - gen_negdi2, - gen_negsi2, - 0, - 0, - gen_one_cmpldi2, - 0, - gen_one_cmplsi2, - 0, - 0, - gen_addtf3, - gen_adddf3, - gen_addsf3, - gen_subtf3, - gen_subdf3, - gen_subsf3, - gen_multf3, - gen_muldf3, - gen_mulsf3, - 0, - 0, - gen_divtf3, - gen_divdf3, - gen_divsf3, - gen_negtf2, - gen_negdf2, - gen_negsf2, - gen_abstf2, - gen_absdf2, - gen_abssf2, - gen_sqrttf2, - gen_sqrtdf2, - gen_sqrtsf2, - gen_ashldi3, - 0, - gen_ashlsi3, - gen_lshldi3, - 0, - 0, - gen_ashrsi3, - gen_lshrsi3, - gen_lshrdi3, - 0, - 0, - gen_jump, - gen_tablejump, - gen_pic_tablejump, - 0, - 0, - gen_call, - 0, - 0, - gen_call_value, - 0, - gen_untyped_call, - 0, - gen_untyped_return, - gen_update_return, - gen_return, - gen_nop, - gen_indirect_jump, - gen_nonlocal_goto, - gen_flush_register_windows, - gen_goto_handler_and_restore, - gen_ffssi2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *insn_name[] = - { - "cmpsi", - "cmpsf", - "cmpdf", - "cmptf", - "seq_special", - "sne_special", - "seq", - "sne", - "sgt", - "slt", - "sge", - "sle", - "sgtu", - "sltu", - "sgeu", - "sleu", - "sleu+1", - "sleu+2", - "sleu+3", - "sleu+4", - "sleu+5", - "sleu+6", - "sleu+7", - "sleu+8", - "sleu+9", - "sleu+10", - "sleu+11", - "sleu+12", - "sleu+13", - "sleu+14", - "sleu+15", - "beq-14", - "beq-13", - "beq-12", - "beq-11", - "beq-10", - "beq-9", - "beq-8", - "beq-7", - "beq-6", - "beq-5", - "beq-4", - "beq-3", - "beq-2", - "beq-1", - "beq", - "bne", - "bgt", - "bgtu", - "blt", - "bltu", - "bge", - "bgeu", - "ble", - "bleu", - "bleu+1", - "movsi-1", - "movsi", - "reload_insi", - "reload_insi+1", - "reload_insi+2", - "reload_insi+3", - "reload_insi+4", - "reload_insi+5", - "movhi-5", - "movhi-4", - "movhi-3", - "movhi-2", - "movhi-1", - "movhi", - "movhi+1", - "movhi+2", - "movqi-1", - "movqi", - "movqi+1", - "movqi+2", - "movtf-2", - "movtf-1", - "movtf", - "movtf+1", - "movtf+2", - "movdf-2", - "movdf-1", - "movdf", - "movdf+1", - "movdf+2", - "movdi-2", - "movdi-1", - "movdi", - "movdi+1", - "movsf-1", - "movsf", - "movsf+1", - "movsf+2", - "zero_extendhisi2-1", - "zero_extendhisi2", - "zero_extendhisi2+1", - "zero_extendqihi2", - "zero_extendqihi2+1", - "zero_extendqisi2", - "zero_extendqisi2+1", - "zero_extendqisi2+2", - "zero_extendqisi2+3", - "extendhisi2-2", - "extendhisi2-1", - "extendhisi2", - "extendhisi2+1", - "extendqihi2", - "extendqihi2+1", - "extendqisi2", - "extendqisi2+1", - "extendsfdf2-1", - "extendsfdf2", - "extendsftf2", - "extenddftf2", - "truncdfsf2", - "trunctfsf2", - "trunctfdf2", - "floatsisf2", - "floatsidf2", - "floatsitf2", - "fix_truncsfsi2", - "fix_truncdfsi2", - "fix_trunctfsi2", - "adddi3", - "addsi3", - "addsi3+1", - "subdi3-1", - "subdi3", - "subsi3", - "subsi3+1", - "mulsi3-1", - "mulsi3", - "mulsi3+1", - "mulsidi3", - "mulsidi3+1", - "const_mulsidi3", - "umulsidi3", - "umulsidi3+1", - "const_umulsidi3", - "divsi3", - "divsi3+1", - "udivsi3", - "udivsi3+1", - "anddi3", - "anddi3+1", - "andsi3", - "andsi3+1", - "andsi3+2", - "iordi3-1", - "iordi3", - "iordi3+1", - "iorsi3", - "iorsi3+1", - "iorsi3+2", - "xordi3-1", - "xordi3", - "xordi3+1", - "xorsi3", - "xorsi3+1", - "xorsi3+2", - "xorsi3+3", - "xorsi3+4", - "xorsi3+5", - "negdi2-5", - "negdi2-4", - "negdi2-3", - "negdi2-2", - "negdi2-1", - "negdi2", - "negsi2", - "negsi2+1", - "one_cmpldi2-1", - "one_cmpldi2", - "one_cmpldi2+1", - "one_cmplsi2", - "one_cmplsi2+1", - "addtf3-1", - "addtf3", - "adddf3", - "addsf3", - "subtf3", - "subdf3", - "subsf3", - "multf3", - "muldf3", - "mulsf3", - "mulsf3+1", - "divtf3-1", - "divtf3", - "divdf3", - "divsf3", - "negtf2", - "negdf2", - "negsf2", - "abstf2", - "absdf2", - "abssf2", - "sqrttf2", - "sqrtdf2", - "sqrtsf2", - "ashldi3", - "ashldi3+1", - "ashlsi3", - "lshldi3", - "lshldi3+1", - "ashrsi3-1", - "ashrsi3", - "lshrsi3", - "lshrdi3", - "lshrdi3+1", - "jump-1", - "jump", - "tablejump", - "pic_tablejump", - "pic_tablejump+1", - "call-1", - "call", - "call+1", - "call_value-1", - "call_value", - "call_value+1", - "untyped_call", - "untyped_call+1", - "untyped_return", - "update_return", - "return", - "nop", - "indirect_jump", - "nonlocal_goto", - "flush_register_windows", - "goto_handler_and_restore", - "ffssi2", - "ffssi2+1", - "ffssi2+2", - "ffssi2+3", - "ffssi2+4", - "ffssi2+5", - "ffssi2+6", - "ffssi2+7", - "ffssi2+8", - "ffssi2+9", - "ffssi2+10", - "ffssi2+11", - "ffssi2+12", - "ffssi2+13", - "ffssi2+14", - "ffssi2+15", - "ffssi2+16", - "ffssi2+17", - "ffssi2+18", - "ffssi2+19", - "ffssi2+20", - "ffssi2+21", - "ffssi2+22", - "ffssi2+23", - "ffssi2+24", - "ffssi2+25", - "ffssi2+26", - "ffssi2+27", - "ffssi2+28", - "ffssi2+29", - "ffssi2+30", - "ffssi2+31", - "ffssi2+32", - "ffssi2+33", - "ffssi2+34", - "ffssi2+35", - "ffssi2+36", - "ffssi2+37", - "ffssi2+38", - }; -char **insn_name_ptr = insn_name; - -const int insn_n_operands[] = - { - 2, - 2, - 2, - 2, - 3, - 3, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 1, - 1, - 2, - 2, - 1, - 1, - 2, - 3, - 2, - 3, - 3, - 2, - 2, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 2, - 2, - 3, - 3, - 2, - 2, - 3, - 3, - 2, - 2, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 2, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 2, - 3, - 3, - 3, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 3, - 3, - 3, - 3, - 3, - 4, - 3, - 3, - 3, - 3, - 3, - 4, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 3, - 3, - 3, - 4, - 2, - 3, - 3, - 4, - 2, - 2, - 1, - 2, - 2, - 2, - 2, - 1, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 2, - 3, - 4, - 4, - 4, - 3, - 3, - 4, - 4, - 4, - 0, - 1, - 1, - 1, - 0, - 4, - 2, - 3, - 5, - 3, - 3, - 3, - 2, - 2, - 0, - 0, - 1, - 4, - 0, - 0, - 3, - 4, - 4, - 3, - 4, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 2, - 2, - 2, - 2, - 3, - 1, - 3, - 2, - 2, - }; - -const int insn_n_dups[] = - { - 0, - 0, - 0, - 0, - 2, - 2, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 0, - 0, - 0, - 2, - 0, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 2, - 0, - 2, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }; - -char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] = - { - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", "", }, - { "", "", "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "", }, - { "r", "rI", }, - { "f", "f", }, - { "f", "f", }, - { "f", "f", }, - { "f", "f", }, - { "f", "f", }, - { "f", "f", }, - { "=r", "r", }, - { "=r", "r", }, - { "=r", "r", }, - { "=r", "r", }, - { "=r", "r", "r", }, - { "=r", "r", "r", }, - { "=r", "r", "r", }, - { "=r", "r", "r", }, - { "=r", }, - { "=r", }, - { "=r", "rI", }, - { "=r", "rI", }, - { "=r", }, - { "=r", }, - { "=r", "rI", }, - { "=r", "%r", "rI", }, - { "=r", "r", }, - { "=r", "r", "rI", }, - { "=r", "r", "rI", }, - { "=r", "r", }, - { "=r", "r", }, - { "=r", "", }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { "", }, - { "", }, - { "", "", }, - { "=r", "", "=&r", }, - { "=r,f,r,r,f,Q,Q", "rI,!f,K,Q,!Q,rJ,!f", }, - { "=r", "i", }, - { "=r", "", }, - { "=r", "", }, - { "=r", "", }, - { "=r", "", }, - { "=r", "0", "in", }, - { "=r", "r", "in", }, - { "=r", "r", "in", }, - { "", "rJ", "=&r", }, - { "", "", }, - { "=r,r,r,Q", "rI,K,Q,rJ", }, - { "=r", "r", "in", }, - { "", "rJ", "=&r", }, - { "", "", }, - { "=r,r,r,Q", "rI,K,Q,rJ", }, - { "=r", "r", "in", }, - { "", "rJ", "=&r", }, - { "=?r,f,o", "?E,m,G", }, - { "", "", }, - { "=f,r,Q,Q,f,&r", "f,r,f,r,Q,Q", }, - { "=r,Q,&r", "r,r,Q", }, - { "i,i", "rf,G", "=&r,&r", }, - { "=?r,f,o", "?E,m,G", }, - { "", "", }, - { "=T,U,f,r,Q,Q,f,&r", "U,T,f,r,f,r,Q,Q", }, - { "=T,U,r,Q,&r", "U,T,r,r,Q", }, - { "", "", }, - { "i,i", "rf,G", "=&r,&r", }, - { "", "", }, - { "=r,Q,&r,&r,?f,?f,?Q", "r,r,Q,i,f,Q,f", }, - { "=?r,f,m", "?E,m,G", }, - { "", "", }, - { "=f,r,f,r,Q,Q", "f,r,Q,Q,f,r", }, - { "=r,r,Q", "r,Q,r", }, - { "i", "rfG", "=&r", }, - { "", "", }, - { "=r", "m", }, - { "", "", }, - { "=r,r", "r,Q", }, - { "", "", }, - { "=r,r", "r,Q", }, - { "r", }, - { "=r", "r", }, - { "r", }, - { "=r", "r", }, - { "", "", }, - { "=r", "m", }, - { "", "", }, - { "=r", "m", }, - { "", "", }, - { "=r", "m", }, - { "r", "n", "n", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=r", "%r", "rHI", }, - { "=r", "%r", "rI", }, - { "%r", "rI", }, - { "=r", "%r", "rI", }, - { "=r", "r", "rHI", }, - { "=r", "r", "rI", }, - { "r", "rI", }, - { "=r", "r", "rI", }, - { "=r", "%r", "rI", }, - { "=r", "%r", "rI", }, - { "", "", "", }, - { "=r", "r", "r", }, - { "=r", "r", "I", }, - { "", "", "", }, - { "=r", "r", "r", }, - { "=r", "r", "I", }, - { "=r", "r", "rI", "=&r", }, - { "=r", "r", "rI", "=&r", }, - { "=r", "r", "rI", }, - { "=r", "r", "rI", }, - { "", "", "", }, - { "=r", "%r", "rHI", }, - { "=r", "%r", "rI", }, - { "", "", "", "", }, - { "=r", "r", "r", }, - { "=r", "r", "r", }, - { "", "", "", }, - { "=r", "%r", "rHI", }, - { "=r", "%r", "rI", }, - { "", "", "", "", }, - { "=r", "r", "r", }, - { "=r", "r", "r", }, - { "", "", "", }, - { "=r", "%r", "rHI", }, - { "=r", "%rJ", "rI", }, - { "", "", "", "", }, - { "", "", "", "", }, - { "=r", "r", "r", }, - { "=r", "rJ", "rI", }, - { "%r", "rI", "", }, - { "=r", "%r", "rI", "", }, - { "%rJ", "rI", }, - { "=r", "%rJ", "rI", }, - { "rI", "rJ", "", }, - { "=r", "rI", "rJ", "", }, - { "=r", "r", }, - { "=r", "rI", }, - { "rI", }, - { "=r", "rI", }, - { "=r", "rHI", }, - { "=r", "rHI", }, - { "=r", "rI", }, - { "rI", }, - { "=r", "rI", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f", "f", "f", }, - { "=f,f", "0,f", }, - { "=f,f", "0,f", }, - { "=f", "f", }, - { "=f,f", "0,f", }, - { "=f,f", "0,f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "=f", "f", }, - { "", "", "", }, - { "=&r", "r", }, - { "=r", "r", "rI", }, - { "", "", "", "", }, - { "=r", "r", "I", "=r", }, - { "=r", "r", "I", "=X", }, - { "=r", "r", "rI", }, - { "=r", "r", "rI", }, - { "", "", "", "", }, - { "=r", "r", "I", "=r", }, - { "=r", "r", "I", "=X", }, - { 0 }, - { "r", }, - { "r", }, - { "p", }, - { 0 }, - { "", "", "", "i", }, - { "S,r", "", }, - { "S,r", "", "", }, - { "=rf", "", "", "", "", }, - { "=rf", "rS", "", }, - { "", "", "", }, - { "rS", "o", "", }, - { "", "", }, - { "r", "r", }, - { 0 }, - { 0 }, - { "p", }, - { "", "", "", "", }, - { 0 }, - { 0 }, - { "=&r", "r", "=&r", }, - { "", "", "", "", }, - { "", "", "", "", }, - { "", "", "", }, - { "", "", "", "", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", }, - { "", "", "", }, - { "", "", "", }, - { "", "", "", }, - { "", "", "", }, - { "=rf", "", "=rf", "", }, - { "", "rf", "", "rf", }, - { "=fr", "", "=fr", "", }, - { "", "fr", "", "fr", }, - { "=rf", "", "=rf", "", }, - { "", "rf", "", "rf", }, - { "=fr", "", "=fr", "", }, - { "", "fr", "", "fr", }, - { "=r", "r", "r", }, - { "", "", "", }, - { "", "", "", }, - { "", "", "", }, - { "", "", "", }, - { "=r", "i", "=fr", }, - { "=r", "i", "=fr", }, - { "", "rI", }, - { "", "rI", }, - { "", "rI", }, - { "r", "r", }, - { "", "%r", "rI", }, - { "f", }, - { "", "S,r", "", }, - { "S,r", "", }, - { "=r", "rJ", }, - }; - -const enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] = - { - { SImode, SImode, }, - { SFmode, SFmode, }, - { DFmode, DFmode, }, - { TFmode, TFmode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, }, - { SImode, SImode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { TFmode, TFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { TFmode, TFmode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, }, - { SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, }, - { SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode }, - { VOIDmode, }, - { VOIDmode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, }, - { DImode, VOIDmode, }, - { SImode, VOIDmode, }, - { SImode, VOIDmode, }, - { HImode, VOIDmode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { HImode, HImode, }, - { HImode, HImode, }, - { HImode, HImode, VOIDmode, }, - { SImode, HImode, SImode, }, - { QImode, QImode, }, - { QImode, QImode, }, - { QImode, QImode, VOIDmode, }, - { SImode, QImode, SImode, }, - { TFmode, TFmode, }, - { TFmode, TFmode, }, - { TFmode, TFmode, }, - { TFmode, TFmode, }, - { SImode, TFmode, SImode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { DFmode, DFmode, }, - { VOIDmode, VOIDmode, }, - { SImode, DFmode, SImode, }, - { DImode, DImode, }, - { DImode, DImode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { SFmode, SFmode, }, - { SImode, SFmode, SImode, }, - { SImode, HImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { SImode, QImode, }, - { QImode, }, - { SImode, QImode, }, - { SImode, }, - { QImode, SImode, }, - { SImode, HImode, }, - { SImode, HImode, }, - { HImode, QImode, }, - { HImode, QImode, }, - { SImode, QImode, }, - { SImode, QImode, }, - { SImode, SImode, SImode, }, - { DFmode, SFmode, }, - { TFmode, SFmode, }, - { TFmode, DFmode, }, - { SFmode, DFmode, }, - { SFmode, TFmode, }, - { DFmode, TFmode, }, - { SFmode, SImode, }, - { DFmode, SImode, }, - { TFmode, SImode, }, - { SImode, SFmode, }, - { SImode, DFmode, }, - { SImode, TFmode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { DImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { DImode, DImode, DImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, SImode, }, - { DImode, DImode, }, - { SImode, SImode, }, - { SImode, }, - { SImode, SImode, }, - { DImode, DImode, }, - { DImode, DImode, }, - { SImode, SImode, }, - { SImode, }, - { SImode, SImode, }, - { TFmode, TFmode, TFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { TFmode, TFmode, TFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { TFmode, TFmode, TFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { DFmode, SFmode, SFmode, }, - { TFmode, DFmode, DFmode, }, - { TFmode, TFmode, TFmode, }, - { DFmode, DFmode, DFmode, }, - { SFmode, SFmode, SFmode, }, - { TFmode, TFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { TFmode, TFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { TFmode, TFmode, }, - { DFmode, DFmode, }, - { SFmode, SFmode, }, - { DImode, DImode, SImode, }, - { DImode, SImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { SImode, SImode, SImode, }, - { SImode, SImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { DImode, DImode, DImode, SImode, }, - { VOIDmode }, - { SImode, }, - { SImode, }, - { SImode, }, - { VOIDmode }, - { SImode, VOIDmode, VOIDmode, VOIDmode, }, - { SImode, VOIDmode, }, - { SImode, VOIDmode, VOIDmode, }, - { VOIDmode, SImode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, SImode, VOIDmode, }, - { SImode, BLKmode, VOIDmode, }, - { SImode, DImode, VOIDmode, }, - { BLKmode, VOIDmode, }, - { SImode, SImode, }, - { VOIDmode }, - { VOIDmode }, - { SImode, }, - { SImode, SImode, SImode, SImode, }, - { VOIDmode }, - { VOIDmode }, - { SImode, SImode, SImode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { QImode, QImode, }, - { HImode, HImode, }, - { SImode, SImode, }, - { SFmode, SFmode, }, - { SImode, SImode, SImode, }, - { SFmode, }, - { VOIDmode, VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - { VOIDmode, VOIDmode, }, - }; - -const char insn_operand_strict_low[][MAX_RECOG_OPERANDS] = - { - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0 }, - { 0, }, - { 0, }, - { 0, }, - { 0 }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0 }, - { 0 }, - { 0, }, - { 0, 0, 0, 0, }, - { 0 }, - { 0 }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - }; - -extern int register_operand (); -extern int arith_operand (); -extern int noov_compare_op (); -extern int general_operand (); -extern int reg_or_nonsymb_mem_operand (); -extern int move_operand (); -extern int move_pic_label (); -extern int immediate_operand (); -extern int symbolic_operand (); -extern int reg_or_0_operand (); -extern int scratch_operand (); -extern int memory_operand (); -extern int sparc_operand (); -extern int small_int (); -extern int arith_double_operand (); -extern int cc_arithop (); -extern int cc_arithopn (); -extern int const_double_operand (); -extern int const_int_operand (); -extern int address_operand (); -extern int call_operand (); -extern int call_operand_address (); -extern int restore_operand (); - -int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() = - { - { register_operand, arith_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, arith_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, arith_operand, }, - { register_operand, arith_operand, }, - { register_operand, }, - { register_operand, }, - { register_operand, arith_operand, }, - { register_operand, arith_operand, arith_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, noov_compare_op, }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { 0 }, - { noov_compare_op, }, - { noov_compare_op, }, - { general_operand, general_operand, }, - { register_operand, general_operand, register_operand, }, - { reg_or_nonsymb_mem_operand, move_operand, }, - { register_operand, move_pic_label, }, - { register_operand, 0, }, - { register_operand, 0, }, - { register_operand, 0, }, - { register_operand, 0, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { register_operand, register_operand, immediate_operand, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { general_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, move_operand, }, - { register_operand, register_operand, immediate_operand, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { general_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, move_operand, }, - { register_operand, register_operand, immediate_operand, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { general_operand, 0, }, - { general_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { general_operand, 0, }, - { general_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { 0, 0, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { reg_or_nonsymb_mem_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, general_operand, }, - { general_operand, 0, }, - { general_operand, general_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { reg_or_nonsymb_mem_operand, reg_or_nonsymb_mem_operand, }, - { symbolic_operand, reg_or_0_operand, scratch_operand, }, - { register_operand, register_operand, }, - { register_operand, memory_operand, }, - { register_operand, register_operand, }, - { register_operand, sparc_operand, }, - { register_operand, register_operand, }, - { register_operand, sparc_operand, }, - { register_operand, }, - { register_operand, register_operand, }, - { register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, memory_operand, }, - { register_operand, register_operand, }, - { register_operand, memory_operand, }, - { register_operand, register_operand, }, - { register_operand, memory_operand, }, - { register_operand, small_int, small_int, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_operand, arith_operand, }, - { arith_operand, arith_operand, }, - { register_operand, arith_operand, arith_operand, }, - { register_operand, register_operand, arith_double_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, arith_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, arith_operand, arith_operand, }, - { register_operand, arith_operand, arith_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, small_int, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, small_int, }, - { register_operand, register_operand, arith_operand, scratch_operand, }, - { register_operand, register_operand, arith_operand, scratch_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_operand, arith_operand, }, - { 0, 0, 0, 0, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_operand, arith_operand, }, - { 0, 0, 0, 0, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_double_operand, arith_double_operand, }, - { register_operand, arith_operand, arith_operand, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { register_operand, register_operand, register_operand, }, - { register_operand, reg_or_0_operand, arith_operand, }, - { arith_operand, arith_operand, cc_arithop, }, - { register_operand, arith_operand, arith_operand, cc_arithop, }, - { reg_or_0_operand, arith_operand, }, - { register_operand, reg_or_0_operand, arith_operand, }, - { arith_operand, reg_or_0_operand, cc_arithopn, }, - { register_operand, arith_operand, reg_or_0_operand, cc_arithopn, }, - { register_operand, register_operand, }, - { general_operand, arith_operand, }, - { arith_operand, }, - { register_operand, arith_operand, }, - { register_operand, arith_double_operand, }, - { register_operand, arith_double_operand, }, - { register_operand, arith_operand, }, - { arith_operand, }, - { register_operand, arith_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, const_double_operand, register_operand, }, - { register_operand, register_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, arith_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { register_operand, register_operand, const_int_operand, scratch_operand, }, - { 0 }, - { register_operand, }, - { register_operand, }, - { address_operand, }, - { 0 }, - { call_operand, 0, 0, 0, }, - { call_operand_address, 0, }, - { call_operand_address, 0, immediate_operand, }, - { register_operand, 0, 0, 0, 0, }, - { 0, call_operand_address, 0, }, - { call_operand, memory_operand, 0, }, - { call_operand_address, memory_operand, 0, }, - { memory_operand, 0, }, - { register_operand, register_operand, }, - { 0 }, - { 0 }, - { address_operand, }, - { general_operand, general_operand, general_operand, 0, }, - { 0 }, - { 0 }, - { register_operand, register_operand, scratch_operand, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { 0, 0, 0, }, - { restore_operand, arith_operand, }, - { restore_operand, arith_operand, }, - { restore_operand, arith_operand, }, - { restore_operand, register_operand, }, - { restore_operand, arith_operand, arith_operand, }, - { register_operand, }, - { 0, 0, 0, }, - { 0, 0, }, - { 0, 0, }, - }; - -const int insn_n_alternatives[] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 4, - 1, - 1, - 0, - 4, - 1, - 1, - 3, - 0, - 6, - 3, - 2, - 3, - 0, - 8, - 5, - 0, - 2, - 0, - 7, - 3, - 0, - 6, - 3, - 1, - 0, - 1, - 0, - 2, - 0, - 2, - 1, - 1, - 1, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 1, - 2, - 2, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 1, - 1, - 0, - 1, - 1, - 0, - 1, - 1, - 1, - 0, - 1, - 2, - 2, - 1, - 1, - 0, - 1, - 0, - 1, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 1, - }; diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-peep.c b/gnu/usr.bin/gcc2/arch/sparc/insn-peep.c deleted file mode 100644 index 5f1d8f08d41..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-peep.c +++ /dev/null @@ -1,797 +0,0 @@ -/* Generated automatically by the program `genpeep' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "regs.h" -#include "output.h" -#include "real.h" - -extern rtx peep_operand[]; - -#define operands peep_operand - -rtx -peephole (ins1) - rtx ins1; -{ - rtx insn, x, pat; - int i; - - if (NEXT_INSN (ins1) - && GET_CODE (NEXT_INSN (ins1)) == BARRIER) - return 0; - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L247; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L247; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, SImode)) goto L247; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L247; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L247; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L247; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L247; - x = XEXP (pat, 1); - operands[3] = x; - if (! memory_operand (x, SImode)) goto L247; - if (! (registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0)))) goto L247; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 247; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L247: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L248; - x = XEXP (pat, 0); - operands[0] = x; - if (! memory_operand (x, SImode)) goto L248; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, SImode)) goto L248; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L248; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L248; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L248; - x = XEXP (pat, 0); - operands[2] = x; - if (! memory_operand (x, SImode)) goto L248; - x = XEXP (pat, 1); - operands[3] = x; - if (! register_operand (x, SImode)) goto L248; - if (! (registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0)))) goto L248; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 248; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L248: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L249; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SFmode)) goto L249; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, SFmode)) goto L249; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L249; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L249; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L249; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SFmode)) goto L249; - x = XEXP (pat, 1); - operands[3] = x; - if (! memory_operand (x, SFmode)) goto L249; - if (! (registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0)))) goto L249; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 249; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L249: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L250; - x = XEXP (pat, 0); - operands[0] = x; - if (! memory_operand (x, SFmode)) goto L250; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, SFmode)) goto L250; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L250; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L250; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L250; - x = XEXP (pat, 0); - operands[2] = x; - if (! memory_operand (x, SFmode)) goto L250; - x = XEXP (pat, 1); - operands[3] = x; - if (! register_operand (x, SFmode)) goto L250; - if (! (registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0)))) goto L250; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 250; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L250: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L251; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L251; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, SImode)) goto L251; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L251; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L251; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L251; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L251; - x = XEXP (pat, 1); - operands[3] = x; - if (! memory_operand (x, SImode)) goto L251; - if (! (registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0)))) goto L251; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 251; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L251: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L252; - x = XEXP (pat, 0); - operands[0] = x; - if (! memory_operand (x, SImode)) goto L252; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, SImode)) goto L252; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L252; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L252; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L252; - x = XEXP (pat, 0); - operands[2] = x; - if (! memory_operand (x, SImode)) goto L252; - x = XEXP (pat, 1); - operands[3] = x; - if (! register_operand (x, SImode)) goto L252; - if (! (registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0)))) goto L252; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 252; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L252: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L253; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SFmode)) goto L253; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, SFmode)) goto L253; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L253; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L253; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L253; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SFmode)) goto L253; - x = XEXP (pat, 1); - operands[3] = x; - if (! memory_operand (x, SFmode)) goto L253; - if (! (registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0)))) goto L253; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 253; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L253: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L254; - x = XEXP (pat, 0); - operands[0] = x; - if (! memory_operand (x, SFmode)) goto L254; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, SFmode)) goto L254; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L254; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L254; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L254; - x = XEXP (pat, 0); - operands[2] = x; - if (! memory_operand (x, SFmode)) goto L254; - x = XEXP (pat, 1); - operands[3] = x; - if (! register_operand (x, SFmode)) goto L254; - if (! (registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0)))) goto L254; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 254; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L254: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L255; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L255; - x = XEXP (pat, 1); - operands[1] = x; - if (! register_operand (x, SImode)) goto L255; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L255; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L255; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L255; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L255; - if (GET_MODE (x) != CCmode) goto L255; - if (XINT (x, 0) != 0) goto L255; - x = XEXP (pat, 1); - if (GET_CODE (x) != COMPARE) goto L255; - if (GET_MODE (x) != CCmode) goto L255; - x = XEXP (XEXP (pat, 1), 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L255; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L255; - if (XWINT (x, 0) != 0) goto L255; - if (! ((rtx_equal_p (operands[2], operands[0]) - || rtx_equal_p (operands[2], operands[1])) - && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1]))) goto L255; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 255; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L255: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L256; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, HImode)) goto L256; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, HImode)) goto L256; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L256; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L256; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L256; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L256; - x = XEXP (pat, 1); - if (GET_CODE (x) != SIGN_EXTEND) goto L256; - if (GET_MODE (x) != SImode) goto L256; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L256; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L256; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L256; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L256; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L256; - if (GET_MODE (x) != CCmode) goto L256; - if (XINT (x, 0) != 0) goto L256; - x = XEXP (pat, 1); - if (GET_CODE (x) != COMPARE) goto L256; - if (GET_MODE (x) != CCmode) goto L256; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[2], x)) goto L256; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L256; - if (XWINT (x, 0) != 0) goto L256; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 256; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L256: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L257; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, QImode)) goto L257; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, QImode)) goto L257; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L257; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L257; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L257; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L257; - x = XEXP (pat, 1); - if (GET_CODE (x) != SIGN_EXTEND) goto L257; - if (GET_MODE (x) != SImode) goto L257; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L257; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L257; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L257; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L257; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L257; - if (GET_MODE (x) != CCmode) goto L257; - if (XINT (x, 0) != 0) goto L257; - x = XEXP (pat, 1); - if (GET_CODE (x) != COMPARE) goto L257; - if (GET_MODE (x) != CCmode) goto L257; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[2], x)) goto L257; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L257; - if (XWINT (x, 0) != 0) goto L257; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 257; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L257: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L258; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, HImode)) goto L258; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, HImode)) goto L258; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L258; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L258; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L258; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L258; - x = XEXP (pat, 1); - if (GET_CODE (x) != SIGN_EXTEND) goto L258; - if (GET_MODE (x) != SImode) goto L258; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L258; - if (! (dead_or_set_p (insn, operands[0]))) goto L258; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 258; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L258: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L259; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, QImode)) goto L259; - x = XEXP (pat, 1); - operands[1] = x; - if (! memory_operand (x, QImode)) goto L259; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L259; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L259; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L259; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SImode)) goto L259; - x = XEXP (pat, 1); - if (GET_CODE (x) != SIGN_EXTEND) goto L259; - if (GET_MODE (x) != SImode) goto L259; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L259; - if (! (dead_or_set_p (insn, operands[0]))) goto L259; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 259; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L259: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L260; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L260; - x = XEXP (pat, 1); - if (GET_CODE (x) != LO_SUM) goto L260; - if (GET_MODE (x) != SImode) goto L260; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L260; - x = XEXP (XEXP (pat, 1), 1); - operands[1] = x; - if (! immediate_operand (x, SImode)) goto L260; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L260; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L260; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L260; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, DFmode)) goto L260; - x = XEXP (pat, 1); - if (GET_CODE (x) != MEM) goto L260; - if (GET_MODE (x) != DFmode) goto L260; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L260; - if (! (RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn))) goto L260; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 260; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L260: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L261; - x = XEXP (pat, 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L261; - x = XEXP (pat, 1); - if (GET_CODE (x) != LO_SUM) goto L261; - if (GET_MODE (x) != SImode) goto L261; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L261; - x = XEXP (XEXP (pat, 1), 1); - operands[1] = x; - if (! immediate_operand (x, SImode)) goto L261; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L261; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L261; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L261; - x = XEXP (pat, 0); - operands[2] = x; - if (! register_operand (x, SFmode)) goto L261; - x = XEXP (pat, 1); - if (GET_CODE (x) != MEM) goto L261; - if (GET_MODE (x) != SFmode) goto L261; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L261; - if (! (RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn))) goto L261; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 261; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L261: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != PARALLEL) goto L268; - if (XVECLEN (x, 0) != 2) goto L268; - x = XVECEXP (pat, 0, 0); - if (GET_CODE (x) != SET) goto L268; - x = XEXP (XVECEXP (pat, 0, 0), 0); - operands[0] = x; - x = XEXP (XVECEXP (pat, 0, 0), 1); - if (GET_CODE (x) != CALL) goto L268; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0); - if (GET_CODE (x) != MEM) goto L268; - if (GET_MODE (x) != SImode) goto L268; - x = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0); - operands[1] = x; - if (! call_operand_address (x, SImode)) goto L268; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1); - operands[2] = x; - x = XVECEXP (pat, 0, 1); - if (GET_CODE (x) != CLOBBER) goto L268; - x = XEXP (XVECEXP (pat, 0, 1), 0); - if (GET_CODE (x) != REG) goto L268; - if (GET_MODE (x) != SImode) goto L268; - if (XINT (x, 0) != 15) goto L268; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L268; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L268; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L268; - x = XEXP (pat, 0); - if (GET_CODE (x) != PC) goto L268; - x = XEXP (pat, 1); - if (GET_CODE (x) != LABEL_REF) goto L268; - x = XEXP (XEXP (pat, 1), 0); - operands[3] = x; - if (! (short_branch (INSN_UID (insn), INSN_UID (operands[3])))) goto L268; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (4, operands)); - INSN_CODE (ins1) = 268; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L268: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != PARALLEL) goto L269; - if (XVECLEN (x, 0) != 2) goto L269; - x = XVECEXP (pat, 0, 0); - if (GET_CODE (x) != CALL) goto L269; - x = XEXP (XVECEXP (pat, 0, 0), 0); - if (GET_CODE (x) != MEM) goto L269; - if (GET_MODE (x) != SImode) goto L269; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0); - operands[0] = x; - if (! call_operand_address (x, SImode)) goto L269; - x = XEXP (XVECEXP (pat, 0, 0), 1); - operands[1] = x; - x = XVECEXP (pat, 0, 1); - if (GET_CODE (x) != CLOBBER) goto L269; - x = XEXP (XVECEXP (pat, 0, 1), 0); - if (GET_CODE (x) != REG) goto L269; - if (GET_MODE (x) != SImode) goto L269; - if (XINT (x, 0) != 15) goto L269; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L269; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L269; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L269; - x = XEXP (pat, 0); - if (GET_CODE (x) != PC) goto L269; - x = XEXP (pat, 1); - if (GET_CODE (x) != LABEL_REF) goto L269; - x = XEXP (XEXP (pat, 1), 0); - operands[2] = x; - if (! (short_branch (INSN_UID (insn), INSN_UID (operands[2])))) goto L269; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (3, operands)); - INSN_CODE (ins1) = 269; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L269: - - insn = ins1; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != PARALLEL) goto L270; - if (XVECLEN (x, 0) != 2) goto L270; - x = XVECEXP (pat, 0, 0); - if (GET_CODE (x) != SET) goto L270; - x = XEXP (XVECEXP (pat, 0, 0), 0); - operands[0] = x; - if (! register_operand (x, SImode)) goto L270; - x = XEXP (XVECEXP (pat, 0, 0), 1); - if (GET_CODE (x) != MINUS) goto L270; - if (GET_MODE (x) != SImode) goto L270; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0); - operands[1] = x; - if (! reg_or_0_operand (x, SImode)) goto L270; - x = XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 1); - if (GET_CODE (x) != REG) goto L270; - if (GET_MODE (x) != SImode) goto L270; - if (XINT (x, 0) != 0) goto L270; - x = XVECEXP (pat, 0, 1); - if (GET_CODE (x) != CLOBBER) goto L270; - x = XEXP (XVECEXP (pat, 0, 1), 0); - if (GET_CODE (x) != REG) goto L270; - if (GET_MODE (x) != CCmode) goto L270; - if (XINT (x, 0) != 0) goto L270; - do { insn = NEXT_INSN (insn); - if (insn == 0) goto L270; } - while (GET_CODE (insn) == NOTE - || (GET_CODE (insn) == INSN - && (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER))); - if (GET_CODE (insn) == CODE_LABEL - || GET_CODE (insn) == BARRIER) - goto L270; - pat = PATTERN (insn); - x = pat; - if (GET_CODE (x) != SET) goto L270; - x = XEXP (pat, 0); - if (GET_CODE (x) != REG) goto L270; - if (GET_MODE (x) != CCmode) goto L270; - if (XINT (x, 0) != 0) goto L270; - x = XEXP (pat, 1); - if (GET_CODE (x) != COMPARE) goto L270; - x = XEXP (XEXP (pat, 1), 0); - if (!rtx_equal_p (operands[0], x)) goto L270; - x = XEXP (XEXP (pat, 1), 1); - if (GET_CODE (x) != CONST_INT) goto L270; - if (XWINT (x, 0) != 0) goto L270; - PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (2, operands)); - INSN_CODE (ins1) = 270; - delete_for_peephole (NEXT_INSN (ins1), insn); - return NEXT_INSN (insn); - L270: - - return 0; -} - -rtx peep_operand[4]; diff --git a/gnu/usr.bin/gcc2/arch/sparc/insn-recog.c b/gnu/usr.bin/gcc2/arch/sparc/insn-recog.c deleted file mode 100644 index 74bb81d006d..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/insn-recog.c +++ /dev/null @@ -1,6575 +0,0 @@ -/* Generated automatically by the program `genrecog' -from the machine description file `md'. */ - -#include "config.h" -#include "rtl.h" -#include "insn-config.h" -#include "recog.h" -#include "real.h" -#include "output.h" -#include "flags.h" - -extern rtx gen_split_86 (); -extern rtx gen_split_147 (); -extern rtx gen_split_153 (); -extern rtx gen_split_159 (); -extern rtx gen_split_160 (); -extern rtx gen_split_233 (); -extern rtx gen_split_234 (); -extern rtx gen_split_235 (); -extern rtx gen_split_236 (); -extern rtx gen_split_237 (); -extern rtx gen_split_238 (); -extern rtx gen_split_239 (); -extern rtx gen_split_240 (); -extern rtx gen_split_241 (); -extern rtx gen_split_242 (); -extern rtx gen_split_243 (); -extern rtx gen_split_244 (); -extern rtx gen_split_245 (); -extern rtx gen_split_246 (); - -/* `recog' contains a decision tree - that recognizes whether the rtx X0 is a valid instruction. - - recog returns -1 if the rtx is not valid. - If the rtx is valid, recog returns a nonnegative number - which is the insn code number for the pattern that matched. - This is the same as the order in the machine description of - the entry that matched. This number can be used as an index into - entry that matched. This number can be used as an index into various - insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands - (found in insn-output.c). - - The third argument to recog is an optional pointer to an int. - If present, recog will accept a pattern if it matches except for - missing CLOBBER expressions at the end. In that case, the value - pointed to by the optional pointer will be set to the number of - CLOBBERs that need to be added (it should be initialized to zero by - the caller). If it is set nonzero, the caller should allocate a - PARALLEL of the appropriate size, copy the initial entries, and call - add_clobbers (found in insn-emit.c) to fill in the CLOBBERs. - - The function split_insns returns 0 if the rtl could not - be split or the split rtl in a SEQUENCE if it can be.*/ - -rtx recog_operand[MAX_RECOG_OPERANDS]; - -rtx *recog_operand_loc[MAX_RECOG_OPERANDS]; - -rtx *recog_dup_loc[MAX_DUP_OPERANDS]; - -char recog_dup_num[MAX_DUP_OPERANDS]; - -#define operands recog_operand - -int -recog_1 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XEXP (x0, 1); - switch (GET_MODE (x1)) - { - case SImode: - switch (GET_CODE (x1)) - { - case NE: - goto L46; - case NEG: - goto L60; - case EQ: - goto L74; - case PLUS: - goto L104; - case MINUS: - goto L173; - case LTU: - goto L162; - case GEU: - goto L189; - } - } - L254: - if (noov_compare_op (x1, SImode)) - { - ro[1] = x1; - goto L255; - } - goto ret0; - - L46: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L47; - } - goto L254; - - L47: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 23; - } - goto L254; - - L60: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != SImode) - { - goto L254; - } - switch (GET_CODE (x2)) - { - case NE: - goto L61; - case EQ: - goto L89; - case LTU: - goto L168; - case PLUS: - goto L182; - case GEU: - goto L195; - } - goto L254; - - L61: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L62; - } - goto L254; - - L62: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 24; - } - goto L254; - - L89: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L90; - } - goto L254; - - L90: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 26; - } - goto L254; - - L168: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L169; - goto L254; - - L169: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - return 32; - goto L254; - - L182: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == LTU && 1) - goto L183; - goto L254; - - L183: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == CCmode && GET_CODE (x4) == REG && XINT (x4, 0) == 0 && 1) - goto L184; - goto L254; - - L184: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L185; - goto L254; - - L185: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - return 34; - } - goto L254; - - L195: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L196; - goto L254; - - L196: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - return 36; - goto L254; - - L74: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L75; - } - goto L254; - - L75: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 25; - } - goto L254; - - L104: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != SImode) - { - goto L254; - } - switch (GET_CODE (x2)) - { - case NE: - goto L105; - case EQ: - goto L139; - case LTU: - goto L201; - case GEU: - goto L242; - } - goto L254; - - L105: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L106; - } - goto L254; - - L106: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L107; - goto L254; - - L107: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && register_operand (x2, SImode)) - { - ro[2] = x2; - *pnum_clobbers = 1; - return 27; - } - goto L254; - - L139: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L140; - } - goto L254; - - L140: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L141; - goto L254; - - L141: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && register_operand (x2, SImode)) - { - ro[2] = x2; - *pnum_clobbers = 1; - return 29; - } - goto L254; - - L201: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L202; - goto L254; - - L202: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L203; - goto L254; - - L203: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - return 37; - } - L210: - if (GET_MODE (x2) == SImode && GET_CODE (x2) == PLUS && 1) - goto L211; - goto L254; - - L211: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L212; - } - goto L254; - - L212: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - return 38; - } - goto L254; - - L242: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L243; - goto L254; - - L243: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L244; - goto L254; - - L244: - x2 = XEXP (x1, 1); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - return 42; - } - goto L254; - - L173: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != SImode) - { - goto L254; - } - switch (GET_CODE (x2)) - { - case NEG: - goto L174; - case MINUS: - goto L224; - case SUBREG: - case REG: - if (register_operand (x2, SImode)) - { - ro[2] = x2; - goto L122; - } - } - L216: - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L217; - } - goto L254; - - L174: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == LTU && 1) - goto L175; - goto L254; - - L175: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == CCmode && GET_CODE (x4) == REG && XINT (x4, 0) == 0 && 1) - goto L176; - goto L254; - - L176: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L177; - goto L254; - - L177: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - return 33; - } - goto L254; - - L224: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L225; - } - goto L254; - - L225: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L226; - } - goto L254; - - L226: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == LTU && 1) - goto L227; - goto L254; - - L227: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L228; - goto L254; - - L228: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - return 40; - goto L254; - - L122: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != SImode) - { - x2 = XEXP (x1, 0); - goto L216; - } - switch (GET_CODE (x2)) - { - case NE: - goto L123; - case EQ: - goto L157; - } - x2 = XEXP (x1, 0); - goto L216; - - L123: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L124; - } - x2 = XEXP (x1, 0); - goto L216; - - L124: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 28; - } - x2 = XEXP (x1, 0); - goto L216; - - L157: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L158; - } - x2 = XEXP (x1, 0); - goto L216; - - L158: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1) - { - *pnum_clobbers = 1; - return 30; - } - x2 = XEXP (x1, 0); - goto L216; - - L217: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != SImode) - { - goto L254; - } - switch (GET_CODE (x2)) - { - case LTU: - goto L218; - case PLUS: - goto L234; - case GEU: - goto L250; - } - goto L254; - - L218: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L219; - goto L254; - - L219: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - return 39; - goto L254; - - L234: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == LTU && 1) - goto L235; - goto L254; - - L235: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == CCmode && GET_CODE (x4) == REG && XINT (x4, 0) == 0 && 1) - goto L236; - goto L254; - - L236: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L237; - goto L254; - - L237: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - return 41; - } - goto L254; - - L250: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == CCmode && GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L251; - goto L254; - - L251: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - return 43; - goto L254; - - L162: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L163; - goto L254; - - L163: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 31; - goto L254; - - L189: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L190; - goto L254; - - L190: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 35; - goto L254; - - L255: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L256; - goto ret0; - - L256: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 44; - goto ret0; - ret0: return -1; -} - -int -recog_2 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SImode) - goto ret0; - switch (GET_CODE (x1)) - { - case HIGH: - goto L292; - case LO_SUM: - goto L310; - case ZERO_EXTEND: - goto L443; - case SIGN_EXTEND: - goto L488; - case FIX: - goto L544; - case PLUS: - goto L572; - case MINUS: - goto L610; - case MULT: - goto L635; - case DIV: - goto L687; - case UDIV: - goto L720; - case AND: - goto L743; - case IOR: - goto L773; - case XOR: - goto L803; - case NOT: - goto L831; - case ASHIFT: - goto L1078; - case ASHIFTRT: - goto L1113; - case LSHIFTRT: - goto L1118; - } - goto ret0; - - L292: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == UNSPEC && XINT (x2, 1) == 0 && XVECLEN (x2, 0) == 1 && 1) - goto L293; - L297: - ro[1] = x2; - if (check_pic (1)) - return 63; - goto ret0; - - L293: - x3 = XVECEXP (x2, 0, 0); - ro[1] = x3; - if (check_pic (1)) - return 62; - goto L297; - - L310: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L311; - } - goto ret0; - - L311: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == UNSPEC && XINT (x2, 1) == 0 && XVECLEN (x2, 0) == 1 && 1) - goto L312; - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - return 67; - } - goto ret0; - - L312: - x3 = XVECEXP (x2, 0, 0); - if (immediate_operand (x3, SImode)) - { - ro[2] = x3; - return 66; - } - goto ret0; - - L443: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (memory_operand (x2, HImode)) - { - ro[1] = x2; - return 96; - } - break; - case QImode: - if (sparc_operand (x2, QImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) != CONST_INT) - return 100; - } - } - goto ret0; - - L488: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case HImode: - if (memory_operand (x2, HImode)) - { - ro[1] = x2; - return 106; - } - break; - case QImode: - if (memory_operand (x2, QImode)) - { - ro[1] = x2; - return 110; - } - } - goto ret0; - - L544: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) != FIX) - goto ret0; - switch (GET_MODE (x2)) - { - case SFmode: - goto L545; - case DFmode: - goto L550; - case TFmode: - goto L555; - } - goto ret0; - - L545: - x3 = XEXP (x2, 0); - if (register_operand (x3, SFmode)) - { - ro[1] = x3; - if (TARGET_FPU) - return 121; - } - goto ret0; - - L550: - x3 = XEXP (x2, 0); - if (register_operand (x3, DFmode)) - { - ro[1] = x3; - if (TARGET_FPU) - return 122; - } - goto ret0; - - L555: - x3 = XEXP (x2, 0); - if (register_operand (x3, TFmode)) - { - ro[1] = x3; - if (TARGET_FPU) - return 123; - } - goto ret0; - - L572: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L573; - } - goto ret0; - - L573: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 125; - } - goto ret0; - - L610: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L611; - } - goto ret0; - - L611: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 129; - } - goto ret0; - - L635: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L636; - } - goto ret0; - - L636: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_V8 || TARGET_SPARCLITE) - return 132; - } - goto ret0; - - L687: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L688; - } - goto ret0; - - L688: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && arith_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_V8) - { - *pnum_clobbers = 1; - return 140; - } - } - goto ret0; - - L720: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L721; - } - goto ret0; - - L721: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_V8) - return 142; - } - goto ret0; - - L743: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L744; - } - L762: - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L763; - goto ret0; - - L744: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 146; - } - x2 = XEXP (x1, 0); - goto L762; - - L763: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L764; - } - goto ret0; - - L764: - x2 = XEXP (x1, 1); - if (register_operand (x2, SImode)) - { - ro[2] = x2; - return 149; - } - goto ret0; - - L773: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L774; - } - L792: - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L793; - goto ret0; - - L774: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 152; - } - x2 = XEXP (x1, 0); - goto L792; - - L793: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L794; - } - goto ret0; - - L794: - x2 = XEXP (x1, 1); - if (register_operand (x2, SImode)) - { - ro[2] = x2; - return 155; - } - goto ret0; - - L803: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L804; - } - goto ret0; - - L804: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 158; - } - goto ret0; - - L831: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == XOR && 1) - goto L832; - L934: - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - return 175; - } - goto ret0; - - L832: - x3 = XEXP (x2, 0); - if (reg_or_0_operand (x3, SImode)) - { - ro[1] = x3; - goto L833; - } - goto L934; - - L833: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - return 162; - } - goto L934; - - L1078: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1079; - } - goto ret0; - - L1079: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 203; - } - goto ret0; - - L1113: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1114; - } - goto ret0; - - L1114: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 207; - } - goto ret0; - - L1118: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - goto L1119; - } - goto ret0; - - L1119: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[2] = x2; - return 208; - } - goto ret0; - ret0: return -1; -} - -int -recog_3 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != DImode) - goto ret0; - switch (GET_CODE (x1)) - { - case HIGH: - goto L288; - case LO_SUM: - goto L305; - case PLUS: - goto L567; - case MINUS: - goto L605; - case MULT: - goto L653; - case AND: - goto L738; - case IOR: - goto L768; - case XOR: - goto L798; - case NOT: - goto L825; - case NEG: - goto L905; - case ASHIFT: - goto L1073; - case LSHIFT: - goto L1091; - case LSHIFTRT: - goto L1131; - } - goto ret0; - - L288: - x2 = XEXP (x1, 0); - ro[1] = x2; - if (check_pic (1)) - return 61; - goto ret0; - - L305: - x2 = XEXP (x1, 0); - if (register_operand (x2, DImode)) - { - ro[1] = x2; - goto L306; - } - goto ret0; - - L306: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, DImode)) - { - ro[2] = x2; - return 65; - } - goto ret0; - - L567: - x2 = XEXP (x1, 0); - if (arith_double_operand (x2, DImode)) - { - ro[1] = x2; - goto L568; - } - goto ret0; - - L568: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && arith_double_operand (x2, DImode)) - { - ro[2] = x2; - *pnum_clobbers = 1; - return 124; - } - goto ret0; - - L605: - x2 = XEXP (x1, 0); - if (register_operand (x2, DImode)) - { - ro[1] = x2; - goto L606; - } - goto ret0; - - L606: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && arith_double_operand (x2, DImode)) - { - ro[2] = x2; - *pnum_clobbers = 1; - return 128; - } - goto ret0; - - L653: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != DImode) - goto ret0; - switch (GET_CODE (x2)) - { - case SIGN_EXTEND: - goto L654; - case ZERO_EXTEND: - goto L667; - } - goto ret0; - - L654: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L655; - } - goto ret0; - - L655: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DImode && GET_CODE (x2) == SIGN_EXTEND && 1) - goto L656; - L662: - if (small_int (x2, SImode)) - { - ro[2] = x2; - if (TARGET_V8 || TARGET_SPARCLITE) - return 136; - } - goto ret0; - - L656: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - if (TARGET_V8 || TARGET_SPARCLITE) - return 135; - } - goto L662; - - L667: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L668; - } - goto ret0; - - L668: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DImode && GET_CODE (x2) == ZERO_EXTEND && 1) - goto L669; - L675: - if (small_int (x2, SImode)) - { - ro[2] = x2; - if (TARGET_V8 || TARGET_SPARCLITE) - return 139; - } - goto ret0; - - L669: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - if (TARGET_V8 || TARGET_SPARCLITE) - return 138; - } - goto L675; - - L738: - x2 = XEXP (x1, 0); - if (arith_double_operand (x2, DImode)) - { - ro[1] = x2; - goto L739; - } - L756: - if (GET_MODE (x2) == DImode && GET_CODE (x2) == NOT && 1) - goto L757; - goto ret0; - - L739: - x2 = XEXP (x1, 1); - if (arith_double_operand (x2, DImode)) - { - ro[2] = x2; - return 145; - } - x2 = XEXP (x1, 0); - goto L756; - - L757: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L758; - } - goto ret0; - - L758: - x2 = XEXP (x1, 1); - if (register_operand (x2, DImode)) - { - ro[2] = x2; - return 148; - } - goto ret0; - - L768: - x2 = XEXP (x1, 0); - if (arith_double_operand (x2, DImode)) - { - ro[1] = x2; - goto L769; - } - L786: - if (GET_MODE (x2) == DImode && GET_CODE (x2) == NOT && 1) - goto L787; - goto ret0; - - L769: - x2 = XEXP (x1, 1); - if (arith_double_operand (x2, DImode)) - { - ro[2] = x2; - return 151; - } - x2 = XEXP (x1, 0); - goto L786; - - L787: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L788; - } - goto ret0; - - L788: - x2 = XEXP (x1, 1); - if (register_operand (x2, DImode)) - { - ro[2] = x2; - return 154; - } - goto ret0; - - L798: - x2 = XEXP (x1, 0); - if (arith_double_operand (x2, DImode)) - { - ro[1] = x2; - goto L799; - } - goto ret0; - - L799: - x2 = XEXP (x1, 1); - if (arith_double_operand (x2, DImode)) - { - ro[2] = x2; - return 157; - } - goto ret0; - - L825: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == DImode && GET_CODE (x2) == XOR && 1) - goto L826; - L930: - if (arith_double_operand (x2, DImode)) - { - ro[1] = x2; - return 174; - } - goto ret0; - - L826: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L827; - } - goto L930; - - L827: - x3 = XEXP (x2, 1); - if (register_operand (x3, DImode)) - { - ro[2] = x3; - return 161; - } - goto L930; - - L905: - x2 = XEXP (x1, 0); - if (pnum_clobbers != 0 && register_operand (x2, DImode)) - { - ro[1] = x2; - *pnum_clobbers = 1; - return 169; - } - goto ret0; - - L1073: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 1 && 1) - goto L1074; - goto ret0; - - L1074: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && register_operand (x2, SImode)) - { - ro[1] = x2; - *pnum_clobbers = 1; - return 202; - } - goto ret0; - - L1091: - x2 = XEXP (x1, 0); - if (register_operand (x2, DImode)) - { - ro[1] = x2; - goto L1092; - } - goto ret0; - - L1092: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - goto L1108; - goto ret0; - - L1108: - if (pnum_clobbers != 0 && 1) - { - ro[2] = x2; - if (INTVAL (operands[2]) < 32) - { - *pnum_clobbers = 1; - return 205; - } - } - L1109: - if (pnum_clobbers != 0 && 1) - { - ro[2] = x2; - if (INTVAL (operands[2]) >= 32) - { - *pnum_clobbers = 1; - return 206; - } - } - goto ret0; - - L1131: - x2 = XEXP (x1, 0); - if (register_operand (x2, DImode)) - { - ro[1] = x2; - goto L1132; - } - goto ret0; - - L1132: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && 1) - goto L1148; - goto ret0; - - L1148: - if (pnum_clobbers != 0 && 1) - { - ro[2] = x2; - if (INTVAL (operands[2]) < 32) - { - *pnum_clobbers = 1; - return 210; - } - } - L1149: - if (pnum_clobbers != 0 && 1) - { - ro[2] = x2; - if (INTVAL (operands[2]) >= 32) - { - *pnum_clobbers = 1; - return 211; - } - } - goto ret0; - ret0: return -1; -} - -int -recog_4 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XEXP (x0, 0); - switch (GET_MODE (x1)) - { - case CCmode: - switch (GET_CODE (x1)) - { - case REG: - if (XINT (x1, 0) == 0 && 1) - goto L2; - } - break; - case CCFPEmode: - switch (GET_CODE (x1)) - { - case REG: - if (XINT (x1, 0) == 0 && 1) - goto L7; - } - break; - case CCFPmode: - if (GET_CODE (x1) == REG && XINT (x1, 0) == 0 && 1) - goto L22; - break; - case SImode: - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L45; - } - } - if (GET_CODE (x1) == PC && 1) - goto L259; - L276: - switch (GET_MODE (x1)) - { - case SImode: - if (reg_or_nonsymb_mem_operand (x1, SImode)) - { - ro[0] = x1; - goto L277; - } - L290: - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L291; - } - break; - case DImode: - if (register_operand (x1, DImode)) - { - ro[0] = x1; - goto L287; - } - L416: - if (reg_or_nonsymb_mem_operand (x1, DImode)) - { - ro[0] = x1; - goto L417; - } - break; - case HImode: - if (register_operand (x1, HImode)) - { - ro[0] = x1; - goto L300; - } - L330: - if (reg_or_nonsymb_mem_operand (x1, HImode)) - { - ro[0] = x1; - goto L331; - } - L333: - if (register_operand (x1, HImode)) - { - ro[0] = x1; - goto L334; - } - } - switch (GET_MODE (x1)) - { - case SImode: - if (GET_CODE (x1) == MEM && 1) - goto L327; - L907: - if (general_operand (x1, SImode)) - { - ro[0] = x1; - goto L908; - } - break; - case HImode: - if (GET_CODE (x1) == MEM && 1) - goto L346; - break; - case QImode: - if (reg_or_nonsymb_mem_operand (x1, QImode)) - { - ro[0] = x1; - goto L350; - } - L352: - if (register_operand (x1, QImode)) - { - ro[0] = x1; - goto L353; - } - if (GET_CODE (x1) == MEM && 1) - goto L366; - break; - case TFmode: - if (general_operand (x1, TFmode)) - { - ro[0] = x1; - goto L370; - } - L372: - if (reg_or_nonsymb_mem_operand (x1, TFmode)) - { - ro[0] = x1; - goto L373; - } - L510: - if (register_operand (x1, TFmode)) - { - ro[0] = x1; - goto L511; - } - if (GET_CODE (x1) == MEM && 1) - goto L388; - break; - case DFmode: - if (general_operand (x1, DFmode)) - { - ro[0] = x1; - goto L392; - } - L394: - if (reg_or_nonsymb_mem_operand (x1, DFmode)) - { - ro[0] = x1; - goto L395; - } - L506: - if (register_operand (x1, DFmode)) - { - ro[0] = x1; - goto L507; - } - if (GET_CODE (x1) == MEM && 1) - goto L413; - break; - case SFmode: - if (general_operand (x1, SFmode)) - { - ro[0] = x1; - goto L420; - } - L422: - if (reg_or_nonsymb_mem_operand (x1, SFmode)) - { - ro[0] = x1; - goto L423; - } - L518: - if (register_operand (x1, SFmode)) - { - ro[0] = x1; - goto L519; - } - switch (GET_CODE (x1)) - { - case MEM: - goto L438; - } - break; - case CC_NOOVmode: - switch (GET_CODE (x1)) - { - case REG: - if (XINT (x1, 0) == 0 && 1) - goto L576; - } - } - L1151: - if (GET_CODE (x1) == PC && 1) - goto L1152; - L1214: - ro[0] = x1; - goto L1215; - L1241: - if (GET_CODE (x1) == PC && 1) - goto L1242; - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L1256; - } - goto ret0; - - L2: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == CCmode && GET_CODE (x1) == COMPARE && 1) - goto L455; - x1 = XEXP (x0, 0); - goto L1214; - - L455: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - switch (GET_CODE (x2)) - { - case ZERO_EXTEND: - goto L456; - case ZERO_EXTRACT: - goto L501; - case SUBREG: - case REG: - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L4; - } - } - L837: - if (cc_arithop (x2, SImode)) - { - ro[2] = x2; - goto L838; - } - L878: - if (cc_arithopn (x2, SImode)) - { - ro[2] = x2; - goto L879; - } - break; - case QImode: - switch (GET_CODE (x2)) - { - case SUBREG: - if (XINT (x2, 1) == 0 && 1) - goto L473; - } - } - L855: - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L856; - x1 = XEXP (x0, 0); - goto L1214; - - L456: - x3 = XEXP (x2, 0); - if (register_operand (x3, QImode)) - { - ro[0] = x3; - goto L457; - } - goto L837; - - L457: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 101; - x2 = XEXP (x1, 0); - goto L837; - - L501: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[0] = x3; - goto L502; - } - goto L837; - - L502: - x3 = XEXP (x2, 1); - if (small_int (x3, SImode)) - { - ro[1] = x3; - goto L503; - } - goto L837; - - L503: - x3 = XEXP (x2, 2); - if (small_int (x3, SImode)) - { - ro[2] = x3; - goto L504; - } - goto L837; - - L504: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - if (INTVAL (operands[2]) > 19) - return 111; - x2 = XEXP (x1, 0); - goto L837; - - L4: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - return 16; - } - x2 = XEXP (x1, 0); - goto L837; - - L838: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[0] = x3; - goto L839; - } - goto L878; - - L839: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L840; - } - goto L878; - - L840: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 163; - x2 = XEXP (x1, 0); - goto L878; - - L879: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == NOT && 1) - goto L880; - goto L855; - - L880: - x4 = XEXP (x3, 0); - if (arith_operand (x4, SImode)) - { - ro[0] = x4; - goto L881; - } - goto L855; - - L881: - x3 = XEXP (x2, 1); - if (reg_or_0_operand (x3, SImode)) - { - ro[1] = x3; - goto L882; - } - goto L855; - - L882: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 167; - x2 = XEXP (x1, 0); - goto L855; - - L473: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[0] = x3; - goto L474; - } - x1 = XEXP (x0, 0); - goto L1214; - - L474: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 103; - x1 = XEXP (x0, 0); - goto L1214; - - L856: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == XOR && 1) - goto L857; - L939: - if (arith_operand (x3, SImode)) - { - ro[0] = x3; - goto L940; - } - x1 = XEXP (x0, 0); - goto L1214; - - L857: - x4 = XEXP (x3, 0); - if (reg_or_0_operand (x4, SImode)) - { - ro[0] = x4; - goto L858; - } - goto L939; - - L858: - x4 = XEXP (x3, 1); - if (arith_operand (x4, SImode)) - { - ro[1] = x4; - goto L859; - } - goto L939; - - L859: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 165; - x2 = XEXP (x1, 0); - x3 = XEXP (x2, 0); - goto L939; - - L940: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 176; - x1 = XEXP (x0, 0); - goto L1214; - - L7: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == CCFPEmode && GET_CODE (x1) == COMPARE && 1) - goto L8; - x1 = XEXP (x0, 0); - goto L1214; - - L8: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case DFmode: - if (register_operand (x2, DFmode)) - { - ro[0] = x2; - goto L9; - } - break; - case SFmode: - if (register_operand (x2, SFmode)) - { - ro[0] = x2; - goto L14; - } - break; - case TFmode: - if (register_operand (x2, TFmode)) - { - ro[0] = x2; - goto L19; - } - } - x1 = XEXP (x0, 0); - goto L1214; - - L9: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 17; - } - x1 = XEXP (x0, 0); - goto L1214; - - L14: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 18; - } - x1 = XEXP (x0, 0); - goto L1214; - - L19: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 19; - } - x1 = XEXP (x0, 0); - goto L1214; - - L22: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == CCFPmode && GET_CODE (x1) == COMPARE && 1) - goto L23; - x1 = XEXP (x0, 0); - goto L1214; - - L23: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case DFmode: - if (register_operand (x2, DFmode)) - { - ro[0] = x2; - goto L24; - } - break; - case SFmode: - if (register_operand (x2, SFmode)) - { - ro[0] = x2; - goto L29; - } - break; - case TFmode: - if (register_operand (x2, TFmode)) - { - ro[0] = x2; - goto L34; - } - } - x1 = XEXP (x0, 0); - goto L1214; - - L24: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 20; - } - x1 = XEXP (x0, 0); - goto L1214; - - L29: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 21; - } - x1 = XEXP (x0, 0); - goto L1214; - - L34: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 22; - } - x1 = XEXP (x0, 0); - goto L1214; - L45: - tem = recog_1 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L276; - - L259: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) == IF_THEN_ELSE && 1) - goto L260; - x1 = XEXP (x0, 0); - goto L276; - - L260: - x2 = XEXP (x1, 0); - if (noov_compare_op (x2, VOIDmode)) - { - ro[0] = x2; - goto L261; - } - x1 = XEXP (x0, 0); - goto L276; - - L261: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == REG && XINT (x3, 0) == 0 && 1) - goto L262; - x1 = XEXP (x0, 0); - goto L276; - - L262: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L263; - x1 = XEXP (x0, 0); - goto L276; - - L263: - x2 = XEXP (x1, 1); - switch (GET_CODE (x2)) - { - case LABEL_REF: - goto L264; - case PC: - goto L273; - } - x1 = XEXP (x0, 0); - goto L276; - - L264: - x3 = XEXP (x2, 0); - ro[1] = x3; - goto L265; - - L265: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == PC && 1) - return 55; - x1 = XEXP (x0, 0); - goto L276; - - L273: - x2 = XEXP (x1, 2); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L274; - x1 = XEXP (x0, 0); - goto L276; - - L274: - x3 = XEXP (x2, 0); - ro[1] = x3; - return 56; - - L277: - x1 = XEXP (x0, 1); - if (move_operand (x1, SImode)) - { - ro[1] = x1; - if (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || operands[1] == const0_rtx) - return 59; - } - x1 = XEXP (x0, 0); - goto L290; - L291: - tem = recog_2 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L907; - L287: - tem = recog_3 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x1 = XEXP (x0, 0); - goto L416; - - L417: - x1 = XEXP (x0, 1); - if (general_operand (x1, DImode)) - { - ro[1] = x1; - if (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx) - return 89; - } - x1 = XEXP (x0, 0); - goto L1151; - - L300: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == HImode && GET_CODE (x1) == HIGH && 1) - goto L301; - x1 = XEXP (x0, 0); - goto L330; - - L301: - x2 = XEXP (x1, 0); - ro[1] = x2; - if (check_pic (1)) - return 64; - x1 = XEXP (x0, 0); - goto L330; - - L331: - x1 = XEXP (x0, 1); - if (move_operand (x1, HImode)) - { - ro[1] = x1; - if (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode) - || operands[1] == const0_rtx) - return 70; - } - x1 = XEXP (x0, 0); - goto L333; - - L334: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != HImode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - switch (GET_CODE (x1)) - { - case LO_SUM: - goto L335; - case ZERO_EXTEND: - goto L447; - case SIGN_EXTEND: - goto L492; - } - x1 = XEXP (x0, 0); - goto L1214; - - L335: - x2 = XEXP (x1, 0); - if (register_operand (x2, HImode)) - { - ro[1] = x2; - goto L336; - } - x1 = XEXP (x0, 0); - goto L1214; - - L336: - x2 = XEXP (x1, 1); - if (immediate_operand (x2, VOIDmode)) - { - ro[2] = x2; - return 71; - } - x1 = XEXP (x0, 0); - goto L1214; - - L447: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == QImode && sparc_operand (x2, QImode)) - { - ro[1] = x2; - if (GET_CODE (operands[1]) != CONST_INT) - return 98; - } - x1 = XEXP (x0, 0); - goto L1214; - - L492: - x2 = XEXP (x1, 0); - if (memory_operand (x2, QImode)) - { - ro[1] = x2; - return 108; - } - x1 = XEXP (x0, 0); - goto L1214; - - L327: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L328; - } - goto L907; - - L328: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, SImode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 68; - } - x1 = XEXP (x0, 0); - goto L907; - - L908: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SImode && GET_CODE (x1) == NEG && 1) - goto L909; - x1 = XEXP (x0, 0); - goto L1214; - - L909: - x2 = XEXP (x1, 0); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - return 170; - } - x1 = XEXP (x0, 0); - goto L1214; - - L346: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L347; - } - goto L1214; - - L347: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, HImode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 72; - } - x1 = XEXP (x0, 0); - goto L1214; - - L350: - x1 = XEXP (x0, 1); - if (move_operand (x1, QImode)) - { - ro[1] = x1; - if (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode) - || operands[1] == const0_rtx) - return 74; - } - x1 = XEXP (x0, 0); - goto L352; - - L353: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == QImode && GET_CODE (x1) == SUBREG && XINT (x1, 1) == 0 && 1) - goto L354; - x1 = XEXP (x0, 0); - goto L1214; - - L354: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == LO_SUM && 1) - goto L355; - x1 = XEXP (x0, 0); - goto L1214; - - L355: - x3 = XEXP (x2, 0); - if (register_operand (x3, QImode)) - { - ro[1] = x3; - goto L356; - } - x1 = XEXP (x0, 0); - goto L1214; - - L356: - x3 = XEXP (x2, 1); - if (immediate_operand (x3, VOIDmode)) - { - ro[2] = x3; - return 75; - } - x1 = XEXP (x0, 0); - goto L1214; - - L366: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L367; - } - goto L1214; - - L367: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, QImode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 76; - } - x1 = XEXP (x0, 0); - goto L1214; - - L370: - x1 = XEXP (x0, 1); - ro[1] = x1; - if (TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE) - return 77; - x1 = XEXP (x0, 0); - goto L372; - - L373: - x1 = XEXP (x0, 1); - if (reg_or_nonsymb_mem_operand (x1, TFmode)) - goto L377; - x1 = XEXP (x0, 0); - goto L510; - - L377: - ro[1] = x1; - if (TARGET_FPU - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))) - return 79; - L378: - ro[1] = x1; - if (! TARGET_FPU - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))) - return 80; - x1 = XEXP (x0, 0); - goto L510; - - L511: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != TFmode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - switch (GET_CODE (x1)) - { - case FLOAT_EXTEND: - goto L512; - case FLOAT: - goto L540; - case PLUS: - goto L955; - case MINUS: - goto L970; - case MULT: - goto L1007; - case DIV: - goto L1014; - case NEG: - goto L1029; - case ABS: - goto L1041; - case SQRT: - goto L1053; - } - x1 = XEXP (x0, 0); - goto L1214; - - L512: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SFmode: - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 113; - } - break; - case DFmode: - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 114; - } - } - x1 = XEXP (x0, 0); - goto L1214; - - L540: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 120; - } - x1 = XEXP (x0, 0); - goto L1214; - - L955: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - goto L956; - } - x1 = XEXP (x0, 0); - goto L1214; - - L956: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 178; - } - x1 = XEXP (x0, 0); - goto L1214; - - L970: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - goto L971; - } - x1 = XEXP (x0, 0); - goto L1214; - - L971: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 181; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1007: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != TFmode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - if (GET_CODE (x2) == FLOAT_EXTEND && 1) - goto L1008; - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - goto L986; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1008: - x3 = XEXP (x2, 0); - if (register_operand (x3, DFmode)) - { - ro[1] = x3; - goto L1009; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1009: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == TFmode && GET_CODE (x2) == FLOAT_EXTEND && 1) - goto L1010; - x1 = XEXP (x0, 0); - goto L1214; - - L1010: - x3 = XEXP (x2, 0); - if (register_operand (x3, DFmode)) - { - ro[2] = x3; - if (TARGET_V8 && TARGET_FPU) - return 188; - } - x1 = XEXP (x0, 0); - goto L1214; - - L986: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 184; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1014: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - goto L1015; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1015: - x2 = XEXP (x1, 1); - if (register_operand (x2, TFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 189; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1029: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 192; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1041: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 195; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1053: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 198; - } - x1 = XEXP (x0, 0); - goto L1214; - - L388: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L389; - } - goto L1214; - - L389: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, TFmode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 81; - } - x1 = XEXP (x0, 0); - goto L1214; - - L392: - x1 = XEXP (x0, 1); - ro[1] = x1; - if (TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE) - return 82; - x1 = XEXP (x0, 0); - goto L394; - - L395: - x1 = XEXP (x0, 1); - if (reg_or_nonsymb_mem_operand (x1, DFmode)) - goto L399; - x1 = XEXP (x0, 0); - goto L506; - - L399: - ro[1] = x1; - if (TARGET_FPU - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))) - return 84; - L400: - ro[1] = x1; - if (! TARGET_FPU - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))) - return 85; - x1 = XEXP (x0, 0); - goto L506; - - L507: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != DFmode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - switch (GET_CODE (x1)) - { - case FLOAT_EXTEND: - goto L508; - case FLOAT_TRUNCATE: - goto L528; - case FLOAT: - goto L536; - case PLUS: - goto L960; - case MINUS: - goto L975; - case MULT: - goto L1000; - case DIV: - goto L1019; - case NEG: - goto L1033; - case ABS: - goto L1045; - case SQRT: - goto L1057; - } - x1 = XEXP (x0, 0); - goto L1214; - - L508: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 112; - } - x1 = XEXP (x0, 0); - goto L1214; - - L528: - x2 = XEXP (x1, 0); - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 117; - } - x1 = XEXP (x0, 0); - goto L1214; - - L536: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 119; - } - x1 = XEXP (x0, 0); - goto L1214; - - L960: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - goto L961; - } - x1 = XEXP (x0, 0); - goto L1214; - - L961: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 179; - } - x1 = XEXP (x0, 0); - goto L1214; - - L975: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - goto L976; - } - x1 = XEXP (x0, 0); - goto L1214; - - L976: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 182; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1000: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != DFmode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - if (GET_CODE (x2) == FLOAT_EXTEND && 1) - goto L1001; - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - goto L991; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1001: - x3 = XEXP (x2, 0); - if (register_operand (x3, SFmode)) - { - ro[1] = x3; - goto L1002; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1002: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == DFmode && GET_CODE (x2) == FLOAT_EXTEND && 1) - goto L1003; - x1 = XEXP (x0, 0); - goto L1214; - - L1003: - x3 = XEXP (x2, 0); - if (register_operand (x3, SFmode)) - { - ro[2] = x3; - if (TARGET_V8 && TARGET_FPU) - return 187; - } - x1 = XEXP (x0, 0); - goto L1214; - - L991: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 185; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1019: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - goto L1020; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1020: - x2 = XEXP (x1, 1); - if (register_operand (x2, DFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 190; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1033: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 193; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1045: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 196; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1057: - x2 = XEXP (x1, 0); - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 199; - } - x1 = XEXP (x0, 0); - goto L1214; - - L413: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L414; - } - goto L1214; - - L414: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, DFmode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 87; - } - x1 = XEXP (x0, 0); - goto L1214; - - L420: - x1 = XEXP (x0, 1); - ro[1] = x1; - if (TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE) - return 90; - x1 = XEXP (x0, 0); - goto L422; - - L423: - x1 = XEXP (x0, 1); - if (reg_or_nonsymb_mem_operand (x1, SFmode)) - goto L427; - x1 = XEXP (x0, 0); - goto L518; - - L427: - ro[1] = x1; - if (TARGET_FPU - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))) - return 92; - L428: - ro[1] = x1; - if (! TARGET_FPU - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))) - return 93; - x1 = XEXP (x0, 0); - goto L518; - - L519: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) != SFmode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - switch (GET_CODE (x1)) - { - case FLOAT_TRUNCATE: - goto L520; - case FLOAT: - goto L532; - case PLUS: - goto L965; - case MINUS: - goto L980; - case MULT: - goto L995; - case DIV: - goto L1024; - case NEG: - goto L1037; - case ABS: - goto L1049; - case SQRT: - goto L1061; - } - x1 = XEXP (x0, 0); - goto L1214; - - L520: - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case DFmode: - if (register_operand (x2, DFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 115; - } - break; - case TFmode: - if (register_operand (x2, TFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 116; - } - } - x1 = XEXP (x0, 0); - goto L1214; - - L532: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 118; - } - x1 = XEXP (x0, 0); - goto L1214; - - L965: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - goto L966; - } - x1 = XEXP (x0, 0); - goto L1214; - - L966: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 180; - } - x1 = XEXP (x0, 0); - goto L1214; - - L980: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - goto L981; - } - x1 = XEXP (x0, 0); - goto L1214; - - L981: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 183; - } - x1 = XEXP (x0, 0); - goto L1214; - - L995: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - goto L996; - } - x1 = XEXP (x0, 0); - goto L1214; - - L996: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 186; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1024: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - goto L1025; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1025: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[2] = x2; - if (TARGET_FPU) - return 191; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1037: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 194; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1049: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 197; - } - x1 = XEXP (x0, 0); - goto L1214; - - L1061: - x2 = XEXP (x1, 0); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - if (TARGET_FPU) - return 200; - } - x1 = XEXP (x0, 0); - goto L1214; - - L438: - x2 = XEXP (x1, 0); - if (symbolic_operand (x2, SImode)) - { - ro[0] = x2; - goto L439; - } - goto L1214; - - L439: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && reg_or_0_operand (x1, SFmode)) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 94; - } - x1 = XEXP (x0, 0); - goto L1214; - - L576: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == CC_NOOVmode && GET_CODE (x1) == COMPARE && 1) - goto L577; - x1 = XEXP (x0, 0); - goto L1214; - - L577: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) != SImode) - { - x1 = XEXP (x0, 0); - goto L1214; - } - switch (GET_CODE (x2)) - { - case PLUS: - goto L578; - case MINUS: - goto L616; - case NEG: - goto L914; - } - x1 = XEXP (x0, 0); - goto L1214; - - L578: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[0] = x3; - goto L579; - } - x1 = XEXP (x0, 0); - goto L1214; - - L579: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L580; - } - x1 = XEXP (x0, 0); - goto L1214; - - L580: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 126; - x1 = XEXP (x0, 0); - goto L1214; - - L616: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[0] = x3; - goto L617; - } - x1 = XEXP (x0, 0); - goto L1214; - - L617: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L618; - } - x1 = XEXP (x0, 0); - goto L1214; - - L618: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 130; - x1 = XEXP (x0, 0); - goto L1214; - - L914: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[0] = x3; - goto L915; - } - x1 = XEXP (x0, 0); - goto L1214; - - L915: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - return 171; - x1 = XEXP (x0, 0); - goto L1214; - - L1152: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) == LABEL_REF && 1) - goto L1153; - x1 = XEXP (x0, 0); - goto L1214; - - L1153: - x2 = XEXP (x1, 0); - ro[0] = x2; - return 212; - - L1215: - x1 = XEXP (x0, 1); - if (GET_CODE (x1) == CALL && 1) - goto L1216; - x1 = XEXP (x0, 0); - goto L1241; - - L1216: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MEM && 1) - goto L1217; - x1 = XEXP (x0, 0); - goto L1241; - - L1217: - x3 = XEXP (x2, 0); - if (call_operand_address (x3, SImode)) - { - ro[1] = x3; - goto L1218; - } - x1 = XEXP (x0, 0); - goto L1241; - - L1218: - x2 = XEXP (x1, 1); - if (pnum_clobbers != 0 && 1) - { - ro[2] = x2; - *pnum_clobbers = 1; - return 221; - } - x1 = XEXP (x0, 0); - goto L1241; - - L1242: - x1 = XEXP (x0, 1); - if (address_operand (x1, SImode)) - { - ro[0] = x1; - return 228; - } - goto ret0; - - L1256: - x1 = XEXP (x0, 1); - if (GET_MODE (x1) == SImode && GET_CODE (x1) == FFS && 1) - goto L1257; - goto ret0; - - L1257: - x2 = XEXP (x1, 0); - if (pnum_clobbers != 0 && register_operand (x2, SImode)) - { - ro[1] = x2; - if (TARGET_SPARCLITE) - { - *pnum_clobbers = 1; - return 232; - } - } - goto ret0; - ret0: return -1; -} - -int -recog_5 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - switch (GET_MODE (x2)) - { - case SImode: - switch (GET_CODE (x2)) - { - case NE: - goto L39; - case NEG: - goto L52; - case EQ: - goto L67; - case PLUS: - goto L95; - case MINUS: - goto L112; - case MULT: - goto L641; - case DIV: - goto L680; - case UDIV: - goto L726; - } - } - L281: - if (move_pic_label (x2, SImode)) - { - ro[1] = x2; - goto L282; - } - goto ret0; - - L39: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L40; - } - goto L281; - - L40: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L41; - goto L281; - - L41: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L42; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L42: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 23; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L52: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != SImode) - { - goto L281; - } - switch (GET_CODE (x3)) - { - case NE: - goto L53; - case EQ: - goto L81; - } - goto L281; - - L53: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L54; - } - goto L281; - - L54: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L55; - goto L281; - - L55: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L56; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L56: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 24; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L81: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L82; - } - goto L281; - - L82: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L83; - goto L281; - - L83: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L84; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L84: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 26; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L67: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L68; - } - goto L281; - - L68: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L69; - goto L281; - - L69: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L70; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L70: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 25; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L95: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != SImode) - { - goto L281; - } - switch (GET_CODE (x3)) - { - case NE: - goto L96; - case EQ: - goto L130; - } - goto L281; - - L96: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L97; - } - goto L281; - - L97: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L98; - goto L281; - - L98: - x3 = XEXP (x2, 1); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L99; - } - goto L281; - - L99: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L100; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L100: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 27; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L130: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L131; - } - goto L281; - - L131: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L132; - goto L281; - - L132: - x3 = XEXP (x2, 1); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L133; - } - goto L281; - - L133: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L134; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L134: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 29; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L112: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L113; - } - goto L281; - - L113: - x3 = XEXP (x2, 1); - if (GET_MODE (x3) != SImode) - { - goto L281; - } - switch (GET_CODE (x3)) - { - case NE: - goto L114; - case EQ: - goto L148; - } - goto L281; - - L114: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L115; - } - goto L281; - - L115: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L116; - goto L281; - - L116: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L117; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L117: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 28; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L148: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L149; - } - goto L281; - - L149: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L150; - goto L281; - - L150: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L151; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L151: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 30; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L641: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L642; - } - goto L281; - - L642: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L643; - } - goto L281; - - L643: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L644; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L644: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CC_NOOVmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L645; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L645: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CC_NOOVmode && GET_CODE (x2) == COMPARE && 1) - goto L646; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L646: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == MULT && 1) - goto L647; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L647: - x4 = XEXP (x3, 0); - if (rtx_equal_p (x4, ro[1]) && 1) - goto L648; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L648: - x4 = XEXP (x3, 1); - if (rtx_equal_p (x4, ro[2]) && 1) - goto L649; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L649: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - if (TARGET_V8 || TARGET_SPARCLITE) - return 133; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L680: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L681; - } - goto L281; - - L681: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L682; - } - goto L281; - - L682: - x1 = XVECEXP (x0, 0, 1); - switch (GET_CODE (x1)) - { - case CLOBBER: - goto L683; - case SET: - goto L711; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L683: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_V8) - return 140; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L711: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L712; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L712: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == COMPARE && 1) - goto L713; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L713: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == DIV && 1) - goto L714; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L714: - x4 = XEXP (x3, 0); - if (rtx_equal_p (x4, ro[1]) && 1) - goto L715; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L715: - x4 = XEXP (x3, 1); - if (rtx_equal_p (x4, ro[2]) && 1) - goto L716; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L716: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1) - if (TARGET_V8) - { - *pnum_clobbers = 1; - return 141; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L726: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L727; - } - goto L281; - - L727: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L728; - } - goto L281; - - L728: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L729; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L729: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L730; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L730: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == COMPARE && 1) - goto L731; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L731: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == UDIV && 1) - goto L732; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L732: - x4 = XEXP (x3, 0); - if (rtx_equal_p (x4, ro[1]) && 1) - goto L733; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L733: - x4 = XEXP (x3, 1); - if (rtx_equal_p (x4, ro[2]) && 1) - goto L734; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L734: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - if (TARGET_V8) - return 143; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L281; - - L282: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L283; - goto ret0; - - L283: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - goto L284; - goto ret0; - - L284: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == PC && 1) - return 60; - goto ret0; - ret0: return -1; -} - -int -recog_6 (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - switch (GET_MODE (x2)) - { - case SImode: - if (GET_CODE (x2) == MEM && 1) - goto L321; - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L38; - } - break; - case HImode: - switch (GET_CODE (x2)) - { - case MEM: - goto L340; - } - break; - case QImode: - switch (GET_CODE (x2)) - { - case MEM: - goto L360; - } - break; - case TFmode: - switch (GET_CODE (x2)) - { - case MEM: - goto L382; - } - break; - case DFmode: - switch (GET_CODE (x2)) - { - case MEM: - goto L407; - } - break; - case SFmode: - switch (GET_CODE (x2)) - { - case MEM: - goto L432; - } - break; - case CCmode: - if (GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L461; - break; - case DImode: - if (register_operand (x2, DImode)) - { - ro[0] = x2; - goto L559; - } - break; - case CC_NOOVmode: - switch (GET_CODE (x2)) - { - case REG: - if (XINT (x2, 0) == 0 && 1) - goto L584; - } - } - if (GET_CODE (x2) == PC && 1) - goto L1166; - L1206: - ro[0] = x2; - goto L1207; - L1249: - switch (GET_MODE (x2)) - { - case SImode: - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L1250; - } - L1375: - if (restore_operand (x2, SImode)) - { - ro[0] = x2; - goto L1376; - } - break; - case QImode: - if (restore_operand (x2, QImode)) - { - ro[0] = x2; - goto L1366; - } - break; - case HImode: - if (restore_operand (x2, HImode)) - { - ro[0] = x2; - goto L1371; - } - break; - case SFmode: - if (restore_operand (x2, SFmode)) - { - ro[0] = x2; - goto L1381; - } - L1392: - if (GET_CODE (x2) == REG && XINT (x2, 0) == 32 && 1) - goto L1393; - } - goto ret0; - - L321: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L322; - } - goto L1206; - - L322: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, SImode)) - { - ro[1] = x2; - goto L323; - } - x2 = XEXP (x1, 0); - goto L1206; - - L323: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L324; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L324: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 68; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - L38: - tem = recog_5 (x0, insn, pnum_clobbers); - if (tem >= 0) return tem; - x2 = XEXP (x1, 0); - goto L1206; - - L340: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L341; - } - goto L1206; - - L341: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, HImode)) - { - ro[1] = x2; - goto L342; - } - x2 = XEXP (x1, 0); - goto L1206; - - L342: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L343; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L343: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 72; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L360: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L361; - } - goto L1206; - - L361: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, QImode)) - { - ro[1] = x2; - goto L362; - } - x2 = XEXP (x1, 0); - goto L1206; - - L362: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L363; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L363: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 76; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L382: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L383; - } - goto L1206; - - L383: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, TFmode)) - { - ro[1] = x2; - goto L384; - } - x2 = XEXP (x1, 0); - goto L1206; - - L384: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L385; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L385: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 81; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L407: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L408; - } - goto L1206; - - L408: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, DFmode)) - { - ro[1] = x2; - goto L409; - } - x2 = XEXP (x1, 0); - goto L1206; - - L409: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L410; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L410: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 87; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L432: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[0] = x3; - goto L433; - } - goto L1206; - - L433: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, SFmode)) - { - ro[1] = x2; - goto L434; - } - x2 = XEXP (x1, 0); - goto L1206; - - L434: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L435; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L435: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - return 94; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L461: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == COMPARE && 1) - goto L462; - x2 = XEXP (x1, 0); - goto L1206; - - L462: - x3 = XEXP (x2, 0); - switch (GET_MODE (x3)) - { - case SImode: - switch (GET_CODE (x3)) - { - case ZERO_EXTEND: - goto L463; - case NOT: - goto L865; - } - L845: - if (cc_arithop (x3, SImode)) - { - ro[3] = x3; - goto L846; - } - L887: - if (cc_arithopn (x3, SImode)) - { - ro[3] = x3; - goto L888; - } - break; - case QImode: - if (GET_CODE (x3) == SUBREG && XINT (x3, 1) == 0 && 1) - goto L480; - } - x2 = XEXP (x1, 0); - goto L1206; - - L463: - x4 = XEXP (x3, 0); - if (register_operand (x4, QImode)) - { - ro[1] = x4; - goto L464; - } - goto L845; - - L464: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L465; - x3 = XEXP (x2, 0); - goto L845; - - L465: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L466; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L466: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L467; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L467: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == ZERO_EXTEND && 1) - goto L468; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L468: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - return 102; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L865: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == SImode && GET_CODE (x4) == XOR && 1) - goto L866; - L946: - if (arith_operand (x4, SImode)) - { - ro[1] = x4; - goto L947; - } - goto L845; - - L866: - x5 = XEXP (x4, 0); - if (reg_or_0_operand (x5, SImode)) - { - ro[1] = x5; - goto L867; - } - goto L946; - - L867: - x5 = XEXP (x4, 1); - if (arith_operand (x5, SImode)) - { - ro[2] = x5; - goto L868; - } - goto L946; - - L868: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L869; - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L869: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L870; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L870: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L871; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L871: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L872; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L872: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == XOR && 1) - goto L873; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L873: - x4 = XEXP (x3, 0); - if (rtx_equal_p (x4, ro[1]) && 1) - goto L874; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L874: - x4 = XEXP (x3, 1); - if (rtx_equal_p (x4, ro[2]) && 1) - return 166; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - x4 = XEXP (x3, 0); - goto L946; - - L947: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L948; - x3 = XEXP (x2, 0); - goto L845; - - L948: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L949; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L949: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L950; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L950: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NOT && 1) - goto L951; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L951: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - return 177; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L845; - - L846: - x4 = XEXP (x3, 0); - if (arith_operand (x4, SImode)) - { - ro[1] = x4; - goto L847; - } - goto L887; - - L847: - x4 = XEXP (x3, 1); - if (arith_operand (x4, SImode)) - { - ro[2] = x4; - goto L848; - } - goto L887; - - L848: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L849; - x3 = XEXP (x2, 0); - goto L887; - - L849: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L850; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L887; - - L850: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L851; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L887; - - L851: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[3]) && 1) - return 164; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - x3 = XEXP (x2, 0); - goto L887; - - L888: - x4 = XEXP (x3, 0); - if (GET_MODE (x4) == SImode && GET_CODE (x4) == NOT && 1) - goto L889; - x2 = XEXP (x1, 0); - goto L1206; - - L889: - x5 = XEXP (x4, 0); - if (arith_operand (x5, SImode)) - { - ro[1] = x5; - goto L890; - } - x2 = XEXP (x1, 0); - goto L1206; - - L890: - x4 = XEXP (x3, 1); - if (reg_or_0_operand (x4, SImode)) - { - ro[2] = x4; - goto L891; - } - x2 = XEXP (x1, 0); - goto L1206; - - L891: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L892; - x2 = XEXP (x1, 0); - goto L1206; - - L892: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L893; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L893: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L894; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L894: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[3]) && 1) - return 168; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L480: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L481; - } - x2 = XEXP (x1, 0); - goto L1206; - - L481: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L482; - x2 = XEXP (x1, 0); - goto L1206; - - L482: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L483; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L483: - x2 = XEXP (x1, 0); - if (register_operand (x2, QImode)) - { - ro[0] = x2; - goto L484; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L484: - x2 = XEXP (x1, 1); - if (rtx_equal_p (x2, ro[1]) && 1) - return 104; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L559: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != DImode) - { - x2 = XEXP (x1, 0); - goto L1206; - } - switch (GET_CODE (x2)) - { - case PLUS: - goto L560; - case MINUS: - goto L598; - case NEG: - goto L899; - case ASHIFT: - goto L1066; - case LSHIFT: - goto L1084; - case LSHIFTRT: - goto L1124; - } - x2 = XEXP (x1, 0); - goto L1206; - - L560: - x3 = XEXP (x2, 0); - if (arith_double_operand (x3, DImode)) - { - ro[1] = x3; - goto L561; - } - x2 = XEXP (x1, 0); - goto L1206; - - L561: - x3 = XEXP (x2, 1); - if (arith_double_operand (x3, DImode)) - { - ro[2] = x3; - goto L562; - } - x2 = XEXP (x1, 0); - goto L1206; - - L562: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L563; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L563: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 124; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L598: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L599; - } - x2 = XEXP (x1, 0); - goto L1206; - - L599: - x3 = XEXP (x2, 1); - if (arith_double_operand (x3, DImode)) - { - ro[2] = x3; - goto L600; - } - x2 = XEXP (x1, 0); - goto L1206; - - L600: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L601; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L601: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 128; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L899: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L900; - } - x2 = XEXP (x1, 0); - goto L1206; - - L900: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L901; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L901: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 169; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1066: - x3 = XEXP (x2, 0); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 1 && 1) - goto L1067; - x2 = XEXP (x1, 0); - goto L1206; - - L1067: - x3 = XEXP (x2, 1); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L1068; - } - x2 = XEXP (x1, 0); - goto L1206; - - L1068: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1069; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1069: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return 202; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1084: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L1085; - } - x2 = XEXP (x1, 0); - goto L1206; - - L1085: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && 1) - { - ro[2] = x3; - goto L1086; - } - x2 = XEXP (x1, 0); - goto L1206; - - L1086: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1087; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1087: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - goto L1106; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1106: - ro[3] = x2; - if (INTVAL (operands[2]) < 32) - return 205; - L1107: - ro[3] = x2; - if (INTVAL (operands[2]) >= 32) - return 206; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1124: - x3 = XEXP (x2, 0); - if (register_operand (x3, DImode)) - { - ro[1] = x3; - goto L1125; - } - x2 = XEXP (x1, 0); - goto L1206; - - L1125: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && 1) - { - ro[2] = x3; - goto L1126; - } - x2 = XEXP (x1, 0); - goto L1206; - - L1126: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1127; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1127: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - goto L1146; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1146: - ro[3] = x2; - if (INTVAL (operands[2]) < 32) - return 210; - L1147: - ro[3] = x2; - if (INTVAL (operands[2]) >= 32) - return 211; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L584: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CC_NOOVmode && GET_CODE (x2) == COMPARE && 1) - goto L585; - x2 = XEXP (x1, 0); - goto L1206; - - L585: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != SImode) - { - x2 = XEXP (x1, 0); - goto L1206; - } - switch (GET_CODE (x3)) - { - case PLUS: - goto L586; - case MINUS: - goto L624; - case NEG: - goto L921; - } - x2 = XEXP (x1, 0); - goto L1206; - - L586: - x4 = XEXP (x3, 0); - if (arith_operand (x4, SImode)) - { - ro[1] = x4; - goto L587; - } - x2 = XEXP (x1, 0); - goto L1206; - - L587: - x4 = XEXP (x3, 1); - if (arith_operand (x4, SImode)) - { - ro[2] = x4; - goto L588; - } - x2 = XEXP (x1, 0); - goto L1206; - - L588: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L589; - x2 = XEXP (x1, 0); - goto L1206; - - L589: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L590; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L590: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L591; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L591: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == PLUS && 1) - goto L592; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L592: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - goto L593; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L593: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[2]) && 1) - return 127; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L624: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L625; - } - x2 = XEXP (x1, 0); - goto L1206; - - L625: - x4 = XEXP (x3, 1); - if (arith_operand (x4, SImode)) - { - ro[2] = x4; - goto L626; - } - x2 = XEXP (x1, 0); - goto L1206; - - L626: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L627; - x2 = XEXP (x1, 0); - goto L1206; - - L627: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L628; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L628: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L629; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L629: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MINUS && 1) - goto L630; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L630: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - goto L631; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L631: - x3 = XEXP (x2, 1); - if (rtx_equal_p (x3, ro[2]) && 1) - return 131; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L921: - x4 = XEXP (x3, 0); - if (arith_operand (x4, SImode)) - { - ro[1] = x4; - goto L922; - } - x2 = XEXP (x1, 0); - goto L1206; - - L922: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L923; - x2 = XEXP (x1, 0); - goto L1206; - - L923: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L924; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L924: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L925; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L925: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == NEG && 1) - goto L926; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L926: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[1]) && 1) - return 172; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1166: - x2 = XEXP (x1, 1); - if (address_operand (x2, SImode)) - { - ro[0] = x2; - goto L1167; - } - L1173: - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1174; - x2 = XEXP (x1, 0); - goto L1206; - - L1167: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L1168; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1173; - - L1168: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1169; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1173; - - L1169: - x3 = XEXP (x2, 0); - ro[1] = x3; - return 215; - - L1174: - x3 = XEXP (x2, 0); - ro[0] = x3; - goto L1175; - - L1175: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L1176; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1176: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - goto L1177; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1177: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1178; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1178: - x3 = XEXP (x2, 0); - if (rtx_equal_p (x3, ro[0]) && 1) - return 216; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1206; - - L1207: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CALL && 1) - goto L1208; - x2 = XEXP (x1, 0); - goto L1249; - - L1208: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == MEM && 1) - goto L1209; - x2 = XEXP (x1, 0); - goto L1249; - - L1209: - x4 = XEXP (x3, 0); - if (call_operand_address (x4, SImode)) - { - ro[1] = x4; - goto L1210; - } - x2 = XEXP (x1, 0); - goto L1249; - - L1210: - x3 = XEXP (x2, 1); - ro[2] = x3; - goto L1211; - - L1211: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1212; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1249; - - L1212: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - return 221; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1249; - - L1250: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == FFS && 1) - goto L1251; - x2 = XEXP (x1, 0); - goto L1375; - - L1251: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L1252; - } - x2 = XEXP (x1, 0); - goto L1375; - - L1252: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1253; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1375; - - L1253: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[2] = x2; - if (TARGET_SPARCLITE) - return 232; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1375; - - L1376: - x2 = XEXP (x1, 1); - if (arith_operand (x2, SImode)) - { - ro[1] = x2; - goto L1377; - } - L1386: - if (GET_MODE (x2) == SImode && GET_CODE (x2) == PLUS && 1) - goto L1387; - goto ret0; - - L1377: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_EPILOGUE) - return 264; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1386; - - L1387: - x3 = XEXP (x2, 0); - if (arith_operand (x3, SImode)) - { - ro[1] = x3; - goto L1388; - } - goto ret0; - - L1388: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L1389; - } - goto ret0; - - L1389: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_EPILOGUE) - return 266; - goto ret0; - - L1366: - x2 = XEXP (x1, 1); - if (arith_operand (x2, QImode)) - { - ro[1] = x2; - goto L1367; - } - goto ret0; - - L1367: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_EPILOGUE) - return 262; - goto ret0; - - L1371: - x2 = XEXP (x1, 1); - if (arith_operand (x2, HImode)) - { - ro[1] = x2; - goto L1372; - } - goto ret0; - - L1372: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_EPILOGUE) - return 263; - goto ret0; - - L1381: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[1] = x2; - goto L1382; - } - x2 = XEXP (x1, 0); - goto L1392; - - L1382: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_FPU && ! TARGET_EPILOGUE) - return 265; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - goto L1392; - - L1393: - x2 = XEXP (x1, 1); - if (register_operand (x2, SFmode)) - { - ro[0] = x2; - goto L1394; - } - goto ret0; - - L1394: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == RETURN && 1) - if (! TARGET_EPILOGUE) - return 267; - goto ret0; - ret0: return -1; -} - -int -recog (x0, insn, pnum_clobbers) - register rtx x0; - rtx insn; - int *pnum_clobbers; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - int tem; - - L1235: - switch (GET_CODE (x0)) - { - case UNSPEC: - if (GET_MODE (x0) == SImode && XINT (x0, 1) == 0 && XVECLEN (x0, 0) == 2 && 1) - goto L1236; - break; - case SET: - goto L1; - case PARALLEL: - if (XVECLEN (x0, 0) == 2 && 1) - goto L36; - if (XVECLEN (x0, 0) == 3 && 1) - goto L690; - if (XVECLEN (x0, 0) == 4 && 1) - goto L1220; - break; - case CALL: - goto L1187; - case RETURN: - if (! TARGET_EPILOGUE) - return 226; - break; - case CONST_INT: - if (XWINT (x0, 0) == 0 && 1) - return 227; - break; - case UNSPEC_VOLATILE: - if (XINT (x0, 1) == 0 && XVECLEN (x0, 0) == 1 && 1) - goto L1244; - if (XINT (x0, 1) == 1 && XVECLEN (x0, 0) == 1 && 1) - goto L1246; - } - goto ret0; - - L1236: - x1 = XVECEXP (x0, 0, 0); - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L1237; - } - goto ret0; - - L1237: - x1 = XVECEXP (x0, 0, 1); - if (register_operand (x1, SImode)) - { - ro[1] = x1; - return 225; - } - goto ret0; - L1: - return recog_4 (x0, insn, pnum_clobbers); - - L36: - x1 = XVECEXP (x0, 0, 0); - switch (GET_CODE (x1)) - { - case SET: - goto L320; - case CALL: - goto L1181; - } - goto ret0; - L320: - return recog_6 (x0, insn, pnum_clobbers); - - L1181: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MEM && 1) - goto L1182; - goto ret0; - - L1182: - x3 = XEXP (x2, 0); - if (call_operand_address (x3, SImode)) - { - ro[0] = x3; - goto L1183; - } - goto ret0; - - L1183: - x2 = XEXP (x1, 1); - ro[1] = x2; - goto L1184; - - L1184: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1185; - if (pnum_clobbers != 0 && immediate_operand (x1, VOIDmode)) - { - ro[2] = x1; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0) - { - *pnum_clobbers = 1; - return 219; - } - } - goto ret0; - - L1185: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - return 218; - goto ret0; - - L690: - x1 = XVECEXP (x0, 0, 0); - switch (GET_CODE (x1)) - { - case SET: - goto L691; - case CALL: - goto L1192; - } - goto ret0; - - L691: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L692; - } - if (GET_CODE (x2) == PC && 1) - goto L1157; - goto ret0; - - L692: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == DIV && 1) - goto L693; - goto ret0; - - L693: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L694; - } - goto ret0; - - L694: - x3 = XEXP (x2, 1); - if (arith_operand (x3, SImode)) - { - ro[2] = x3; - goto L695; - } - goto ret0; - - L695: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == SET && 1) - goto L696; - goto ret0; - - L696: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - goto L697; - goto ret0; - - L697: - x2 = XEXP (x1, 1); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == COMPARE && 1) - goto L698; - goto ret0; - - L698: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == DIV && 1) - goto L699; - goto ret0; - - L699: - x4 = XEXP (x3, 0); - if (rtx_equal_p (x4, ro[1]) && 1) - goto L700; - goto ret0; - - L700: - x4 = XEXP (x3, 1); - if (rtx_equal_p (x4, ro[2]) && 1) - goto L701; - goto ret0; - - L701: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L702; - goto ret0; - - L702: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L703; - goto ret0; - - L703: - x2 = XEXP (x1, 0); - if (scratch_operand (x2, SImode)) - { - ro[3] = x2; - if (TARGET_V8) - return 141; - } - goto ret0; - - L1157: - x2 = XEXP (x1, 1); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L1158; - } - goto ret0; - - L1158: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == USE && 1) - goto L1159; - goto ret0; - - L1159: - x2 = XEXP (x1, 0); - if (GET_CODE (x2) == LABEL_REF && 1) - goto L1160; - goto ret0; - - L1160: - x3 = XEXP (x2, 0); - ro[1] = x3; - goto L1161; - - L1161: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == USE && 1) - goto L1162; - goto ret0; - - L1162: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - return 214; - goto ret0; - - L1192: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MEM && 1) - goto L1193; - goto ret0; - - L1193: - x3 = XEXP (x2, 0); - if (call_operand_address (x3, SImode)) - { - ro[0] = x3; - goto L1194; - } - goto ret0; - - L1194: - x2 = XEXP (x1, 1); - ro[1] = x2; - goto L1195; - L1232: - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - goto L1233; - goto ret0; - - L1195: - x1 = XVECEXP (x0, 0, 1); - if (immediate_operand (x1, VOIDmode)) - { - ro[2] = x1; - goto L1196; - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1232; - - L1196: - x1 = XVECEXP (x0, 0, 2); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1197; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1232; - - L1197: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0) - return 219; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - goto L1232; - - L1233: - x1 = XVECEXP (x0, 0, 1); - if (memory_operand (x1, DImode)) - { - ro[1] = x1; - goto L1234; - } - goto ret0; - - L1234: - x1 = XVECEXP (x0, 0, 2); - if (pnum_clobbers != 0 && 1) - { - ro[2] = x1; - *pnum_clobbers = 1; - return 223; - } - goto ret0; - - L1220: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == CALL && 1) - goto L1221; - goto ret0; - - L1221: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == MEM && 1) - goto L1222; - goto ret0; - - L1222: - x3 = XEXP (x2, 0); - if (call_operand_address (x3, SImode)) - { - ro[0] = x3; - goto L1223; - } - goto ret0; - - L1223: - x2 = XEXP (x1, 1); - if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1) - goto L1224; - goto ret0; - - L1224: - x1 = XVECEXP (x0, 0, 1); - if (memory_operand (x1, DImode)) - { - ro[1] = x1; - goto L1225; - } - goto ret0; - - L1225: - x1 = XVECEXP (x0, 0, 2); - ro[2] = x1; - goto L1226; - - L1226: - x1 = XVECEXP (x0, 0, 3); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1227; - goto ret0; - - L1227: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == SImode && GET_CODE (x2) == REG && XINT (x2, 0) == 15 && 1) - return 223; - goto ret0; - - L1187: - x1 = XEXP (x0, 0); - if (GET_MODE (x1) == SImode && GET_CODE (x1) == MEM && 1) - goto L1188; - goto ret0; - - L1188: - x2 = XEXP (x1, 0); - if (call_operand_address (x2, SImode)) - { - ro[0] = x2; - goto L1189; - } - goto ret0; - - L1189: - x1 = XEXP (x0, 1); - if (pnum_clobbers != 0 && 1) - { - ro[1] = x1; - *pnum_clobbers = 1; - return 218; - } - goto ret0; - - L1244: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == CONST_INT && XWINT (x1, 0) == 0 && 1) - return 230; - goto ret0; - - L1246: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == CONST_INT && XWINT (x1, 0) == 0 && 1) - return 231; - goto ret0; - ret0: return -1; -} - -rtx -split_1 (x0, insn) - register rtx x0; - rtx insn; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - rtx tem; - - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 1); - if (GET_MODE (x2) != SImode) - goto ret0; - switch (GET_CODE (x2)) - { - case AND: - goto L749; - case IOR: - goto L779; - case XOR: - goto L809; - case NOT: - goto L817; - case NE: - goto L1293; - case NEG: - goto L1301; - case EQ: - goto L1310; - case PLUS: - goto L1327; - case MINUS: - goto L1337; - } - goto ret0; - - L749: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L750; - } - goto ret0; - - L750: - x3 = XEXP (x2, 1); - ro[2] = x3; - goto L751; - - L751: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L752; - goto ret0; - - L752: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff) - return gen_split_147 (operands); - } - goto ret0; - - L779: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L780; - } - goto ret0; - - L780: - x3 = XEXP (x2, 1); - ro[2] = x3; - goto L781; - - L781: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L782; - goto ret0; - - L782: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff) - return gen_split_153 (operands); - } - goto ret0; - - L809: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L810; - } - goto ret0; - - L810: - x3 = XEXP (x2, 1); - ro[2] = x3; - goto L811; - - L811: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L812; - goto ret0; - - L812: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff) - return gen_split_159 (operands); - } - goto ret0; - - L817: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) == SImode && GET_CODE (x3) == XOR && 1) - goto L818; - goto ret0; - - L818: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L819; - } - goto ret0; - - L819: - x4 = XEXP (x3, 1); - ro[2] = x4; - goto L820; - - L820: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L821; - goto ret0; - - L821: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff) - return gen_split_160 (operands); - } - goto ret0; - - L1293: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L1294; - } - goto ret0; - - L1294: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1295; - goto ret0; - - L1295: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1296; - goto ret0; - - L1296: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_239 (operands); - goto ret0; - - L1301: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != SImode) - goto ret0; - switch (GET_CODE (x3)) - { - case NE: - goto L1302; - case EQ: - goto L1319; - } - goto ret0; - - L1302: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1303; - } - goto ret0; - - L1303: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1304; - goto ret0; - - L1304: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1305; - goto ret0; - - L1305: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_240 (operands); - goto ret0; - - L1319: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1320; - } - goto ret0; - - L1320: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1321; - goto ret0; - - L1321: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1322; - goto ret0; - - L1322: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_242 (operands); - goto ret0; - - L1310: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[1] = x3; - goto L1311; - } - goto ret0; - - L1311: - x3 = XEXP (x2, 1); - if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1) - goto L1312; - goto ret0; - - L1312: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1313; - goto ret0; - - L1313: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_241 (operands); - goto ret0; - - L1327: - x3 = XEXP (x2, 0); - if (GET_MODE (x3) != SImode) - goto ret0; - switch (GET_CODE (x3)) - { - case NE: - goto L1328; - case EQ: - goto L1348; - } - goto ret0; - - L1328: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1329; - } - goto ret0; - - L1329: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1330; - goto ret0; - - L1330: - x3 = XEXP (x2, 1); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L1331; - } - goto ret0; - - L1331: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1332; - goto ret0; - - L1332: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_243 (operands); - goto ret0; - - L1348: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1349; - } - goto ret0; - - L1349: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1350; - goto ret0; - - L1350: - x3 = XEXP (x2, 1); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L1351; - } - goto ret0; - - L1351: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1352; - goto ret0; - - L1352: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_245 (operands); - goto ret0; - - L1337: - x3 = XEXP (x2, 0); - if (register_operand (x3, SImode)) - { - ro[2] = x3; - goto L1338; - } - goto ret0; - - L1338: - x3 = XEXP (x2, 1); - if (GET_MODE (x3) != SImode) - goto ret0; - switch (GET_CODE (x3)) - { - case NE: - goto L1339; - case EQ: - goto L1359; - } - goto ret0; - - L1339: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1340; - } - goto ret0; - - L1340: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1341; - goto ret0; - - L1341: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1342; - goto ret0; - - L1342: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_244 (operands); - goto ret0; - - L1359: - x4 = XEXP (x3, 0); - if (register_operand (x4, SImode)) - { - ro[1] = x4; - goto L1360; - } - goto ret0; - - L1360: - x4 = XEXP (x3, 1); - if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1) - goto L1361; - goto ret0; - - L1361: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1362; - goto ret0; - - L1362: - x2 = XEXP (x1, 0); - if (GET_MODE (x2) == CCmode && GET_CODE (x2) == REG && XINT (x2, 0) == 0 && 1) - return gen_split_246 (operands); - goto ret0; - ret0: return 0; -} - -rtx -split_insns (x0, insn) - register rtx x0; - rtx insn; -{ - register rtx *ro = &recog_operand[0]; - register rtx x1, x2, x3, x4, x5; - rtx tem; - - L401: - switch (GET_CODE (x0)) - { - case SET: - goto L402; - case PARALLEL: - if (XVECLEN (x0, 0) == 2 && 1) - goto L746; - } - goto ret0; - - L402: - x1 = XEXP (x0, 0); - if (register_operand (x1, DFmode)) - { - ro[0] = x1; - goto L403; - } - L1273: - if (register_operand (x1, VOIDmode)) - { - ro[0] = x1; - goto L1274; - } - L1282: - if (register_operand (x1, SImode)) - { - ro[0] = x1; - goto L1283; - } - goto ret0; - - L403: - x1 = XEXP (x0, 1); - if (register_operand (x1, DFmode)) - { - ro[1] = x1; - if (reload_completed) - return gen_split_86 (operands); - } - x1 = XEXP (x0, 0); - goto L1273; - - L1274: - x1 = XEXP (x0, 1); - if (memop (x1, VOIDmode)) - { - ro[1] = x1; - goto L1275; - } - L1278: - if (extend_op (x1, VOIDmode)) - { - ro[1] = x1; - goto L1279; - } - x1 = XEXP (x0, 0); - goto L1282; - - L1275: - x2 = XEXP (x1, 0); - if (immediate_operand (x2, SImode)) - { - ro[2] = x2; - if (flag_pic) - return gen_split_235 (operands); - } - goto L1278; - - L1279: - x2 = XEXP (x1, 0); - if (memop (x2, VOIDmode)) - { - ro[2] = x2; - goto L1280; - } - x1 = XEXP (x0, 0); - goto L1282; - - L1280: - x3 = XEXP (x2, 0); - if (immediate_operand (x3, SImode)) - { - ro[3] = x3; - if (flag_pic) - return gen_split_236 (operands); - } - x1 = XEXP (x0, 0); - goto L1282; - - L1283: - x1 = XEXP (x0, 1); - if (immediate_operand (x1, SImode)) - goto L1287; - goto ret0; - - L1287: - ro[1] = x1; - if (! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST - || GET_CODE (operands[1]) == LABEL_REF)) - return gen_split_237 (operands); - L1288: - ro[1] = x1; - if (flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST)) - return gen_split_238 (operands); - goto ret0; - - L746: - x1 = XVECEXP (x0, 0, 0); - if (GET_CODE (x1) == SET && 1) - goto L747; - goto ret0; - - L747: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[0] = x2; - goto L748; - } - L1260: - if (memop (x2, VOIDmode)) - { - ro[0] = x2; - goto L1261; - } - goto ret0; - L748: - tem = split_1 (x0, insn); - if (tem != 0) return tem; - x2 = XEXP (x1, 0); - goto L1260; - - L1261: - x3 = XEXP (x2, 0); - if (symbolic_operand (x3, SImode)) - { - ro[1] = x3; - goto L1262; - } - L1268: - if (immediate_operand (x3, SImode)) - { - ro[1] = x3; - goto L1269; - } - goto ret0; - - L1262: - x2 = XEXP (x1, 1); - if (reg_or_0_operand (x2, VOIDmode)) - { - ro[2] = x2; - goto L1263; - } - x2 = XEXP (x1, 0); - x3 = XEXP (x2, 0); - goto L1268; - - L1263: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1264; - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - x3 = XEXP (x2, 0); - goto L1268; - - L1264: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (! flag_pic) - return gen_split_233 (operands); - } - x1 = XVECEXP (x0, 0, 0); - x2 = XEXP (x1, 0); - x3 = XEXP (x2, 0); - goto L1268; - - L1269: - x2 = XEXP (x1, 1); - if (general_operand (x2, VOIDmode)) - { - ro[2] = x2; - goto L1270; - } - goto ret0; - - L1270: - x1 = XVECEXP (x0, 0, 1); - if (GET_CODE (x1) == CLOBBER && 1) - goto L1271; - goto ret0; - - L1271: - x2 = XEXP (x1, 0); - if (register_operand (x2, SImode)) - { - ro[3] = x2; - if (flag_pic) - return gen_split_234 (operands); - } - goto ret0; - ret0: return 0; -} - diff --git a/gnu/usr.bin/gcc2/arch/sparc/md b/gnu/usr.bin/gcc2/arch/sparc/md deleted file mode 100644 index 188afaabb17..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/md +++ /dev/null @@ -1,3507 +0,0 @@ -;;- Machine description for SPARC chip for GNU C compiler -;; Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. -;; Contributed by Michael Tiemann (tiemann@cygnus.com) - -;; 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Insn type. Used to default other attribute values. - -;; type "unary" insns have one input operand (1) and one output operand (0) -;; type "binary" insns have two input operands (1,2) and one output (0) -;; type "compare" insns have one or two input operands (0,1) and no output -;; type "call_no_delay_slot" is a call followed by an unimp instruction. - -(define_attr "type" - "move,unary,binary,compare,load,store,uncond_branch,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc" - (const_string "binary")) - -;; Set true if insn uses call-clobbered intermediate register. -(define_attr "use_clobbered" "false,true" - (if_then_else (and (eq_attr "type" "address") - (match_operand 0 "clobbered_register" "")) - (const_string "true") - (const_string "false"))) - -;; Length (in # of insns). -(define_attr "length" "" - (cond [(eq_attr "type" "load,fpload") - (if_then_else (match_operand 1 "symbolic_memory_operand" "") - (const_int 2) (const_int 1)) - - (eq_attr "type" "store,fpstore") - (if_then_else (match_operand 0 "symbolic_memory_operand" "") - (const_int 2) (const_int 1)) - - (eq_attr "type" "address") (const_int 2) - - (eq_attr "type" "binary") - (if_then_else (ior (match_operand 2 "arith_operand" "") - (match_operand 2 "arith_double_operand" "")) - (const_int 1) (const_int 3)) - - (eq_attr "type" "multi") (const_int 2) - - (eq_attr "type" "move,unary") - (if_then_else (ior (match_operand 1 "arith_operand" "") - (match_operand 1 "arith_double_operand" "")) - (const_int 1) (const_int 2))] - - (const_int 1))) - -(define_asm_attributes - [(set_attr "length" "1") - (set_attr "type" "multi")]) - -;; Attributes for instruction and branch scheduling - -(define_attr "in_call_delay" "false,true" - (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi") - (const_string "false") - (eq_attr "type" "load,fpload,store,fpstore") - (if_then_else (eq_attr "length" "1") - (const_string "true") - (const_string "false")) - (eq_attr "type" "address") - (if_then_else (eq_attr "use_clobbered" "false") - (const_string "true") - (const_string "false"))] - (if_then_else (eq_attr "length" "1") - (const_string "true") - (const_string "false")))) - -(define_delay (eq_attr "type" "call") - [(eq_attr "in_call_delay" "true") (nil) (nil)]) - -;; ??? Should implement the notion of predelay slots for floating point -;; branches. This would allow us to remove the nop always inserted before -;; a floating point branch. - -;; ??? It is OK for fill_simple_delay_slots to put load/store instructions -;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. -;; This is because doing so will add several pipeline stalls to the path -;; that the load/store did not come from. Unfortunately, there is no way -;; to prevent fill_eager_delay_slots from using load/store without completely -;; disabling them. For the SPEC benchmark set, this is a serious lose, -;; because it prevents us from moving back the final store of inner loops. - -(define_attr "in_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") - (eq_attr "length" "1")) - (const_string "true") - (const_string "false"))) - -(define_attr "in_uncond_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") - (eq_attr "length" "1")) - (const_string "true") - (const_string "false"))) - -(define_attr "in_annul_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") - (eq_attr "length" "1")) - (const_string "true") - (const_string "false"))) - -(define_delay (eq_attr "type" "branch") - [(eq_attr "in_branch_delay" "true") - (nil) (eq_attr "in_annul_branch_delay" "true")]) - -(define_delay (eq_attr "type" "uncond_branch") - [(eq_attr "in_uncond_branch_delay" "true") - (nil) (nil)]) - -;; Function units of the SPARC - -;; (define_function_unit {name} {num-units} {n-users} {test} -;; {ready-delay} {issue-delay} [{conflict-list}]) - -;; The integer ALU. -;; (Noted only for documentation; units that take one cycle do not need to -;; be specified.) - -;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on -;; the inputs. - -;; (define_function_unit "alu" 1 0 -;; (eq_attr "type" "unary,binary,move,address") 1 0) - -;; Memory with load-delay of 1 (i.e., 2 cycle load). -(define_function_unit "memory" 1 1 (eq_attr "type" "load,fpload") 2 0) - -;; SPARC has two floating-point units: the FP ALU, -;; and the FP MUL/DIV/SQRT unit. -;; Instruction timings on the CY7C602 are as follows -;; FABSs 4 -;; FADDs/d 5/5 -;; FCMPs/d 4/4 -;; FDIVs/d 23/37 -;; FMOVs 4 -;; FMULs/d 5/7 -;; FNEGs 4 -;; FSQRTs/d 34/63 -;; FSUBs/d 5/5 -;; FdTOi/s 5/5 -;; FsTOi/d 5/5 -;; FiTOs/d 9/5 - -;; The CY7C602 can only support 2 fp isnsn simultaneously. -;; More insns cause the chip to stall. - -(define_function_unit "fp_alu" 1 1 (eq_attr "type" "fp") 5 0) -(define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpmul") 7 0) -(define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpdiv") 37 0) -(define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpsqrt") 63 0) - -;; Compare instructions. -;; This controls RTL generation and register allocation. - -;; We generate RTL for comparisons and branches by having the cmpxx -;; patterns store away the operands. Then, the scc and bcc patterns -;; emit RTL for both the compare and the branch. -;; -;; We do this because we want to generate different code for an sne and -;; seq insn. In those cases, if the second operand of the compare is not -;; const0_rtx, we want to compute the xor of the two operands and test -;; it against zero. -;; -;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match -;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc -;; insns that actually require more than one machine instruction. - -;; Put cmpsi first among compare insns so it matches two CONST_INT operands. - -(define_expand "cmpsi" - [(set (reg:CC 0) - (compare:CC (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "arith_operand" "")))] - "" - " -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpsf" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "register_operand" "")))] - "TARGET_FPU" - " -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpdf" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" "")))] - "TARGET_FPU" - " -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmptf" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:TF 0 "register_operand" "") - (match_operand:TF 1 "register_operand" "")))] - "TARGET_FPU" - " -{ - sparc_compare_op0 = operands[0]; - sparc_compare_op1 = operands[1]; - DONE; -}") - -;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this -;; without jumps using the addx/subx instructions. For the rest, we do -;; branches. Seq_special and sne_special clobber the CC reg, because they -;; generate addcc/subcc instructions. - -(define_expand "seq_special" - [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (parallel [(set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] - - "" - "{ operands[3] = gen_reg_rtx (SImode); }") - -(define_expand "sne_special" - [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (parallel [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] - "" - "{ operands[3] = gen_reg_rtx (SImode); }") - -(define_expand "seq" - [(set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_dup 1) (const_int 0)))] - "" - " -{ if (GET_MODE (sparc_compare_op0) == SImode) - { - emit_insn (gen_seq_special (operands[0], sparc_compare_op0, - sparc_compare_op1)); - DONE; - } - else - operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "sne" - [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ if (GET_MODE (sparc_compare_op0) == SImode) - { - emit_insn (gen_sne_special (operands[0], sparc_compare_op0, - sparc_compare_op1)); - DONE; - } - else - operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "sgt" - [(set (match_operand:SI 0 "register_operand" "") - (gt:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "slt" - [(set (match_operand:SI 0 "register_operand" "") - (lt:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "sge" - [(set (match_operand:SI 0 "register_operand" "") - (ge:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "sle" - [(set (match_operand:SI 0 "register_operand" "") - (le:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "sgtu" - [(set (match_operand:SI 0 "register_operand" "") - (gtu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - rtx tem; - - /* We can do ltu easily, so if both operands are registers, swap them and - do a LTU. */ - if ((GET_CODE (sparc_compare_op0) == REG - || GET_CODE (sparc_compare_op0) == SUBREG) - && (GET_CODE (sparc_compare_op1) == REG - || GET_CODE (sparc_compare_op1) == SUBREG)) - { - tem = sparc_compare_op0; - sparc_compare_op0 = sparc_compare_op1; - sparc_compare_op1 = tem; - emit_insn (gen_sltu (operands[0])); - DONE; - } - - operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "sltu" - [(set (match_operand:SI 0 "register_operand" "") - (ltu:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "sgeu" - [(set (match_operand:SI 0 "register_operand" "") - (geu:SI (match_dup 1) (const_int 0)))] - "" - " -{ operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "sleu" - [(set (match_operand:SI 0 "register_operand" "") - (leu:SI (match_dup 1) (const_int 0)))] - "" - " -{ - rtx tem; - - /* We can do geu easily, so if both operands are registers, swap them and - do a GEU. */ - if ((GET_CODE (sparc_compare_op0) == REG - || GET_CODE (sparc_compare_op0) == SUBREG) - && (GET_CODE (sparc_compare_op1) == REG - || GET_CODE (sparc_compare_op1) == SUBREG)) - { - tem = sparc_compare_op0; - sparc_compare_op0 = sparc_compare_op1; - sparc_compare_op1 = tem; - emit_insn (gen_sgeu (operands[0])); - DONE; - } - - operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -}") - -;; Now the DEFINE_INSNs for the compare and scc cases. First the compares. - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "arith_operand" "rI")))] - "" - "cmp %r0,%1" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmped %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmpes %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:TF 0 "register_operand" "f") - (match_operand:TF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmpeq %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmpd %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmps %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:TF 0 "register_operand" "f") - (match_operand:TF 1 "register_operand" "f")))] - "TARGET_FPU" - "fcmpq %0,%1" - [(set_attr "type" "fpcmp")]) - -;; The SEQ and SNE patterns are special because they can be done -;; without any branching and do not involve a COMPARE. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;subx %%g0,0,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -;; We can also do (x + (i == 0)) and related, so put them in. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;addx %2,0,%0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 2 "register_operand" "r") - (ne:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;subx %2,0,%0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;subx %2,-1,%0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 2 "register_operand" "r") - (eq:SI (match_operand:SI 1 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - "subcc %%g0,%1,%%g0\;addx %2,-1,%0" - [(set_attr "length" "2")]) - -;; We can also do GEU and LTU directly, but these operate after a -;; compare. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (reg:CC 0) (const_int 0)))] - "" - "addx %%g0,0,%0" - [(set_attr "type" "misc")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] - "" - "subx %%g0,0,%0" - [(set_attr "type" "misc")]) - -;; ??? Combine should canonicalize these next two to the same pattern. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0))) - (match_operand:SI 1 "arith_operand" "rI")))] - "" - "subx %%g0,%1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) - (match_operand:SI 1 "arith_operand" "rI"))))] - "" - "subx %%g0,%1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (reg:CC 0) (const_int 0)))] - "" - "subx %%g0,-1,%0" - [(set_attr "type" "misc")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] - "" - "addx %%g0,-1,%0" - [(set_attr "type" "misc")]) - -;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) - (match_operand:SI 1 "arith_operand" "rI")))] - "" - "addx %%g0,%1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) - (plus:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI"))))] - "" - "addx %1,%2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (ltu:SI (reg:CC 0) (const_int 0))))] - "" - "subx %1,0,%0" - [(set_attr "type" "unary")]) - -;; ??? Combine should canonicalize these next two to the same pattern. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC 0) (const_int 0))))] - "" - "subx %1,%2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) - (match_operand:SI 2 "arith_operand" "rI"))))] - "" - "subx %1,%2,%0") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (geu:SI (reg:CC 0) (const_int 0)) - (match_operand:SI 1 "register_operand" "r")))] - "" - "subx %1,-1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (geu:SI (reg:CC 0) (const_int 0))))] - "" - "addx %1,-1,%0" - [(set_attr "type" "unary")]) - -;; Now we have the generic scc insns. These will be done using a jump. -;; We have to exclude the cases above, since we will not want combine to -;; turn something that does not require a jump into something that does. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))] - "" - "* return output_scc_insn (operands, insn); " - [(set_attr "type" "multi") - (set_attr "length" "3")]) - -;; These control RTL generation for conditional jump insns - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); -}") - -(define_expand "ble" - [(set (pc) - (if_then_else (le (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); -}") - -;; Now match both normal and inverted jump. - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "noov_compare_op" - [(reg 0) (const_int 0)]) - (label_ref (match_operand 1 "" "")) - (pc)))] - "" - "* -{ - return output_cbranch (operands[0], 1, 0, - final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); -}" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "noov_compare_op" - [(reg 0) (const_int 0)]) - (pc) - (label_ref (match_operand 1 "" ""))))] - "" - "* -{ - return output_cbranch (operands[0], 1, 1, - final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); -}" - [(set_attr "type" "branch")]) - -;; Move instructions - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, SImode, NULL_RTX)) - DONE; -}") - -(define_expand "reload_insi" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "general_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (emit_move_sequence (operands, SImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; We must support both 'r' and 'f' registers here, because combine may -;; convert SFmode hard registers to SImode hard registers when simplifying -;; subreg sets. - -;; We cannot combine the similar 'r' and 'f' constraints, because it causes -;; problems with register allocation. Reload might try to put an integer -;; in an fp register, or an fp number is an integer register. - -(define_insn "" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q") - (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))] - "register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || operands[1] == const0_rtx" - "@ - mov %1,%0 - fmovs %1,%0 - sethi %%hi(%a1),%0 - ld %1,%0 - ld %1,%0 - st %r1,%0 - st %r1,%0" - [(set_attr "type" "move,fp,move,load,load,store,store") - (set_attr "length" "*,*,1,*,*,*,*")]) - -;; Special pic pattern, for loading the address of a label into a register. -;; It clobbers o7 because the call puts the return address (i.e. pc value) -;; there. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "move_pic_label" "i")) - (set (reg:SI 15) (pc))] - "" - "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "" "")))] - "check_pic (1)" - "* -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - - if (GET_CODE (op1) == CONST_INT) - { - operands[0] = operand_subword (op0, 1, 0, DImode); - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - if (INTVAL (op1) < 0) - return \"mov -1,%0\"; - else - return \"mov 0,%0\"; - } - else if (GET_CODE (op1) == CONST_DOUBLE) - { - operands[0] = operand_subword (op0, 1, 0, DImode); - operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); - return singlemove_string (operands); - } - else - abort (); - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "2")]) - -;; For PIC, symbol_refs are put inside unspec so that the optimizer won't -;; confuse them with real addresses. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] - "check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (match_operand 1 "" "")))] - "check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (high:HI (match_operand 1 "" "")))] - "check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "immediate_operand" "in")))] - "" - "* -{ - /* Don't output a 64 bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); - return \"or %R1,%%lo(%a2),%R0\"; -}" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - -;; For PIC, symbol_refs are put inside unspec so that the optimizer won't -;; confuse them with real addresses. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] - "" - "or %1,%%lo(%a2),%0" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "immediate_operand" "in")))] - "" - "or %1,%%lo(%a2),%0" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - -(define_insn "" - [(set (mem:SI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:SI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, HImode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") - (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] - "register_operand (operands[0], HImode) - || register_operand (operands[1], HImode) - || operands[1] == const0_rtx" - "@ - mov %1,%0 - sethi %%hi(%a1),%0 - lduh %1,%0 - sth %r1,%0" - [(set_attr "type" "move,move,load,store") - (set_attr "length" "*,1,*,1")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (lo_sum:HI (match_operand:HI 1 "register_operand" "r") - (match_operand 2 "immediate_operand" "in")))] - "" - "or %1,%%lo(%a2),%0" - [(set_attr "length" "1")]) - -(define_insn "" - [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:HI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, QImode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") - (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] - "register_operand (operands[0], QImode) - || register_operand (operands[1], QImode) - || operands[1] == const0_rtx" - "@ - mov %1,%0 - sethi %%hi(%a1),%0 - ldub %1,%0 - stb %r1,%0" - [(set_attr "type" "move,move,load,store") - (set_attr "length" "*,1,*,1")]) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=r") - (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") - (match_operand 2 "immediate_operand" "in")) 0))] - "" - "or %1,%%lo(%a2),%0" - [(set_attr "length" "1")]) - -(define_insn "" - [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:QI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) - -;; ??? We get better code without it. See output_block_move in sparc.c. - -;; The definition of this insn does not really explain what it does, -;; but it should suffice -;; that anything generated as this insn will be recognized as one -;; and that it will not successfully combine with anything. -;(define_expand "movstrsi" -; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) -; (mem:BLK (match_operand:BLK 1 "general_operand" ""))) -; (use (match_operand:SI 2 "nonmemory_operand" "")) -; (use (match_operand:SI 3 "immediate_operand" "")) -; (clobber (match_dup 0)) -; (clobber (match_dup 1)) -; (clobber (match_scratch:SI 4 "")) -; (clobber (reg:SI 0)) -; (clobber (reg:SI 1))])] -; "" -; " -;{ -; /* If the size isn't known, don't emit inline code. output_block_move -; would output code that's much slower than the library function. -; Also don't output code for large blocks. */ -; if (GET_CODE (operands[2]) != CONST_INT -; || GET_CODE (operands[3]) != CONST_INT -; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16) -; FAIL; -; -; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); -; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); -; operands[2] = force_not_mem (operands[2]); -;}") - -;(define_insn "" -; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r")) -; (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) -; (use (match_operand:SI 2 "nonmemory_operand" "rn")) -; (use (match_operand:SI 3 "immediate_operand" "i")) -; (clobber (match_dup 0)) -; (clobber (match_dup 1)) -; (clobber (match_scratch:SI 4 "=&r")) -; (clobber (reg:SI 0)) -; (clobber (reg:SI 1))] -; "" -; "* return output_block_move (operands);" -; [(set_attr "type" "multi") -; (set_attr "length" "6")]) - -;; Floating point move insns - -;; This pattern forces (set (reg:TF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movtf pattern. -(define_insn "" - [(set (match_operand:TF 0 "general_operand" "=?r,f,o") - (match_operand:TF 1 "" "?E,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" - "* -{ - switch (which_alternative) - { - case 0: - return output_move_quad (operands); - case 1: - return output_fp_move_quad (operands); - case 2: - operands[1] = adj_offsettable_operand (operands[0], 4); - operands[2] = adj_offsettable_operand (operands[0], 8); - operands[3] = adj_offsettable_operand (operands[0], 12); - return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; - } -}" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "5,5,5")]) - -(define_expand "movtf" - [(set (match_operand:TF 0 "general_operand" "") - (match_operand:TF 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, TFmode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r") - (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))] - "TARGET_FPU - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -}" - [(set_attr "type" "fp,move,fpstore,store,fpload,load") - (set_attr "length" "4,4,5,5,5,5")]) - -;; Exactly the same as above, except that all `f' cases are deleted. -;; This is necessary to prevent reload from ever trying to use a `f' reg -;; when -mno-fpu. - -(define_insn "" - [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r") - (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))] - "! TARGET_FPU - && (register_operand (operands[0], TFmode) - || register_operand (operands[1], TFmode))" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -}" - [(set_attr "type" "move,store,load") - (set_attr "length" "4,5,5")]) - -(define_insn "" - [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) - (match_operand:TF 1 "reg_or_0_operand" "rf,G")) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "" - "* -{ - output_asm_insn (\"sethi %%hi(%a0),%2\", operands); - if (which_alternative == 0) - return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\"; - else - return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\"; -}" - [(set_attr "type" "store") - (set_attr "length" "5")]) - -;; This pattern forces (set (reg:DF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movdf pattern. - -(define_insn "" - [(set (match_operand:DF 0 "general_operand" "=?r,f,o") - (match_operand:DF 1 "" "?E,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" - "* -{ - switch (which_alternative) - { - case 0: - return output_move_double (operands); - case 1: - return output_fp_move_double (operands); - case 2: - operands[1] = adj_offsettable_operand (operands[0], 4); - return \"st %%g0,%0\;st %%g0,%1\"; - } -}" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "3,3,3")]) - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, DFmode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,&r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))] - "TARGET_FPU - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -}" - [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load") - (set_attr "length" "1,1,2,2,3,3,3,3")]) - -;; Exactly the same as above, except that all `f' cases are deleted. -;; This is necessary to prevent reload from ever trying to use a `f' reg -;; when -mno-fpu. - -(define_insn "" - [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))] - "! TARGET_FPU - && (register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* return output_move_double (operands);" - [(set_attr "type" "store,load,move,store,load") - (set_attr "length" "1,1,2,3,3")]) - -(define_split - [(set (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" ""))] - "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - " -{ operands[2] = operand_subword (operands[0], 0, 0, DFmode); - operands[3] = operand_subword (operands[1], 0, 0, DFmode); - operands[4] = operand_subword (operands[0], 1, 0, DFmode); - operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") - -(define_insn "" - [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i")) - (match_operand:DF 1 "reg_or_0_operand" "rf,G")) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "" - "* -{ - output_asm_insn (\"sethi %%hi(%a0),%2\", operands); - if (which_alternative == 0) - return \"std %1,[%2+%%lo(%a0)]\"; - else - return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\"; -}" - [(set_attr "type" "store") - (set_attr "length" "3")]) - -;; Double-word move insns. - -(define_expand "movdi" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, DImode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?Q") - (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))] - "register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -}" - [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore") - (set_attr "length" "2,3,3,3,2,3,3")]) - -;; Floating-point move insns. - -;; This pattern forces (set (reg:SF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movsf pattern. -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=?r,f,m") - (match_operand:SF 1 "" "?E,m,G"))] - "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" - "* -{ - switch (which_alternative) - { - case 0: - return singlemove_string (operands); - case 1: - return \"ld %1,%0\"; - case 2: - return \"st %%g0,%0\"; - } -}" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "2,1,1")]) - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - if (emit_move_sequence (operands, SFmode, NULL_RTX)) - DONE; -}") - -(define_insn "" - [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q") - (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))] - "TARGET_FPU - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "@ - fmovs %1,%0 - mov %1,%0 - ld %1,%0 - ld %1,%0 - st %r1,%0 - st %r1,%0" - [(set_attr "type" "fp,move,fpload,load,fpstore,store")]) - -;; Exactly the same as above, except that all `f' cases are deleted. -;; This is necessary to prevent reload from ever trying to use a `f' reg -;; when -mno-fpu. - -(define_insn "" - [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") - (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))] - "! TARGET_FPU - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "@ - mov %1,%0 - ld %1,%0 - st %r1,%0" - [(set_attr "type" "move,load,store")]) - -(define_insn "" - [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) - (match_operand:SF 1 "reg_or_0_operand" "rfG")) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) - -;;- zero extension instructions - -;; These patterns originally accepted general_operands, however, slightly -;; better code is generated by only accepting register_operands, and then -;; letting combine generate the ldu[hb] insns. - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] - "" - " -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_16)); - emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] - "" - "lduh %1,%0" - [(set_attr "type" "load")]) - -(define_expand "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))] - "GET_CODE (operands[1]) != CONST_INT" - "@ - and %1,0xff,%0 - ldub %1,%0" - [(set_attr "type" "unary,load") - (set_attr "length" "1")]) - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))] - "GET_CODE (operands[1]) != CONST_INT" - "@ - and %1,0xff,%0 - ldub %1,%0" - [(set_attr "type" "unary,load") - (set_attr "length" "1")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) - (const_int 0)))] - "" - "andcc %0,0xff,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (match_dup 1)))] - "" - "andcc %1,0xff,%0" - [(set_attr "type" "unary")]) - -;; Similarly, handle SI->QI mode truncation followed by a compare. - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0) - (const_int 0)))] - "" - "andcc %0,0xff,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0) - (const_int 0))) - (set (match_operand:QI 0 "register_operand" "=r") - (match_dup 1))] - "" - "andcc %1,0xff,%0" - [(set_attr "type" "unary")]) - -;;- sign extension instructions - -;; These patterns originally accepted general_operands, however, slightly -;; better code is generated by only accepting register_operands, and then -;; letting combine generate the lds[hb] insns. - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] - "" - " -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_16)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] - "" - "ldsh %1,%0" - [(set_attr "type" "load")]) - -(define_expand "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] - "" - " -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - if (GET_CODE (operand0) == SUBREG) - operand0 = XEXP (operand0, 0); - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_24)); - if (GET_MODE (operand0) != SImode) - operand0 = gen_rtx (SUBREG, SImode, operand0, 0); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; -}") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldsb %1,%0" - [(set_attr "type" "load")]) - -(define_expand "extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] - "" - " -{ - rtx temp = gen_reg_rtx (SImode); - rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); - - if (GET_CODE (operand1) == SUBREG) - operand1 = XEXP (operand1, 0); - emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0), - shift_24)); - emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "" - "ldsb %1,%0" - [(set_attr "type" "load")]) - -;; Special pattern for optimizing bit-field compares. This is needed -;; because combine uses this as a canonical form. - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "small_int" "n") - (match_operand:SI 2 "small_int" "n")) - (const_int 0)))] - "INTVAL (operands[2]) > 19" - "* -{ - int len = INTVAL (operands[1]); - int pos = 32 - INTVAL (operands[2]) - len; - unsigned mask = ((1 << len) - 1) << pos; - - operands[1] = gen_rtx (CONST_INT, VOIDmode, mask); - return \"andcc %0,%1,%%g0\"; -}") - -;; Conversions between float, double and long double. - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float_extend:DF - (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fstod %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "extendsftf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (float_extend:TF - (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fstoq %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "extenddftf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (float_extend:TF - (match_operand:DF 1 "register_operand" "f")))] - "TARGET_FPU" - "fdtoq %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF - (match_operand:DF 1 "register_operand" "f")))] - "TARGET_FPU" - "fdtos %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "trunctfsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF - (match_operand:TF 1 "register_operand" "f")))] - "TARGET_FPU" - "fqtos %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "trunctfdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float_truncate:DF - (match_operand:TF 1 "register_operand" "f")))] - "TARGET_FPU" - "fqtod %1,%0" - [(set_attr "type" "fp")]) - -;; Conversion between fixed point and floating point. - -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "register_operand" "f")))] - "TARGET_FPU" - "fitos %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "f")))] - "TARGET_FPU" - "fitod %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "floatsitf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (float:TF (match_operand:SI 1 "register_operand" "f")))] - "TARGET_FPU" - "fitoq %1,%0" - [(set_attr "type" "fp")]) - -;; Convert a float to an actual integer. -;; Truncation is performed as part of the conversion. - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "TARGET_FPU" - "fstoi %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] - "TARGET_FPU" - "fdtoi %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "fix_trunctfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] - "TARGET_FPU" - "fqtoi %1,%0" - [(set_attr "type" "fp")]) - -;;- arithmetic instructions - -(define_insn "adddi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 0))] - "" - "* -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return \"addcc %R1,%2,%R0\;addx %1,-1,%0\"; - return \"addcc %R1,%2,%R0\;addx %1,0,%0\"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"addcc %R1,%2,%R0\;addx %1,-1,%0\"; - return \"addcc %R1,%2,%R0\;addx %1,0,%0\"; - } - return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\"; -}" - [(set_attr "length" "2")]) - -(define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "add %1,%2,%0") - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") - (match_operand:SI 1 "arith_operand" "rI")) - (const_int 0)))] - "" - "addcc %0,%1,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "addcc %1,%2,%0") - -(define_insn "subdi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 0))] - "" - "* -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return \"subcc %R1,%2,%R0\;subx %1,-1,%0\"; - return \"subcc %R1,%2,%R0\;subx %1,0,%0\"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"subcc %R1,%2,%R0\;subx %1,-1,%0\"; - return \"subcc %R1,%2,%R0\;subx %1,0,%0\"; - } - return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\"; -}" - [(set_attr "length" "2")]) - -(define_insn "subsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "sub %1,%2,%0") - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "arith_operand" "rI")) - (const_int 0)))] - "" - "subcc %0,%1,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_dup 1) (match_dup 2)))] - "" - "subcc %1,%2,%0") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] - "TARGET_V8 || TARGET_SPARCLITE" - "smul %1,%2,%0") - -;; It is not known whether this will match. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC_NOOV 0) - (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] - "TARGET_V8 || TARGET_SPARCLITE" - "smulcc %1,%2,%0") - -(define_expand "mulsidi3" - [(set (match_operand:DI 0 "register_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) - (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE" - " -{ - if (CONSTANT_P (operands[2])) - { - emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE" - "smul %1,%2,%R0\;rd %%y,%0" - [(set_attr "length" "2")]) - -;; Extra pattern, because sign_extend of a constant isn't legal. - -(define_insn "const_mulsidi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "small_int" "I")))] - "TARGET_V8 || TARGET_SPARCLITE" - "smul %1,%2,%R0\;rd %%y,%0" - [(set_attr "length" "2")]) - -(define_expand "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) - (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE" - " -{ - if (CONSTANT_P (operands[2])) - { - emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2])); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE" - "umul %1,%2,%R0\;rd %%y,%0" - [(set_attr "length" "2")]) - -;; Extra pattern, because sign_extend of a constant isn't legal. - -(define_insn "const_umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "small_int" "I")))] - "TARGET_V8 || TARGET_SPARCLITE" - "umul %1,%2,%R0\;rd %%y,%0" - [(set_attr "length" "2")]) - -;; The architecture specifies that there must be 3 instructions between -;; a y register write and a use of it for correct results. - -(define_insn "divsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (div:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI"))) - (clobber (match_scratch:SI 3 "=&r"))] - "TARGET_V8" - "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0" - [(set_attr "length" "6")]) - -;; It is not known whether this will match. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (div:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC 0) - (compare:CC (div:SI (match_dup 1) (match_dup 2)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r"))] - "TARGET_V8" - "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0" - [(set_attr "length" "6")]) - -(define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "TARGET_V8" - "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0" - [(set_attr "length" "5")]) - -;; It is not known whether this will match. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC 0) - (compare:CC (udiv:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] - "TARGET_V8" - "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0" - [(set_attr "length" "5")]) - -;;- and instructions -;; We define DImode `and` so with DImode `not` we can get -;; DImode `andn`. Other combinations are possible. - -(define_expand "anddi3" - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (match_operand:DI 1 "arith_double_operand" "") - (match_operand:DI 2 "arith_double_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] - "" - "* -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return \"mov %1,%0\;and %R1,%2,%R0\"; - return \"mov 0,%0\;and %R1,%2,%R0\"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"mov %1,%0\;and %R1,%2,%R0\"; - return \"mov 0,%0\;and %R1,%2,%R0\"; - } - return \"and %1,%2,%0\;and %R1,%R2,%R0\"; -}" - [(set_attr "length" "2")]) - -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "and %1,%2,%0") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (and:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "" ""))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] - " -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] - "" - "andn %2,%1,%0\;andn %R2,%R1,%R0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] - "" - "andn %2,%1,%0") - -(define_expand "iordi3" - [(set (match_operand:DI 0 "register_operand" "") - (ior:DI (match_operand:DI 1 "arith_double_operand" "") - (match_operand:DI 2 "arith_double_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] - "" - "* -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return \"mov -1,%0\;or %R1,%2,%R0\"; - return \"mov %1,%0\;or %R1,%2,%R0\"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"mov -1,%0\;or %R1,%2,%R0\"; - return \"mov %1,%0\;or %R1,%2,%R0\"; - } - return \"or %1,%2,%0\;or %R1,%R2,%R0\"; -}" - [(set_attr "length" "2")]) - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "or %1,%2,%0") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (ior:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "" ""))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] - " -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] - "" - "orn %2,%1,%0\;orn %R2,%R1,%R0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] - "" - "orn %2,%1,%0") - -(define_expand "xordi3" - [(set (match_operand:DI 0 "register_operand" "") - (xor:DI (match_operand:DI 1 "arith_double_operand" "") - (match_operand:DI 2 "arith_double_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] - "" - "* -{ - rtx op2 = operands[2]; - - /* If constant is positive, upper bits zeroed, otherwise unchanged. - Give the assembler a chance to pick the move instruction. */ - if (GET_CODE (op2) == CONST_INT) - { - int sign = INTVAL (op2); - if (sign < 0) - return \"xor %1,-1,%0\;xor %R1,%2,%R0\"; - return \"mov %1,%0\;xor %R1,%2,%R0\"; - } - else if (GET_CODE (op2) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"xor %1,-1,%0\;xor %R1,%2,%R0\"; - return \"mov %1,%0\;xor %R1,%2,%R0\"; - } - return \"xor %1,%2,%0\;xor %R1,%R2,%R0\"; -}" - [(set_attr "length" "2")]) - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "xor %r1,%2,%0") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (xor:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "" ""))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] - " -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "" "")))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "GET_CODE (operands[2]) == CONST_INT - && !SMALL_INT (operands[2]) - && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] - " -{ - operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); -}") - -;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). -;; Combine now canonicalizes to the rightmost expression. -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "register_operand" "r"))))] - "" - "xnor %1,%2,%0\;xnor %R1,%R2,%R0" - [(set_attr "length" "2")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") - (match_operand:SI 2 "arith_operand" "rI"))))] - "" - "xnor %r1,%2,%0") - -;; These correspond to the above in the case where we also (or only) -;; want to set the condition code. - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (match_operator:SI 2 "cc_arithop" - [(match_operand:SI 0 "arith_operand" "%r") - (match_operand:SI 1 "arith_operand" "rI")]) - (const_int 0)))] - "" - "%A2cc %0,%1,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (match_operator:SI 3 "cc_arithop" - [(match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI")]) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (match_dup 3))] - "" - "%A3cc %1,%2,%0") - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") - (match_operand:SI 1 "arith_operand" "rI"))) - (const_int 0)))] - "" - "xnorcc %r0,%1,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") - (match_operand:SI 2 "arith_operand" "rI"))) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (not:SI (xor:SI (match_dup 1) (match_dup 2))))] - "" - "xnorcc %r1,%2,%0") - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (match_operator:SI 2 "cc_arithopn" - [(not:SI (match_operand:SI 0 "arith_operand" "rI")) - (match_operand:SI 1 "reg_or_0_operand" "rJ")]) - (const_int 0)))] - "" - "%B2cc %r1,%0,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC - (match_operator:SI 3 "cc_arithopn" - [(not:SI (match_operand:SI 1 "arith_operand" "rI")) - (match_operand:SI 2 "reg_or_0_operand" "rJ")]) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (match_dup 3))] - "" - "%B3cc %r2,%1,%0") - -;; We cannot use the "neg" pseudo insn because the Sun assembler -;; does not know how to make it work for constants. - -(define_insn "negdi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (clobber (reg:SI 0))] - "" - "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -(define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] - "" - "sub %%g0,%1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) - (const_int 0)))] - "" - "subcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC_NOOV 0) - (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_dup 1)))] - "" - "subcc %%g0,%1,%0" - [(set_attr "type" "unary")]) - -;; We cannot use the "not" pseudo insn because the Sun assembler -;; does not know how to make it work for constants. -(define_expand "one_cmpldi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] - "" - "* -{ - rtx op1 = operands[1]; - - if (GET_CODE (op1) == CONST_INT) - { - int sign = INTVAL (op1); - if (sign < 0) - return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\"; - return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\"; - } - else if (GET_CODE (op1) == CONST_DOUBLE) - { - int sign = CONST_DOUBLE_HIGH (op1); - operands[1] = gen_rtx (CONST_INT, VOIDmode, - CONST_DOUBLE_LOW (operands[1])); - if (sign < 0) - return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\"; - return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\"; - } - return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\"; -}" - [(set_attr "type" "unary") - (set_attr "length" "2")]) - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_operand:SI 1 "arith_operand" "rI")))] - "" - "xnor %%g0,%1,%0" - [(set_attr "type" "unary")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) - (const_int 0)))] - "" - "xnorcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) - -(define_insn "" - [(set (reg:CC 0) - (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_dup 1)))] - "" - "xnorcc %%g0,%1,%0" - [(set_attr "type" "unary")]) - -;; Floating point arithmetic instructions. - -(define_insn "addtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (plus:TF (match_operand:TF 1 "register_operand" "f") - (match_operand:TF 2 "register_operand" "f")))] - "TARGET_FPU" - "faddq %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "adddf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (plus:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "TARGET_FPU" - "faddd %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "addsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (plus:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "TARGET_FPU" - "fadds %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "subtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (minus:TF (match_operand:TF 1 "register_operand" "f") - (match_operand:TF 2 "register_operand" "f")))] - "TARGET_FPU" - "fsubq %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "subdf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "TARGET_FPU" - "fsubd %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "subsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (minus:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "TARGET_FPU" - "fsubs %1,%2,%0" - [(set_attr "type" "fp")]) - -(define_insn "multf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (mult:TF (match_operand:TF 1 "register_operand" "f") - (match_operand:TF 2 "register_operand" "f")))] - "TARGET_FPU" - "fmulq %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "muldf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (mult:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "TARGET_FPU" - "fmuld %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (mult:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "TARGET_FPU" - "fmuls %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) - (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] - "TARGET_V8 && TARGET_FPU" - "fsmuld %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "" - [(set (match_operand:TF 0 "register_operand" "=f") - (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f")) - (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))] - "TARGET_V8 && TARGET_FPU" - "fdmulq %1,%2,%0" - [(set_attr "type" "fpmul")]) - -(define_insn "divtf3" - [(set (match_operand:TF 0 "register_operand" "=f") - (div:TF (match_operand:TF 1 "register_operand" "f") - (match_operand:TF 2 "register_operand" "f")))] - "TARGET_FPU" - "fdivq %1,%2,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "divdf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "TARGET_FPU" - "fdivd %1,%2,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "divsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (div:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "TARGET_FPU" - "fdivs %1,%2,%0" - [(set_attr "type" "fpdiv")]) - -(define_insn "negtf2" - [(set (match_operand:TF 0 "register_operand" "=f,f") - (neg:TF (match_operand:TF 1 "register_operand" "0,f")))] - "TARGET_FPU" - "@ - fnegs %0,%0 - fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0" - [(set_attr "type" "fp") - (set_attr "length" "1,4")]) - -(define_insn "negdf2" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (neg:DF (match_operand:DF 1 "register_operand" "0,f")))] - "TARGET_FPU" - "@ - fnegs %0,%0 - fnegs %1,%0\;fmovs %R1,%R0" - [(set_attr "type" "fp") - (set_attr "length" "1,2")]) - -(define_insn "negsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fnegs %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "abstf2" - [(set (match_operand:TF 0 "register_operand" "=f,f") - (abs:TF (match_operand:TF 1 "register_operand" "0,f")))] - "TARGET_FPU" - "@ - fabss %0,%0 - fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0" - [(set_attr "type" "fp") - (set_attr "length" "1,4")]) - -(define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (abs:DF (match_operand:DF 1 "register_operand" "0,f")))] - "TARGET_FPU" - "@ - fabss %0,%0 - fabss %1,%0\;fmovs %R1,%R0" - [(set_attr "type" "fp") - (set_attr "length" "1,2")]) - -(define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fabss %1,%0" - [(set_attr "type" "fp")]) - -(define_insn "sqrttf2" - [(set (match_operand:TF 0 "register_operand" "=f") - (sqrt:TF (match_operand:TF 1 "register_operand" "f")))] - "TARGET_FPU" - "fsqrtq %1,%0" - [(set_attr "type" "fpsqrt")]) - -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] - "TARGET_FPU" - "fsqrtd %1,%0" - [(set_attr "type" "fpsqrt")]) - -(define_insn "sqrtsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] - "TARGET_FPU" - "fsqrts %1,%0" - [(set_attr "type" "fpsqrt")]) - -;;- arithmetic shift instructions - -;; We can trivially handle shifting the constant 1 by 64 bits. -;; For other shifts we use the library routine. -;; ??? Questionable, we can do better than this can't we? -(define_expand "ashldi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "const_double_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:SI 0))])] - "" - " -{ - if (GET_CODE (operands[1]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[1]) == 0 - && CONST_DOUBLE_LOW (operands[1]) == 1) - operands[1] = const1_rtx; - else if (operands[1] != const1_rtx) - FAIL; -}") - -;; ??? Questionable, we can do better than this can't we? -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r") - (ashift:DI (const_int 1) - (match_operand:SI 1 "register_operand" "r"))) - (clobber (reg:SI 0))] - "" - "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0" - [(set_attr "type" "multi") - (set_attr "length" "5")]) - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashift:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "sll %1,%2,%0") - -(define_expand "lshldi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (lshift:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" ""))) - (clobber (match_scratch:SI 3 ""))])] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshift:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=r"))] - "INTVAL (operands[2]) < 32" - "* -{ - operands[4] = GEN_INT (32 - INTVAL (operands[2])); - return \"srl %R1,%4,%3\;sll %R1,%2,%R0\;sll %1,%2,%0\;or %3,%0,%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshift:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=X"))] - "INTVAL (operands[2]) >= 32" - "* -{ - operands[4] = GEN_INT (INTVAL (operands[2]) - 32); - return \"sll %R1,%4,%0\;mov %%g0,%R0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "2")]) - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "sra %1,%2,%0") - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "" - "srl %1,%2,%0") - -(define_expand "lshrdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" ""))) - (clobber (match_scratch:SI 3 ""))])] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=r"))] - "INTVAL (operands[2]) < 32" - "* -{ - operands[4] = GEN_INT (32 - INTVAL (operands[2])); - return \"sll %1,%4,%3\;srl %1,%2,%0\;srl %R1,%2,%R0\;or %3,%R0,%R0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "I"))) - (clobber (match_scratch:SI 3 "=X"))] - "INTVAL (operands[2]) >= 32" - "* -{ - operands[4] = GEN_INT (INTVAL (operands[2]) - 32); - return \"srl %1,%4,%R0\;mov %%g0,%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "2")]) - -;; Unconditional and other jump instructions -;; On the Sparc, by setting the annul bit on an unconditional branch, the -;; following insn is never executed. This saves us a nop. Dbx does not -;; handle such branches though, so we only use them when optimizing. -(define_insn "jump" - [(set (pc) (label_ref (match_operand 0 "" "")))] - "" - "b%* %l0%(" - [(set_attr "type" "uncond_branch")]) - -(define_expand "tablejump" - [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r")) - (use (label_ref (match_operand 1 "" "")))])] - "" - " -{ - /* We need to use the PC value in %o7 that was set up when the address - of the label was loaded into a register, so we need different RTL. */ - if (flag_pic) - { - emit_insn (gen_pic_tablejump (operands[0], operands[1])); - DONE; - } -}") - -(define_insn "pic_tablejump" - [(set (pc) (match_operand:SI 0 "register_operand" "r")) - (use (label_ref (match_operand 1 "" ""))) - (use (reg:SI 15))] - "" - "jmp %%o7+%0%#" - [(set_attr "type" "uncond_branch")]) - -(define_insn "" - [(set (pc) (match_operand:SI 0 "address_operand" "p")) - (use (label_ref (match_operand 1 "" "")))] - "" - "jmp %a0%#" - [(set_attr "type" "uncond_branch")]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 0 "" ""))) - (set (reg:SI 15) (label_ref (match_dup 0)))] - "" - "call %l0%#" - [(set_attr "type" "uncond_branch")]) - -;; This pattern recognizes the "instruction" that appears in -;; a function call that wants a structure value, -;; to inform the called function if compiled with Sun CC. -;(define_insn "" -; [(match_operand:SI 0 "immediate_operand" "")] -; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0" -; "unimp %0" -; [(set_attr "type" "marker")]) - -;;- jump to subroutine -(define_expand "call" - ;; Note that this expression is not used for generating RTL. - ;; All the RTL is generated explicitly below. - [(call (match_operand:SI 0 "call_operand" "") - (match_operand 3 "" "i"))] - ;; operands[2] is next_arg_register - ;; operands[3] is struct_value_size_rtx. - "" - " -{ - rtx fn_rtx, nregs_rtx; - - if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) - { - /* This is really a PIC sequence. We want to represent - it as a funny jump so it's delay slots can be filled. - - ??? But if this really *is* a CALL, will not it clobber the - call-clobbered registers? We lose this if it is a JUMP_INSN. - Why cannot we have delay slots filled if it were a CALL? */ - - if (INTVAL (operands[3]) > 0) - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (SET, VOIDmode, pc_rtx, - XEXP (operands[0], 0)), - operands[3], - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - else - emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (SET, VOIDmode, pc_rtx, - XEXP (operands[0], 0)), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - goto finish_call; - } - - fn_rtx = operands[0]; - - /* Count the number of parameter registers being used by this call. - if that argument is NULL, it means we are using them all, which - means 6 on the sparc. */ -#if 0 - if (operands[2]) - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8); - else - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); -#else - nregs_rtx = const0_rtx; -#endif - - if (INTVAL (operands[3]) > 0) - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), - operands[3], - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - else - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), - gen_rtx (CLOBBER, VOIDmode, - gen_rtx (REG, SImode, 15))))); - - finish_call: -#if 0 - /* If this call wants a structure value, - emit an unimp insn to let the called function know about this. */ - if (INTVAL (operands[3]) > 0) - { - rtx insn = emit_insn (operands[3]); - SCHED_GROUP_P (insn) = 1; - } -#endif - - DONE; -}") - -(define_insn "" - [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) - (match_operand 1 "" "")) - (clobber (reg:SI 15))] - ;;- Do not use operand 1 for most machines. - "" - "* -{ - return \"call %a0,%1%#\"; -}" - [(set_attr "type" "call")]) - -;; This is a call that wants a structure value. -(define_insn "" - [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) - (match_operand 1 "" "")) - (match_operand 2 "immediate_operand" "") - (clobber (reg:SI 15))] - ;;- Do not use operand 1 for most machines. - "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" - "* -{ - return \"call %a0,%1\;nop\;unimp %2\"; -}" - [(set_attr "type" "call_no_delay_slot")]) - -(define_expand "call_value" - [(set (match_operand 0 "register_operand" "=rf") - (call (match_operand:SI 1 "" "") - (match_operand 4 "" "")))] - ;; operand 3 is next_arg_register - "" - " -{ - rtx fn_rtx, nregs_rtx; - rtvec vec; - - fn_rtx = operands[1]; - -#if 0 - if (operands[3]) - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8); - else - nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); -#else - nregs_rtx = const0_rtx; -#endif - - vec = gen_rtvec (2, - gen_rtx (SET, VOIDmode, operands[0], - gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15))); - - emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec)); - - DONE; -}") - -(define_insn "" - [(set (match_operand 0 "" "=rf") - (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS")) - (match_operand 2 "" ""))) - (clobber (reg:SI 15))] - ;;- Do not use operand 2 for most machines. - "" - "* -{ - return \"call %a1,%2%#\"; -}" - [(set_attr "type" "call")]) - -(define_expand "untyped_call" - [(parallel [(call (match_operand:SI 0 "call_operand" "") - (const_int 0)) - (match_operand:BLK 1 "memory_operand" "") - (match_operand 2 "" "") - (clobber (reg:SI 15))])] - "" - " -{ - operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0)); -}") - -;; Make a call followed by two nops in case the function being called -;; returns a structure value and expects to skip an unimp instruction. - -(define_insn "" - [(call (mem:SI (match_operand:SI 0 "call_operand_address" "rS")) - (const_int 0)) - (match_operand:DI 1 "memory_operand" "o") - (match_operand 2 "" "") - (clobber (reg:SI 15))] - "" - "* -{ - operands[2] = adj_offsettable_operand (operands[1], 8); - return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\"; -}" - [(set_attr "type" "multi")]) - -;; Prepare to return any type including a structure value. - -(define_expand "untyped_return" - [(match_operand:BLK 0 "memory_operand" "") - (match_operand 1 "" "")] - "" - " -{ - rtx valreg1 = gen_rtx (REG, DImode, 24); - rtx valreg2 = gen_rtx (REG, DFmode, 32); - rtx result = operands[0]; - rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31)); - rtx value = gen_reg_rtx (SImode); - - /* Fetch the instruction where we will return to and see if it's an unimp - instruction (the most significant 10 bits will be zero). If so, - update the return address to skip the unimp instruction. */ - emit_move_insn (value, - gen_rtx (MEM, SImode, plus_constant (rtnreg, 8))); - emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); - emit_insn (gen_update_return (rtnreg, value)); - - /* Reload the function value registers. */ - emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0))); - emit_move_insn (valreg2, - change_address (result, DFmode, - plus_constant (XEXP (result, 0), 8))); - - /* Put USE insns before the return. */ - emit_insn (gen_rtx (USE, VOIDmode, valreg1)); - emit_insn (gen_rtx (USE, VOIDmode, valreg2)); - - /* Construct the return. */ - expand_null_return (); - - DONE; -}") - -;; This is a bit of a hack. We're incrementing a fixed register (%i7), -;; and parts of the compiler don't want to believe that the add is needed. - -(define_insn "update_return" - [(unspec:SI [(match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "register_operand" "r")] 0)] - "" - "cmp %1,0\;be,a .+8\;add %0,4,%0" - [(set_attr "type" "multi")]) - -(define_insn "return" - [(return)] - "! TARGET_EPILOGUE" - "* return output_return (operands);" - [(set_attr "type" "multi")]) - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "address_operand" "p"))] - "" - "jmp %a0%#" - [(set_attr "type" "uncond_branch")]) - -(define_expand "nonlocal_goto" - [(match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "") - (match_operand:SI 3 "" "")] - "" - " -{ - /* Trap instruction to flush all the registers window. */ - emit_insn (gen_flush_register_windows ()); - /* Load the fp value for the containing fn into %fp. - This is needed because operands[2] refers to %fp. - Virtual register instantiation fails if the virtual %fp isn't set from a - register. Thus we must copy operands[0] into a register if it isn't - already one. */ - if (GET_CODE (operands[0]) != REG) - operands[0] = force_reg (SImode, operands[0]); - emit_move_insn (virtual_stack_vars_rtx, operands[0]); - /* Find the containing function's current nonlocal goto handler, - which will do any cleanups and then jump to the label. */ - emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]); - /* Restore %fp from stack pointer value for containing function. - The restore insn that follows will move this to %sp, - and reload the appropriate value into %fp. */ - emit_move_insn (frame_pointer_rtx, operands[2]); - /* Put in the static chain register the nonlocal label address. */ - emit_move_insn (static_chain_rtx, operands[3]); - /* USE of frame_pointer_rtx added for consistency; not clear if - really needed. */ - emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx)); - emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8))); - /* Return, restoring reg window and jumping to goto handler. */ - emit_insn (gen_goto_handler_and_restore ()); - DONE; -}") - -;; Special trap insn to flush register windows. -(define_insn "flush_register_windows" - [(unspec_volatile [(const_int 0)] 0)] - "" - "ta 3" - [(set_attr "type" "misc")]) - -(define_insn "goto_handler_and_restore" - [(unspec_volatile [(const_int 0)] 1)] - "" - "jmp %%o0+0\;restore" - [(set_attr "type" "misc") - (set_attr "length" "2")]) - -;; find first set. - -;; The scan instruction searches from the most significant bit while ffs -;; searches from the least significant bit. The bit index and treatment of -;; zero also differ. It takes at least 7 instructions to get the proper -;; result. Here is an obvious 8 instruction seequence. - -(define_insn "ffssi2" - [(set (match_operand:SI 0 "register_operand" "=&r") - (ffs:SI (match_operand:SI 1 "register_operand" "r"))) - (clobber (match_scratch:SI 2 "=&r"))] - "TARGET_SPARCLITE" - "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -;; Split up troublesome insns for better scheduling. */ - -;; The following patterns are straightforward. They can be applied -;; either before or after register allocation. - -(define_split - [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")]) - (match_operand 2 "reg_or_0_operand" "")) - (clobber (match_operand:SI 3 "register_operand" ""))] - "! flag_pic" - [(set (match_dup 3) (high:SI (match_dup 1))) - (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))]) - (match_dup 2))] - "") - -(define_split - [(set (match_operator 0 "memop" - [(match_operand:SI 1 "immediate_operand" "")]) - (match_operand 2 "general_operand" "")) - (clobber (match_operand:SI 3 "register_operand" ""))] - "flag_pic" - [(set (match_op_dup 0 [(match_dup 1)]) - (match_dup 2))] - " -{ - operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]), - operands[3], 0); -}") - -(define_split - [(set (match_operand 0 "register_operand" "") - (match_operator 1 "memop" - [(match_operand:SI 2 "immediate_operand" "")]))] - "flag_pic" - [(set (match_dup 0) - (match_op_dup 1 [(match_dup 2)]))] - " -{ - operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]), - operands[0], 0); -}") - -;; Sign- and Zero-extend operations can have symbolic memory operands. - -(define_split - [(set (match_operand 0 "register_operand" "") - (match_operator 1 "extend_op" - [(match_operator 2 "memop" - [(match_operand:SI 3 "immediate_operand" "")])]))] - "flag_pic" - [(set (match_dup 0) - (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))] - " -{ - operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]), - operands[0], 0); -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "immediate_operand" ""))] - "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST - || GET_CODE (operands[1]) == LABEL_REF)" - [(set (match_dup 0) (high:SI (match_dup 1))) - (set (match_dup 0) - (lo_sum:SI (match_dup 0) (match_dup 1)))] - "") - -;; LABEL_REFs are not modified by `legitimize_pic_address` -;; so do not recurse infinitely in the PIC case. -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "immediate_operand" ""))] - "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST)" - [(set (match_dup 0) (match_dup 1))] - " -{ - operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0); -}") - -;; These split sne/seq insns. The forms of the resulting insns are -;; somewhat bogus, but they avoid extra patterns and show data dependency. -;; Nothing will look at these in detail after splitting has occurred. - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) - (match_dup 2)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 2 "register_operand" "") - (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (minus:SI (match_dup 2) - (ltu:SI (reg:CC 0) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0)) - (match_dup 2)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 2 "register_operand" "") - (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 0))] - "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (minus:SI (match_dup 2) - (geu:SI (reg:CC 0) (const_int 0))))] - "") - -;; Peepholes go at the end. - -;; Optimize consecutive loads or stores into ldd and std when possible. -;; The conditions in which we do this are very restricted and are -;; explained in the code for {registers,memory}_ok_for_ldd functions. - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=rf") - (match_operand:SI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "=rf") - (match_operand:SI 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "ldd %1,%0") - -(define_peephole - [(set (match_operand:SI 0 "memory_operand" "") - (match_operand:SI 1 "register_operand" "rf")) - (set (match_operand:SI 2 "memory_operand" "") - (match_operand:SI 3 "register_operand" "rf"))] - "registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "std %1,%0") - -(define_peephole - [(set (match_operand:SF 0 "register_operand" "=fr") - (match_operand:SF 1 "memory_operand" "")) - (set (match_operand:SF 2 "register_operand" "=fr") - (match_operand:SF 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) - && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "ldd %1,%0") - -(define_peephole - [(set (match_operand:SF 0 "memory_operand" "") - (match_operand:SF 1 "register_operand" "fr")) - (set (match_operand:SF 2 "memory_operand" "") - (match_operand:SF 3 "register_operand" "fr"))] - "registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "std %1,%0") - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=rf") - (match_operand:SI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "=rf") - (match_operand:SI 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" - "ldd %3,%2") - -(define_peephole - [(set (match_operand:SI 0 "memory_operand" "") - (match_operand:SI 1 "register_operand" "rf")) - (set (match_operand:SI 2 "memory_operand" "") - (match_operand:SI 3 "register_operand" "rf"))] - "registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" - "std %3,%2") - -(define_peephole - [(set (match_operand:SF 0 "register_operand" "=fr") - (match_operand:SF 1 "memory_operand" "")) - (set (match_operand:SF 2 "register_operand" "=fr") - (match_operand:SF 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" - "ldd %3,%2") - -(define_peephole - [(set (match_operand:SF 0 "memory_operand" "") - (match_operand:SF 1 "register_operand" "fr")) - (set (match_operand:SF 2 "memory_operand" "") - (match_operand:SF 3 "register_operand" "fr"))] - "registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" - "std %3,%2") - -;; Optimize the case of following a reg-reg move with a test -;; of reg just moved. Don't allow floating point regs for operand 0 or 1. -;; This can result from a float to fix conversion. - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "register_operand" "r")) - (set (reg:CC 0) - (compare:CC (match_operand:SI 2 "register_operand" "r") - (const_int 0)))] - "(rtx_equal_p (operands[2], operands[0]) - || rtx_equal_p (operands[2], operands[1])) - && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "orcc %1,%%g0,%0") - -;; Do {sign,zero}-extended compares somewhat more efficiently. -;; ??? Is this now the Right Way to do this? Or will SCRATCH -;; eventually have some impact here? - -(define_peephole - [(set (match_operand:HI 0 "register_operand" "") - (match_operand:HI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "") - (sign_extend:SI (match_dup 0))) - (set (reg:CC 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "" - "ldsh %1,%0\;orcc %0,%%g0,%2") - -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (match_operand:QI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "") - (sign_extend:SI (match_dup 0))) - (set (reg:CC 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "" - "ldsb %1,%0\;orcc %0,%%g0,%2") - -(define_peephole - [(set (match_operand:HI 0 "register_operand" "") - (match_operand:HI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "") - (sign_extend:SI (match_dup 0)))] - "dead_or_set_p (insn, operands[0])" - "* -{ - warning (\"bad peephole\"); - if (! MEM_VOLATILE_P (operands[1])) - abort (); - return \"ldsh %1,%2\"; -}") - -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (match_operand:QI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "") - (sign_extend:SI (match_dup 0)))] - "dead_or_set_p (insn, operands[0])" - "* -{ - warning (\"bad peephole\"); - if (! MEM_VOLATILE_P (operands[1])) - abort (); - return \"ldsb %1,%2\"; -}") - -;; Floating-point move peepholes - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_dup 0) - (match_operand:SI 1 "immediate_operand" "i"))) - (set (match_operand:DF 2 "register_operand" "=fr") - (mem:DF (match_dup 0)))] - "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" - "* -{ - /* Go by way of output_move_double in case the register in operand 2 - is not properly aligned for ldd. */ - operands[1] = gen_rtx (MEM, DFmode, - gen_rtx (LO_SUM, SImode, operands[0], operands[1])); - operands[0] = operands[2]; - return output_move_double (operands); -}") - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_dup 0) - (match_operand:SI 1 "immediate_operand" "i"))) - (set (match_operand:SF 2 "register_operand" "=fr") - (mem:SF (match_dup 0)))] - "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" - "ld [%0+%%lo(%a1)],%2") - -;; Return peepholes. First the "normal" ones - -;; ??? There are QImode, HImode, and SImode versions of this pattern. -;; It might be possible to write one more general pattern instead of three. - -(define_insn "" - [(set (match_operand:QI 0 "restore_operand" "") - (match_operand:QI 1 "arith_operand" "rI")) - (return)] - "! TARGET_EPILOGUE" - "* -{ - if (current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; - else - return \"ret\;restore %%g0,%1,%Y0\"; -}" - [(set_attr "type" "multi")]) - -(define_insn "" - [(set (match_operand:HI 0 "restore_operand" "") - (match_operand:HI 1 "arith_operand" "rI")) - (return)] - "! TARGET_EPILOGUE" - "* -{ - if (current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; - else - return \"ret\;restore %%g0,%1,%Y0\"; -}" - [(set_attr "type" "multi")]) - -(define_insn "" - [(set (match_operand:SI 0 "restore_operand" "") - (match_operand:SI 1 "arith_operand" "rI")) - (return)] - "! TARGET_EPILOGUE" - "* -{ - if (current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; - else - return \"ret\;restore %%g0,%1,%Y0\"; -}" - [(set_attr "type" "multi")]) - -;; The following pattern is only generated by delayed-branch scheduling, -;; when the insn winds up in the epilogue. This can only happen when -;; ! TARGET_FPU because otherwise fp return values are in %f0. -(define_insn "" - [(set (match_operand:SF 0 "restore_operand" "r") - (match_operand:SF 1 "register_operand" "r")) - (return)] - "! TARGET_FPU && ! TARGET_EPILOGUE" - "* -{ - if (current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; - else - return \"ret\;restore %%g0,%1,%Y0\"; -}" - [(set_attr "type" "multi")]) - -(define_insn "" - [(set (match_operand:SI 0 "restore_operand" "") - (plus:SI (match_operand:SI 1 "arith_operand" "%r") - (match_operand:SI 2 "arith_operand" "rI"))) - (return)] - "! TARGET_EPILOGUE" - "* -{ - if (current_function_returns_struct) - return \"jmp %%i7+12\;restore %r1,%2,%Y0\"; - else - return \"ret\;restore %r1,%2,%Y0\"; -}" - [(set_attr "type" "multi")]) - -;; Turned off because it should never match (subtracting a constant -;; is turned into addition) and because it would do the wrong thing -;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate). -;;(define_insn "" -;; [(set (match_operand:SI 0 "restore_operand" "") -;; (minus:SI (match_operand:SI 1 "register_operand" "r") -;; (match_operand:SI 2 "small_int" "I"))) -;; (return)] -;; "! TARGET_EPILOGUE" -;; "ret\;restore %1,-(%2),%Y0" -;; [(set_attr "type" "multi")]) - -;; The following pattern is only generated by delayed-branch scheduling, -;; when the insn winds up in the epilogue. -(define_insn "" - [(set (reg:SF 32) - (match_operand:SF 0 "register_operand" "f")) - (return)] - "! TARGET_EPILOGUE" - "ret\;fmovs %0,%%f0" - [(set_attr "type" "multi")]) - -;; Now peepholes to go a call followed by a jump. - -(define_peephole - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r")) - (match_operand 2 "" ""))) - (clobber (reg:SI 15))]) - (set (pc) (label_ref (match_operand 3 "" "")))] - "short_branch (INSN_UID (insn), INSN_UID (operands[3]))" - "* -{ - return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\"; -}") - -(define_peephole - [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r")) - (match_operand 1 "" "")) - (clobber (reg:SI 15))]) - (set (pc) (label_ref (match_operand 2 "" "")))] - "short_branch (INSN_UID (insn), INSN_UID (operands[2]))" - "* -{ - return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\"; -}") - -(define_peephole - [(parallel [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") - (reg:SI 0))) - (clobber (reg:CC 0))]) - (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))] - "" - "subxcc %r1,0,%0") diff --git a/gnu/usr.bin/gcc2/arch/sparc/sparc.h b/gnu/usr.bin/gcc2/arch/sparc/sparc.h deleted file mode 100644 index f072aa34534..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/sparc.h +++ /dev/null @@ -1,1843 +0,0 @@ -/* Definitions of target machine for GNU compiler, for Sun SPARC. - Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com). - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Note that some other tm.h files include this one and then override - many of the definitions that relate to assembler syntax. */ - -#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg} \ - %{a:/usr/lib/bb_link.o}" - -/* Provide required defaults for linker -e and -d switches. */ - -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -/* Special flags to the Sun-4 assembler when using pipe for input. */ - -#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}" - -/* Define macros to distinguish architectures. */ -#define CPP_SPEC "%{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__}" - -/* Prevent error on `-sun4' and `-target sun4' options. */ -/* This used to translate -dalign to -malign, but that is no good - because it can't turn off the usual meaning of making debugging dumps. */ - -#define CC1_SPEC "%{sun4:} %{target:}" - -#if 0 -/* ??? This fails because REAL_VALUE_TYPE is `double' making it impossible to - represent and output `long double' constants. This causes problems during - a bootstrap with enquire/float.h, and hence must be disabled for now. - To fix, we need to implement code for TFmode just like the existing XFmode - support in real.[ch]. */ -/* Sparc ABI says that long double is 4 words. */ - -#define LONG_DOUBLE_TYPE_SIZE 128 -#endif - -#define PTRDIFF_TYPE "int" -/* In 2.4 it should work to delete this. - #define SIZE_TYPE "int" */ -#define WCHAR_TYPE "short unsigned int" -#define WCHAR_TYPE_SIZE 16 - -/* Omit frame pointer at high optimization levels. */ - -#define OPTIMIZATION_OPTIONS(OPTIMIZE) \ -{ \ - if (OPTIMIZE >= 2) \ - { \ - flag_omit_frame_pointer = 1; \ - } \ -} - -/* To make profiling work with -f{pic,PIC}, we need to emit the profiling - code into the rtl. Also, if we are profiling, we cannot eliminate - the frame pointer (because the return address will get smashed). */ - -#define OVERRIDE_OPTIONS \ - do { if (profile_flag || profile_block_flag) \ - flag_omit_frame_pointer = 0, flag_pic = 0; } while (0) - -/* These compiler options take an argument. We ignore -target for now. */ - -#define WORD_SWITCH_TAKES_ARG(STR) \ - (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) \ - || !strcmp (STR, "target") || !strcmp (STR, "assert")) - -/* Names to predefine in the preprocessor for this target machine. */ - -/* The GCC_NEW_VARARGS macro is so that old versions of gcc can compile - new versions, which have an incompatible va-sparc.h file. This matters - because gcc does "gvarargs.h" instead of , and thus gets the - wrong varargs file when it is compiled with a different version of gcc. */ - -#define CPP_PREDEFINES "-Dsparc -Dsun -Dunix -D__NetBSD__ -D__sparc__ -D__GCC_NEW_VARARGS__" - -/* Print subsidiary information on the compiler version in use. */ - -#define TARGET_VERSION fprintf (stderr, " (sparc)"); - -/* Generate DBX debugging information. */ - -#define DBX_DEBUGGING_INFO - -/* Run-time compilation parameters selecting different hardware subsets. */ - -extern int target_flags; - -/* Nonzero if we should generate code to use the fpu. */ -#define TARGET_FPU (target_flags & 1) - -/* Nonzero if we should use FUNCTION_EPILOGUE. Otherwise, we - use fast return insns, but lose some generality. */ -#define TARGET_EPILOGUE (target_flags & 2) - -/* Nonzero if we should assume that double pointers might be unaligned. - This can happen when linking gcc compiled code with other compilers, - because the ABI only guarantees 4 byte alignment. */ -#define TARGET_UNALIGNED_DOUBLES (target_flags & 4) - -/* Nonzero means that we should generate code for a v8 sparc. */ -#define TARGET_V8 (target_flags & 64) - -/* Nonzero means that we should generate code for a sparclite. */ -#define TARGET_SPARCLITE (target_flags & 128) - -/* Nonzero means that we should generate code using a flat register window - model, i.e. no save/restore instructions are generated, in the most - efficient manner. This code is not compatible with normal sparc code. */ -/* This is not a user selectable option yet, because it requires changes - that are not yet switchable via command line arguments. */ -#define TARGET_FRW (target_flags & 256) - -/* Nonzero means that we should generate code using a flat register window - model, i.e. no save/restore instructions are generated, but which is - compatible with normal sparc code. This is the same as above, except - that the frame pointer is %l6 instead of %fp. This code is not as efficient - as TARGET_FRW, because it has one less allocatable register. */ -/* This is not a user selectable option yet, because it requires changes - that are not yet switchable via command line arguments. */ -#define TARGET_FRW_COMPAT (target_flags & 512) - -/* Macro to define tables used to set the flags. - This is a list in braces of pairs in braces, - each pair being { "NAME", VALUE } - where VALUE is the bits to set or minus the bits to clear. - An empty string NAME is used to identify the default VALUE. */ - -#define TARGET_SWITCHES \ - { {"fpu", 1}, \ - {"no-fpu", -1}, \ - {"hard-float", 1}, \ - {"soft-float", -1}, \ - {"epilogue", 2}, \ - {"no-epilogue", -2}, \ - {"unaligned-doubles", 4}, \ - {"no-unaligned-doubles", -4},\ - {"v8", 64}, \ - {"no-v8", -64}, \ - {"sparclite", 128}, \ - {"sparclite", -1}, \ - {"no-sparclite", -128}, \ - {"no-sparclite", 1}, \ -/* {"frw", 256}, */ \ -/* {"no-frw", -256}, */ \ -/* {"frw-compat", 256+512}, */ \ -/* {"no-frw-compat", -(256+512)}, */ \ - { "", TARGET_DEFAULT}} - -#define TARGET_DEFAULT 3 - -/* target machine storage layout */ - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. */ -#define BITS_BIG_ENDIAN 1 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* This is true on the SPARC. */ -#define BYTES_BIG_ENDIAN 1 - -/* Define this if most significant word of a multiword number is the lowest - numbered. */ -/* Doubles are stored in memory with the high order word first. This - matters when cross-compiling. */ -#define WORDS_BIG_ENDIAN 1 - -/* number of bits in an addressable storage unit */ -#define BITS_PER_UNIT 8 - -/* Width in bits of a "word", which is the contents of a machine register. - Note that this is not necessarily the width of data type `int'; - if using 16-bit ints on a 68000, this would still be 32. - But on a machine with 16-bit registers, this would be 16. */ -#define BITS_PER_WORD 32 -#define MAX_BITS_PER_WORD 32 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD 4 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -#define POINTER_SIZE 32 - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY 32 - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY 64 - -/* ALIGN FRAMES on double word boundaries */ - -#define SPARC_STACK_ALIGN(LOC) (((LOC)+7) & 0xfffffff8) - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 32 - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 32 - -/* Every structure's size must be a multiple of this. */ -#define STRUCTURE_SIZE_BOUNDARY 8 - -/* A bitfield declared as `int' forces `int' alignment for the struct. */ -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* No data type wants to be aligned rounder than this. */ -#define BIGGEST_ALIGNMENT 64 - -/* The best alignment to use in cases where we have a choice. */ -#define FASTEST_ALIGNMENT 64 - -/* Make strings word-aligned so strcpy from constants will be faster. */ -#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ - ((TREE_CODE (EXP) == STRING_CST \ - && (ALIGN) < FASTEST_ALIGNMENT) \ - ? FASTEST_ALIGNMENT : (ALIGN)) - -/* Make arrays of chars word-aligned for the same reasons. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN)) - -/* Set this nonzero if move instructions will actually fail to work - when given unaligned data. */ -#define STRICT_ALIGNMENT 1 - -/* Things that must be doubleword aligned cannot go in the text section, - because the linker fails to align the text section enough! - Put them in the data section. */ -#define MAX_TEXT_ALIGN 32 - -#define SELECT_SECTION(T,RELOC) \ -{ \ - if (TREE_CODE (T) == VAR_DECL) \ - { \ - if (TREE_READONLY (T) && ! TREE_SIDE_EFFECTS (T) \ - && DECL_ALIGN (T) <= MAX_TEXT_ALIGN \ - && ! (flag_pic && (RELOC))) \ - text_section (); \ - else \ - data_section (); \ - } \ - else if (TREE_CODE (T) == CONSTRUCTOR) \ - { \ - if (flag_pic != 0 && (RELOC) != 0) \ - data_section (); \ - } \ - else if (*tree_code_type[(int) TREE_CODE (T)] == 'c') \ - { \ - if ((TREE_CODE (T) == STRING_CST && flag_writable_strings) \ - || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN) \ - data_section (); \ - else \ - text_section (); \ - } \ -} - -/* Use text section for a constant - unless we need more alignment than that offers. */ -#define SELECT_RTX_SECTION(MODE, X) \ -{ \ - if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \ - && ! (flag_pic && symbolic_operand (X))) \ - text_section (); \ - else \ - data_section (); \ -} - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - - SPARC has 32 integer registers and 32 floating point registers. */ - -#define FIRST_PSEUDO_REGISTER 64 - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - g0 is used for the condition code and not to represent %g0, which is - hardwired to 0, so reg 0 is *not* fixed. - g1 through g4 are free to use as temporaries. - g5 through g7 are reserved for the operating system. */ -#define FIXED_REGISTERS \ - {0, 0, 0, 0, 0, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 1, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 1, 1, \ - \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0} - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 1, 1, \ - \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1} - -/* If !TARGET_FPU, then make the fp registers fixed so that they won't - be allocated. */ - -#define CONDITIONAL_REGISTER_USAGE \ -do \ - { \ - if (! TARGET_FPU) \ - { \ - int regno; \ - for (regno = 32; regno < 64; regno++) \ - fixed_regs[regno] = 1; \ - } \ - } \ -while (0) - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - - On SPARC, ordinary registers hold 32 bits worth; - this means both integer and floating point registers. - - We use vectors to keep this information about registers. */ - -/* How many hard registers it takes to make a register of this mode. */ -extern int hard_regno_nregs[]; - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Value is 1 if register/mode pair is acceptable on sparc. */ -extern int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER]; - -/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On SPARC, the cpu registers can hold any mode but the float registers - can only hold SFmode or DFmode. See sparc.c for how we - initialize this. */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((hard_regno_mode_ok[REGNO] & (1<<(int)(MODE))) != 0) - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - ((MODE1) == (MODE2) || GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* SPARC pc isn't overloaded on a register that the compiler knows about. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 14 - -/* Actual top-of-stack address is 92 greater than the contents - of the stack pointer register. 92 = 68 + 24. 64 bytes reserving space - for the ins and local registers, 4 byte for structure return address, and - 24 bytes for the 6 register parameters. */ -#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0) - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 30 - -#if 0 -/* Register that is used for the return address. */ -#define RETURN_ADDR_REGNUM 15 -#endif - -/* Value should be nonzero if functions must have frame pointers. - Zero means the frame pointer need not be set up (and parms - may be accessed via the stack pointer) in functions that seem suitable. - This is computed in `reload', in reload1.c. - - Used in flow.c, global.c, and reload1.c. */ -extern int leaf_function; - -#define FRAME_POINTER_REQUIRED \ - (! (leaf_function_p () && only_leaf_regs_used ())) - -/* C statement to store the difference between the frame pointer - and the stack pointer values immediately after the function prologue. - - Note, we always pretend that this is a leaf function because if - it's not, there's no point in trying to eliminate the - frame pointer. If it is a leaf function, we guessed right! */ -#define INITIAL_FRAME_POINTER_OFFSET(VAR) \ - ((VAR) = (TARGET_FRW ? sparc_frw_compute_frame_size (get_frame_size ()) \ - : compute_frame_size (get_frame_size (), 1))) - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 30 - -/* Register in which static-chain is passed to a function. */ -/* ??? */ -#define STATIC_CHAIN_REGNUM 1 - -/* Register which holds offset table for position-independent - data references. */ - -#define PIC_OFFSET_TABLE_REGNUM 23 - -#define INITIALIZE_PIC initialize_pic () -#define FINALIZE_PIC finalize_pic () - -/* Sparc ABI says that quad-precision floats and all structures are returned - in memory. */ -#define RETURN_IN_MEMORY(TYPE) \ - (TYPE_MODE (TYPE) == BLKmode || TYPE_MODE (TYPE) == TFmode) - -/* Functions which return large structures get the address - to place the wanted value at offset 64 from the frame. - Must reserve 64 bytes for the in and local registers. */ -/* Used only in other #defines in this file. */ -#define STRUCT_VALUE_OFFSET 64 - -#define STRUCT_VALUE \ - gen_rtx (MEM, Pmode, \ - gen_rtx (PLUS, Pmode, stack_pointer_rtx, \ - gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))) -#define STRUCT_VALUE_INCOMING \ - gen_rtx (MEM, Pmode, \ - gen_rtx (PLUS, Pmode, frame_pointer_rtx, \ - gen_rtx (CONST_INT, VOIDmode, STRUCT_VALUE_OFFSET))) - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -/* The SPARC has two kinds of registers, general and floating point. */ - -enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES }; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ - {"NO_REGS", "GENERAL_REGS", "FP_REGS", "ALL_REGS" } - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#if 0 && defined (__GNUC__) -#define REG_CLASS_CONTENTS {0LL, 0xfffffffeLL, 0xffffffff00000000LL, 0xfffffffffffffffeLL} -#else -#define REG_CLASS_CONTENTS {{0, 0}, {-2, 0}, {0, -1}, {-2, -1}} -#endif - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) >= 32 ? FP_REGS : (REGNO) == 0 ? NO_REGS : GENERAL_REGS) - -/* This is the order in which to allocate registers - normally. - - We put %f0/%f1 last among the float registers, so as to make it more - likely that a pseduo-register which dies in the float return register - will get allocated to the float return register, thus saving a move - instruction at the end of the function. */ -#define REG_ALLOC_ORDER \ -{ 8, 9, 10, 11, 12, 13, 2, 3, \ - 15, 16, 17, 18, 19, 20, 21, 22, \ - 23, 24, 25, 26, 27, 28, 29, 31, \ - 34, 35, 36, 37, 38, 39, \ - 40, 41, 42, 43, 44, 45, 46, 47, \ - 48, 49, 50, 51, 52, 53, 54, 55, \ - 56, 57, 58, 59, 60, 61, 62, 63, \ - 32, 33, \ - 1, 4, 5, 6, 7, 0, 14, 30} - -/* This is the order in which to allocate registers for - leaf functions. If all registers can fit in the "i" registers, - then we have the possibility of having a leaf function. */ -#define REG_LEAF_ALLOC_ORDER \ -{ 2, 3, 24, 25, 26, 27, 28, 29, \ - 15, 8, 9, 10, 11, 12, 13, \ - 16, 17, 18, 19, 20, 21, 22, 23, \ - 34, 35, 36, 37, 38, 39, \ - 40, 41, 42, 43, 44, 45, 46, 47, \ - 48, 49, 50, 51, 52, 53, 54, 55, \ - 56, 57, 58, 59, 60, 61, 62, 63, \ - 32, 33, \ - 1, 4, 5, 6, 7, 0, 14, 30, 31} - -#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc () - -#define LEAF_REGISTERS \ -{ 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 1, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 0, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1} - -extern char leaf_reg_remap[]; -#define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO]) -extern char leaf_reg_backmap[]; -#define LEAF_REG_BACKMAP(REGNO) (leaf_reg_backmap[REGNO]) - -/* The class value for index registers, and the one for base regs. */ -#define INDEX_REG_CLASS GENERAL_REGS -#define BASE_REG_CLASS GENERAL_REGS - -/* Get reg_class from a letter such as appears in the machine description. */ - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'f' ? FP_REGS : (C) == 'r' ? GENERAL_REGS : NO_REGS) - -/* The letters I, J, K, L and M in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - - For SPARC, `I' is used for the range of constants an insn - can actually contain. - `J' is used for the range which is just zero (since that is R0). - `K' is used for constants which can be loaded with a single sethi insn. */ - -#define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x1000) < 0x2000) - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (unsigned) ((VALUE) + 0x1000) < 0x2000 \ - : (C) == 'J' ? (VALUE) == 0 \ - : (C) == 'K' ? ((VALUE) & 0x3ff) == 0 \ - : 0) - -/* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. */ - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? CONST_DOUBLE_HIGH (VALUE) == 0 \ - && CONST_DOUBLE_LOW (VALUE) == 0 \ - : (C) == 'H' ? arith_double_operand (VALUE, DImode) \ - : 0) - -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. */ -/* We can't load constants into FP registers. We can't load any FP constant - if an 'E' constraint fails to match it. */ -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - (CONSTANT_P (X) \ - && ((CLASS) == FP_REGS \ - || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \ - || HOST_BITS_PER_INT != BITS_PER_WORD))) \ - ? NO_REGS : (CLASS)) - -/* Return the register class of a scratch register needed to load IN into - a register of class CLASS in MODE. - - On the SPARC, when PIC, we need a temporary when loading some addresses - into a register. - - Also, we need a temporary when loading/storing a HImode/QImode value - between memory and the FPU registers. This can happen when combine puts - a paradoxical subreg in a float/fix conversion insn. */ - -#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - (flag_pic && pic_address_needs_scratch (IN) ? GENERAL_REGS \ - : ((CLASS) == FP_REGS && ((MODE) == HImode || (MODE) == QImode)\ - && (GET_CODE (IN) == MEM \ - || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ - && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS) - -#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - ((CLASS) == FP_REGS && ((MODE) == HImode || (MODE) == QImode) \ - && (GET_CODE (IN) == MEM \ - || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ - && true_regnum (IN) == -1)) ? GENERAL_REGS : NO_REGS) - -/* On SPARC it is not possible to directly move data between - GENERAL_REGS and FP_REGS. */ -#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ - (((CLASS1) == FP_REGS && (CLASS2) == GENERAL_REGS) \ - || ((CLASS1) == GENERAL_REGS && (CLASS2) == FP_REGS)) - -/* Return the stack location to use for secondary memory needed reloads. */ -#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ - gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, frame_pointer_rtx, GEN_INT (-8))) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ -/* On SPARC, this is the size of MODE in words. */ -#define CLASS_MAX_NREGS(CLASS, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Stack layout; function entry, exit and calling. */ - -/* Define the number of register that can hold parameters. - These two macros are used only in other macro definitions below. */ -#define NPARM_REGS 6 - -/* Define this if pushing a word on the stack - makes the stack pointer a smaller address. */ -#define STACK_GROWS_DOWNWARD - -/* Define this if the nominal address of the stack frame - is at the high-address end of the local variables; - that is, each additional local variable allocated - goes at a more negative offset in the frame. */ -#define FRAME_GROWS_DOWNWARD - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. */ -#define STARTING_FRAME_OFFSET (-8) - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On SPARC, don't define this because there are no push insns. */ -/* #define PUSH_ROUNDING(BYTES) */ - -/* Offset of first parameter from the argument pointer register value. - This is 64 for the ins and locals, plus 4 for the struct-return reg - even if this function isn't going to use it. */ -#define FIRST_PARM_OFFSET(FNDECL) (STRUCT_VALUE_OFFSET + UNITS_PER_WORD) - -/* When a parameter is passed in a register, stack space is still - allocated for it. */ -#define REG_PARM_STACK_SPACE(DECL) (NPARM_REGS * UNITS_PER_WORD) - -/* Keep the stack pointer constant throughout the function. - This is both an optimization and a necessity: longjmp - doesn't behave itself when the stack pointer moves within - the function! */ -#define ACCUMULATE_OUTGOING_ARGS - -/* Value is the number of bytes of arguments automatically - popped when returning from a subroutine call. - FUNTYPE is the data type of the function (as a tree), - or for a library call it is an identifier node for the subroutine name. - SIZE is the number of bytes of arguments passed on the stack. */ - -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0 - -/* Some subroutine macros specific to this machine. - When !TARGET_FPU, put float return values in the general registers, - since we don't have any fp registers. */ -#define BASE_RETURN_VALUE_REG(MODE) \ - (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8) -#define BASE_OUTGOING_VALUE_REG(MODE) \ - (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \ - : (TARGET_FRW ? 8 : 24)) -#define BASE_PASSING_ARG_REG(MODE) (8) -#define BASE_INCOMING_ARG_REG(MODE) (TARGET_FRW ? 8 : 24) - -/* Define this macro if the target machine has "register windows". This - C expression returns the register number as seen by the called function - corresponding to register number OUT as seen by the calling function. - Return OUT if register number OUT is not an outbound register. */ - -#define INCOMING_REGNO(OUT) \ - ((TARGET_FRW || (OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16) - -/* Define this macro if the target machine has "register windows". This - C expression returns the register number as seen by the calling function - corresponding to register number IN as seen by the called function. - Return IN if register number IN is not an inbound register. */ - -#define OUTGOING_REGNO(IN) \ - ((TARGET_FRW || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16) - -/* Define how to find the value returned by a function. - VALTYPE is the data type of the value (as a tree). - If the precise function being called is known, FUNC is its FUNCTION_DECL; - otherwise, FUNC is 0. */ - -/* On SPARC the value is found in the first "output" register. */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE))) - -/* But the called function leaves it in the first "input" register. */ - -#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \ - gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_OUTGOING_VALUE_REG (TYPE_MODE (VALTYPE))) - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) \ - gen_rtx (REG, MODE, BASE_RETURN_VALUE_REG (MODE)) - -/* 1 if N is a possible register number for a function value - as seen by the caller. - On SPARC, the first "output" reg is used for integer values, - and the first floating point register is used for floating point values. */ - -#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32) - -/* 1 if N is a possible register number for function argument passing. - On SPARC, these are the "output" registers. */ - -#define FUNCTION_ARG_REGNO_P(N) ((N) < 14 && (N) > 7) - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. - - On SPARC, this is a single integer, which is a number of words - of arguments scanned so far (including the invisible argument, - if any, which holds the structure-value-address). - Thus 7 or more means all following args should go on the stack. */ - -#define CUMULATIVE_ARGS int - -#define ROUND_ADVANCE(SIZE) \ - ((SIZE + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* Initialize a variable CUM of type CUMULATIVE_ARGS - for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. - - On SPARC, the offset always starts at 0: the first parm reg is always - the same reg. */ - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) ((CUM) = 0) - -/* Update the data in CUM to advance over an argument - of mode MODE and data type TYPE. - (TYPE is null for libcalls where that information may not be available.) */ - -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM) += ((MODE) != BLKmode \ - ? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \ - : ROUND_ADVANCE (int_size_in_bytes (TYPE)))) - -/* Determine where to put an argument to a function. - Value is zero to push the argument on the stack, - or a hard register in which to store the argument. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ - -/* On SPARC the first six args are normally in registers - and the rest are pushed. Any arg that starts within the first 6 words - is at least partially passed in a register unless its data type forbids. */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ -((CUM) < NPARM_REGS \ - && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \ - && ((TYPE)==0 || (MODE) != BLKmode \ - || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \ - ? gen_rtx (REG, (MODE), (BASE_PASSING_ARG_REG (MODE) + (CUM))) \ - : 0) - -/* Define where a function finds its arguments. - This is different from FUNCTION_ARG because of register windows. */ - -#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \ -((CUM) < NPARM_REGS \ - && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \ - && ((TYPE)==0 || (MODE) != BLKmode \ - || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \ - ? gen_rtx (REG, (MODE), (BASE_INCOMING_ARG_REG (MODE) + (CUM))) \ - : 0) - -/* For an arg passed partly in registers and partly in memory, - this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. - Any arg that starts in the first 6 regs but won't entirely fit in them - needs partial registers on the Sparc. */ - -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ - ((CUM) < NPARM_REGS \ - && ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \ - && ((TYPE)==0 || (MODE) != BLKmode \ - || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \ - && ((CUM) + ((MODE) == BLKmode \ - ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \ - : ROUND_ADVANCE (GET_MODE_SIZE (MODE))) - NPARM_REGS > 0)\ - ? (NPARM_REGS - (CUM)) \ - : 0) - -/* The SPARC ABI stipulates passing struct arguments (of any size) and - quad-precision floats by invisible reference. */ -#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - ((TYPE && (TREE_CODE (TYPE) == RECORD_TYPE \ - || TREE_CODE (TYPE) == UNION_TYPE)) \ - || (MODE == TFmode)) - -/* Define the information needed to generate branch and scc insns. This is - stored from the compare operation. Note that we can't use "rtx" here - since it hasn't been defined! */ - -extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1; - -/* Define the function that build the compare insn for scc and bcc. */ - -extern struct rtx_def *gen_compare_reg (); - -/* Generate the special assembly code needed to tell the assembler whatever - it might need to know about the return value of a function. - - For Sparc assemblers, we need to output a .proc pseudo-op which conveys - information to the assembler relating to peephole optimization (done in - the assembler). */ - -#define ASM_DECLARE_RESULT(FILE, RESULT) \ - fprintf ((FILE), "\t.proc\t0%o\n", sparc_type_code (TREE_TYPE (RESULT))) - -/* Output the label for a function definition. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ -do { \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ -} while (0) - -/* Two views of the size of the current frame. */ -extern int actual_fsize; -extern int apparent_fsize; - -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. */ - -/* On SPARC, move-double insns between fpu and cpu need an 8-byte block - of memory. If any fpu reg is used in the function, we allocate - such a block here, at the bottom of the frame, just in case it's needed. - - If this function is a leaf procedure, then we may choose not - to do a "save" insn. The decision about whether or not - to do this is made in regclass.c. */ - -#define FUNCTION_PROLOGUE(FILE, SIZE) \ - (TARGET_FRW ? sparc_frw_output_function_prologue (FILE, SIZE, leaf_function)\ - : output_function_prologue (FILE, SIZE, leaf_function)) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - do { \ - fputs ("\tsethi %hi(", (FILE)); \ - ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO); \ - fputs ("),%o0\n\tcall mcount\n\tor %lo(", (FILE)); \ - ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO); \ - fputs ("),%o0,%o0\n", (FILE)); \ - } while (0) - -/* Output assembler code to FILE to initialize this source file's - basic block profiling info, if that has not already been done. */ -/* FIXME -- this does not parameterize how it generates labels (like the - above FUNCTION_PROFILER). Broken on Solaris-2. --gnu@cygnus.com */ - -#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \ - (LABELNO), (LABELNO)) - -/* Output assembler code to FILE to increment the entry-count for - the BLOCKNO'th basic block in this source file. */ - -#define BLOCK_PROFILER(FILE, BLOCKNO) \ -{ \ - int blockn = (BLOCKNO); \ - fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\ -\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \ - 4 * blockn, 4 * blockn, 4 * blockn); \ -} - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. The value is tested only in - functions that have frame pointers. - No definition is equivalent to always zero. */ - -extern int current_function_calls_alloca; -extern int current_function_outgoing_args_size; - -#define EXIT_IGNORE_STACK \ - (get_frame_size () != 0 \ - || current_function_calls_alloca || current_function_outgoing_args_size) - -/* This macro generates the assembly code for function exit, - on machines that need it. If FUNCTION_EPILOGUE is not defined - then individual return instructions are generated for each - return statement. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer! - It should use the frame pointer only. This is mandatory because - of alloca; we also take advantage of it to omit stack adjustments - before returning. */ - -/* This declaration is needed due to traditional/ANSI - incompatibilities which cannot be #ifdefed away - because they occur inside of macros. Sigh. */ -extern union tree_node *current_function_decl; - -#define FUNCTION_EPILOGUE(FILE, SIZE) \ - (TARGET_FRW ? sparc_frw_output_function_epilogue (FILE, SIZE, leaf_function)\ - : output_function_epilogue (FILE, SIZE, leaf_function)) - -#define DELAY_SLOTS_FOR_EPILOGUE \ - (TARGET_FRW ? sparc_frw_epilogue_delay_slots () : 1) -#define ELIGIBLE_FOR_EPILOGUE_DELAY(trial, slots_filled) \ - (TARGET_FRW ? sparc_frw_eligible_for_epilogue_delay (trial, slots_filled) \ - : eligible_for_epilogue_delay (trial, slots_filled)) - -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On the sparc, the trampoline contains five instructions: - sethi #TOP_OF_FUNCTION,%g2 - or #BOTTOM_OF_FUNCTION,%g2,%g2 - sethi #TOP_OF_STATIC,%g1 - jmp g2 - or #BOTTOM_OF_STATIC,%g1,%g1 */ -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x81C08000)); \ - ASM_OUTPUT_INT (FILE, gen_rtx (CONST_INT, VOIDmode, 0x00000000)); \ -} - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE 20 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. - - This takes 16 insns: 2 shifts & 2 ands (to split up addresses), 4 sethi - (to load in opcodes), 4 iors (to merge address and opcodes), and 4 writes - (to store insns). This is a bit excessive. Perhaps a different - mechanism would be better here. */ - -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - rtx high_cxt = expand_shift (RSHIFT_EXPR, SImode, CXT, \ - size_int (10), 0, 1); \ - rtx high_fn = expand_shift (RSHIFT_EXPR, SImode, FNADDR, \ - size_int (10), 0, 1); \ - rtx low_cxt = expand_and (CXT, gen_rtx (CONST_INT, VOIDmode, 0x3ff), 0); \ - rtx low_fn = expand_and (FNADDR, gen_rtx (CONST_INT, VOIDmode, 0x3ff), 0); \ - rtx g1_sethi = gen_rtx (HIGH, SImode, \ - gen_rtx (CONST_INT, VOIDmode, 0x03000000)); \ - rtx g2_sethi = gen_rtx (HIGH, SImode, \ - gen_rtx (CONST_INT, VOIDmode, 0x05000000)); \ - rtx g1_ori = gen_rtx (HIGH, SImode, \ - gen_rtx (CONST_INT, VOIDmode, 0x82106000)); \ - rtx g2_ori = gen_rtx (HIGH, SImode, \ - gen_rtx (CONST_INT, VOIDmode, 0x8410A000)); \ - rtx tem = gen_reg_rtx (SImode); \ - emit_move_insn (tem, g2_sethi); \ - emit_insn (gen_iorsi3 (high_fn, high_fn, tem)); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 0)), high_fn);\ - emit_move_insn (tem, g2_ori); \ - emit_insn (gen_iorsi3 (low_fn, low_fn, tem)); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), low_fn);\ - emit_move_insn (tem, g1_sethi); \ - emit_insn (gen_iorsi3 (high_cxt, high_cxt, tem)); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 8)), high_cxt);\ - emit_move_insn (tem, g1_ori); \ - emit_insn (gen_iorsi3 (low_cxt, low_cxt, tem)); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 16)), low_cxt);\ -} - -/* Generate necessary RTL for __builtin_saveregs(). - ARGLIST is the argument list; see expr.c. */ -extern struct rtx_def *sparc_builtin_saveregs (); -#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) sparc_builtin_saveregs (ARGLIST) - -/* Generate RTL to flush the register windows so as to make arbitrary frames - available. */ -#define SETUP_FRAME_ADDRESSES() \ - emit_insn (gen_flush_register_windows ()) - -/* Given an rtx for the address of a frame, - return an rtx for the address of the word in the frame - that holds the dynamic chain--the previous frame's address. */ -#define DYNAMIC_CHAIN_ADDRESS(frame) \ - gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 56)) - -/* The return address isn't on the stack, it is in a register, so we can't - access it from the current frame pointer. We can access it from the - previous frame pointer though by reading a value from the register window - save area. */ -#define RETURN_ADDR_IN_PREVIOUS_FRAME - -/* The current return address is in %i7. The return address of anything - farther back is in the register window save area at [%fp+60]. */ -/* ??? This ignores the fact that the actual return address is +8 for normal - returns, and +12 for structure returns. */ -#define RETURN_ADDR_RTX(count, frame) \ - ((count == -1) \ - ? gen_rtx (REG, Pmode, 31) \ - : copy_to_reg (gen_rtx (MEM, Pmode, \ - memory_address (Pmode, plus_constant (frame, 60))))) - -/* Addressing modes, and classification of registers for them. */ - -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ - -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in local-alloc.c. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ -(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0) -#define REGNO_OK_FOR_BASE_P(REGNO) \ -(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0) -#define REGNO_OK_FOR_FP_P(REGNO) \ -(((REGNO) ^ 0x20) < 32 \ - || (((REGNO) != 0) && (unsigned) (reg_renumber[REGNO] ^ 0x20) < 32)) - -/* Now macros that check whether X is a register and also, - strictly, whether it is in a specified class. - - These macros are specific to the SPARC, and may be used only - in code for printing assembler insns and in conditions for - define_optimization. */ - -/* 1 if X is an fp register. */ - -#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X))) - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -/* Nonzero if the constant value X is a legitimate general operand. - Anything can be made to work except floating point constants. */ - -#define LEGITIMATE_CONSTANT_P(X) \ - (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode) - -/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx - and check its validity for a certain class. - We have two alternate definitions for each of them. - The usual definition accepts all pseudo regs; the other rejects - them unless they have been allocated suitable hard regs. - The symbol REG_OK_STRICT causes the latter definition to be used. - - Most source files want to accept pseudo regs in the hope that - they will get allocated to the class that the insn wants them to be in. - Source files for reload pass need to be strict. - After reload, it makes no difference, since pseudo regs have - been eliminated by then. */ - -/* Optional extra constraints for this machine. Borrowed from romp.h. - - For the SPARC, `Q' means that this is a memory operand but not a - symbolic memory operand. Note that an unassigned pseudo register - is such a memory operand. Needed because reload will generate - these things in insns and then not re-recognize the insns, causing - constrain_operands to fail. - - `S' handles constraints for calls. */ - -#ifndef REG_OK_STRICT - -/* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg. */ -#define REG_OK_FOR_INDEX_P(X) (((unsigned) REGNO (X)) - 32 >= 32 && REGNO (X) != 0) -/* Nonzero if X is a hard reg that can be used as a base reg - or if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) (((unsigned) REGNO (X)) - 32 >= 32 && REGNO (X) != 0) - -#define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' \ - ? ((GET_CODE (OP) == MEM \ - && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \ - && ! symbolic_memory_operand (OP, VOIDmode)) \ - || (reload_in_progress && GET_CODE (OP) == REG \ - && REGNO (OP) >= FIRST_PSEUDO_REGISTER)) \ - : (C) == 'S' \ - ? (CONSTANT_P (OP) || memory_address_p (Pmode, OP)) \ - : (C) == 'T' \ - ? (mem_aligned_8 (OP)) \ - : (C) == 'U' \ - ? (register_ok_for_ldd (OP)) \ - : 0) - -#else - -/* Nonzero if X is a hard reg that can be used as an index. */ -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -/* Nonzero if X is a hard reg that can be used as a base reg. */ -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) - -#define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' \ - ? (GET_CODE (OP) == REG \ - ? (REGNO (OP) >= FIRST_PSEUDO_REGISTER \ - && reg_renumber[REGNO (OP)] < 0) \ - : GET_CODE (OP) == MEM) \ - : (C) == 'S' \ - ? (CONSTANT_P (OP) \ - || (GET_CODE (OP) == REG && reg_renumber[REGNO (OP)] > 0) \ - || strict_memory_address_p (Pmode, OP)) \ - : (C) == 'T' \ - ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, OP) \ - : (C) == 'U' \ - ? register_ok_for_ldd (OP) : 0) -#endif - -/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT - ordinarily. This changes a bit when generating PIC. - - If you change this, execute "rm explow.o recog.o reload.o". */ - -#define RTX_OK_FOR_BASE_P(X) \ - ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ - || (GET_CODE (X) == SUBREG \ - && GET_CODE (SUBREG_REG (X)) == REG \ - && REG_OK_FOR_BASE_P (SUBREG_REG (X)))) - -#define RTX_OK_FOR_INDEX_P(X) \ - ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \ - || (GET_CODE (X) == SUBREG \ - && GET_CODE (SUBREG_REG (X)) == REG \ - && REG_OK_FOR_INDEX_P (SUBREG_REG (X)))) - -#define RTX_OK_FOR_OFFSET_P(X) \ - (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000) - -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ if (RTX_OK_FOR_BASE_P (X)) \ - goto ADDR; \ - else if (GET_CODE (X) == PLUS) \ - { \ - register rtx op0 = XEXP (X, 0); \ - register rtx op1 = XEXP (X, 1); \ - if (flag_pic && op0 == pic_offset_table_rtx) \ - { \ - if (RTX_OK_FOR_BASE_P (op1)) \ - goto ADDR; \ - else if (flag_pic == 1 \ - && GET_CODE (op1) != REG \ - && GET_CODE (op1) != LO_SUM \ - && GET_CODE (op1) != MEM) \ - goto ADDR; \ - } \ - else if (RTX_OK_FOR_BASE_P (op0)) \ - { \ - if (RTX_OK_FOR_INDEX_P (op1) \ - || RTX_OK_FOR_OFFSET_P (op1)) \ - goto ADDR; \ - } \ - else if (RTX_OK_FOR_BASE_P (op1)) \ - { \ - if (RTX_OK_FOR_INDEX_P (op0) \ - || RTX_OK_FOR_OFFSET_P (op0)) \ - goto ADDR; \ - } \ - } \ - else if (GET_CODE (X) == LO_SUM) \ - { \ - register rtx op0 = XEXP (X, 0); \ - register rtx op1 = XEXP (X, 1); \ - if (RTX_OK_FOR_BASE_P (op0) \ - && CONSTANT_P (op1)) \ - goto ADDR; \ - } \ - else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \ - goto ADDR; \ -} - -/* Try machine-dependent ways of modifying an illegitimate address - to be legitimate. If we find one, return the new, valid address. - This macro is used in only one place: `memory_address' in explow.c. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE and WIN are passed so that this macro can use - GO_IF_LEGITIMATE_ADDRESS. - - It is always safe for this macro to do nothing. It exists to recognize - opportunities to optimize the output. */ - -/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */ -extern struct rtx_def *legitimize_pic_address (); -#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ -{ rtx sparc_x = (X); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1), \ - force_operand (XEXP (X, 0), NULL_RTX)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ - force_operand (XEXP (X, 1), NULL_RTX)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS) \ - (X) = gen_rtx (PLUS, Pmode, force_operand (XEXP (X, 0), NULL_RTX),\ - XEXP (X, 1)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ - force_operand (XEXP (X, 1), NULL_RTX)); \ - if (sparc_x != (X) && memory_address_p (MODE, X)) \ - goto WIN; \ - if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0, 0); \ - else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 0), \ - copy_to_mode_reg (Pmode, XEXP (X, 1))); \ - else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ - (X) = gen_rtx (PLUS, Pmode, XEXP (X, 1), \ - copy_to_mode_reg (Pmode, XEXP (X, 0))); \ - else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ - || GET_CODE (X) == LABEL_REF) \ - (X) = gen_rtx (LO_SUM, Pmode, \ - copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \ - if (memory_address_p (MODE, X)) \ - goto WIN; } - -/* Go to LABEL if ADDR (a legitimate address expression) - has an effect that depends on the machine mode it is used for. - On the SPARC this is never true. */ - -#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE SImode - -/* Define this if the tablejump instruction expects the table - to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ -/* #define CASE_VECTOR_PC_RELATIVE */ - -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 1 - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX 8 - -#if 0 /* Sun 4 has matherr, so this is no good. */ -/* This is the value of the error code EDOM for this machine, - used by the sqrt instruction. */ -#define TARGET_EDOM 33 - -/* This is how to refer to the variable errno. */ -#define GEN_ERRNO_RTX \ - gen_rtx (MEM, SImode, gen_rtx (SYMBOL_REF, Pmode, "errno")) -#endif /* 0 */ - -/* Define if normal loads of shorter-than-word items from memory clears - the rest of the bigs in the register. */ -#define BYTE_LOADS_ZERO_EXTEND - -/* Nonzero if access to memory by bytes is slow and undesirable. - For RISC chips, it means that access to memory by bytes is no - better than access by words when possible, so grab a whole word - and maybe make use of that. */ -#define SLOW_BYTE_ACCESS 1 - -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE 1 - -/* When a prototype says `char' or `short', really pass an `int'. */ -#define PROMOTE_PROTOTYPES - -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -#define SHIFT_COUNT_TRUNCATED - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ -#define Pmode SImode - -/* Generate calls to memcpy, memcmp and memset. */ -#define TARGET_MEM_FUNCTIONS - -/* Add any extra modes needed to represent the condition code. - - On the Sparc, we have a "no-overflow" mode which is used when an add or - subtract insn is used to set the condition code. Different branches are - used in this case for some operations. - - We also have two modes to indicate that the relevant condition code is - in the floating-point condition code register. One for comparisons which - will generate an exception if the result is unordered (CCFPEmode) and - one for comparisons which will never trap (CCFPmode). This really should - be a separate register, but we don't want to go to 65 registers. */ -#define EXTRA_CC_MODES CC_NOOVmode, CCFPmode, CCFPEmode - -/* Define the names for the modes specified above. */ -#define EXTRA_CC_NAMES "CC_NOOV", "CCFP", "CCFPE" - -/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, - return the mode to be used for the comparison. For floating-point, - CCFP[E]mode is used. CC_NOOVmode should be used when the first operand is a - PLUS, MINUS, or NEG. CCmode should be used when no special processing is - needed. */ -#define SELECT_CC_MODE(OP,X,Y) \ - (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode) \ - : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS || GET_CODE (X) == NEG) \ - ? CC_NOOVmode : CCmode)) - -/* A function address in a call instruction - is a byte address (for indexing purposes) - so give the MEM rtx a byte's mode. */ -#define FUNCTION_MODE SImode - -/* Define this if addresses of constant functions - shouldn't be put through pseudo regs where they can be cse'd. - Desirable on machines where ordinary constants are expensive - but a CALL with constant address is cheap. */ -#define NO_FUNCTION_CSE - -/* alloca should avoid clobbering the old register save area. */ -#define SETJMP_VIA_SAVE_AREA - -/* Define subroutines to call to handle multiply and divide. - Use the subroutines that Sun's library provides. - The `*' prevents an underscore from being prepended by the compiler. */ - -#define DIVSI3_LIBCALL "*.div" -#define UDIVSI3_LIBCALL "*.udiv" -#define MODSI3_LIBCALL "*.rem" -#define UMODSI3_LIBCALL "*.urem" -/* .umul is a little faster than .mul. */ -#define MULSI3_LIBCALL "*.umul" - -/* Compute the cost of computing a constant rtl expression RTX - whose rtx-code is CODE. The body of this macro is a portion - of a switch statement. If the code is computed here, - return it with a return statement. Otherwise, break from the switch. */ - -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - if (INTVAL (RTX) < 0x1000 && INTVAL (RTX) >= -0x1000) \ - return 0; \ - case HIGH: \ - return 2; \ - case CONST: \ - case LABEL_REF: \ - case SYMBOL_REF: \ - return 4; \ - case CONST_DOUBLE: \ - if (GET_MODE (RTX) == DImode) \ - if ((XINT (RTX, 3) == 0 \ - && (unsigned) XINT (RTX, 2) < 0x1000) \ - || (XINT (RTX, 3) == -1 \ - && XINT (RTX, 2) < 0 \ - && XINT (RTX, 2) >= -0x1000)) \ - return 0; \ - return 8; - -/* SPARC offers addressing modes which are "as cheap as a register". - See sparc.c (or gcc.texinfo) for details. */ - -#define ADDRESS_COST(RTX) \ - (GET_CODE (RTX) == REG ? 1 : sparc_address_cost (RTX)) - -/* Compute extra cost of moving data between one register class - and another. */ -#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ - (((CLASS1 == FP_REGS && CLASS2 == GENERAL_REGS) \ - || (CLASS1 == GENERAL_REGS && CLASS2 == FP_REGS)) ? 6 : 2) - -/* Provide the costs of a rtl expression. This is in the body of a - switch on CODE. The purpose for the cost of MULT is to encourage - `synth_mult' to find a synthetic multiply when reasonable. - - If we need more than 12 insns to do a multiply, then go out-of-line, - since the call overhead will be < 10% of the cost of the multiply. */ - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case MULT: \ - return TARGET_V8 ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \ - case DIV: \ - case UDIV: \ - case MOD: \ - case UMOD: \ - return COSTS_N_INSNS (25); \ - /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\ - so that cse will favor the latter. */ \ - case FLOAT: \ - case FIX: \ - return 19; - -/* Conditional branches with empty delay slots have a length of two. */ -#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ - if (GET_CODE (INSN) == CALL_INSN \ - || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn))) \ - LENGTH += 1; - -/* Control the assembler format that we output. */ - -/* Output at beginning of assembler file. */ - -#define ASM_FILE_START(file) - -/* Output to assembler file text saying following lines - may contain character constants, extra white space, comments, etc. */ - -#define ASM_APP_ON "" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "" - -#define ASM_LONG ".word" -#define ASM_SHORT ".half" -#define ASM_BYTE_OP ".byte" - -/* Output before read-only data. */ - -#define TEXT_SECTION_ASM_OP ".text" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP ".data" - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -#define REGISTER_NAMES \ -{"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7", \ - "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7", \ - "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7", \ - "%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7", \ - "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", \ - "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15", \ - "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23", \ - "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"} - -/* Define additional names for use in asm clobbers and asm declarations. - - We define the fake Condition Code register as an alias for reg 0 (which - is our `condition code' register), so that condition codes can easily - be clobbered by an asm. No such register actually exists. Condition - codes are partly stored in the PSR and partly in the FSR. */ - -#define ADDITIONAL_REGISTER_NAMES {"ccr", 0, "cc", 0} - -/* How to renumber registers for dbx and gdb. */ - -#define DBX_REGISTER_NUMBER(REGNO) (REGNO) - -/* On Sun 4, this limit is 2048. We use 1500 to be safe, - since the length can run past this up to a continuation point. */ -#define DBX_CONTIN_LENGTH 1500 - -/* This is how to output a note to DBX telling it the line number - to which the following sequence of instructions corresponds. - - This is needed for SunOS 4.0, and should not hurt for 3.2 - versions either. */ -#define ASM_OUTPUT_SOURCE_LINE(file, line) \ - { static int sym_lineno = 1; \ - fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \ - line, sym_lineno, sym_lineno); \ - sym_lineno += 1; } - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ - do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0) - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - fprintf (FILE, "_%s", NAME) - -/* This is how to output a definition of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d:\n", PREFIX, NUM) - -/* This is how to output a reference to an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ -/* FIXME: This should be used throughout gcc, and documented in the texinfo - files. There is no reason you should have to allocate a buffer and - `sprintf' to reference an internal label (as opposed to defining it). */ - -#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d", PREFIX, NUM) - -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s%d", PREFIX, NUM) - -/* This is how to output an assembler line defining a `double' constant. */ - -/* Assemblers (both gas 1.35 and as in 4.0.3) - seem to treat -0.0 as if it were 0.0. - They reject 99e9999, but accept inf. */ -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n", \ - ASM_LONG, t[0], ASM_LONG, t[1]); \ - } \ - else \ - fprintf (FILE, "\t.double 0r%.17g\n", VALUE); \ - } - -/* This is how to output an assembler line defining a `float' constant. */ - -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - { \ - if (REAL_VALUE_ISINF (VALUE) \ - || REAL_VALUE_ISNAN (VALUE) \ - || REAL_VALUE_MINUS_ZERO (VALUE)) \ - { \ - long t; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t); \ - } \ - else \ - fprintf (FILE, "\t.single 0r%.9g\n", VALUE); \ - } - -/* This is how to output an assembler line defining a `long double' - constant. */ - -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ - { \ - long t[4]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), t); \ - fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n\t%s\t0x%lx\n", \ - ASM_LONG, t[0], ASM_LONG, t[1], ASM_LONG, t[2], ASM_LONG, t[3]); \ - } - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fprintf (FILE, "\t%s\t", ASM_LONG), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line defining a DImode constant. */ -#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE) \ - output_double_int (FILE, VALUE) - -/* Likewise for `char' and `short' constants. */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "\t%s\t", ASM_SHORT), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fprintf (FILE, "\t%s\t", ASM_BYTE_OP), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE)) - -/* This is how to output an element of a case-vector that is absolute. */ - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ -do { \ - char label[30]; \ - ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \ - fprintf (FILE, "\t.word\t"); \ - assemble_name (FILE, label); \ - fprintf (FILE, "\n"); \ -} while (0) - -/* This is how to output an element of a case-vector that is relative. - (SPARC uses such vectors only when generating PIC.) */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ -do { \ - char label[30]; \ - ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \ - fprintf (FILE, "\t.word\t"); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-1b\n"); \ -} while (0) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) != 0) \ - fprintf (FILE, "\t.align %d\n", (1<<(LOG))) - -#define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.skip %u\n", (SIZE)) - -/* This says how to output an assembler line - to define a global common symbol. */ - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs ("\t.global ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fputs ("\n\t.common ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u,\"bss\"\n", (ROUNDED))) - -/* This says how to output an assembler line - to define a local common symbol. */ - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs ("\n\t.reserve ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u,\"bss\"\n", (ROUNDED))) - -/* Store in OUTPUT a string (made with alloca) containing - an assembler-name for a local static variable named NAME. - LABELNO is an integer which is different for each call. */ - -#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ -( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ - sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) - -#define IDENT_ASM_OP ".ident" - -/* Output #ident as a .ident. */ - -#define ASM_OUTPUT_IDENT(FILE, NAME) \ - fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME); - -/* Define the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "(" -#define ASM_CLOSE_PAREN ")" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - -#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ - ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(') - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and X is null. */ - -#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE) - -/* Print a memory address as an operand to reference that memory location. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ -{ register rtx base, index = 0; \ - int offset = 0; \ - register rtx addr = ADDR; \ - if (GET_CODE (addr) == REG) \ - fputs (reg_names[REGNO (addr)], FILE); \ - else if (GET_CODE (addr) == PLUS) \ - { \ - if (GET_CODE (XEXP (addr, 0)) == CONST_INT) \ - offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\ - else if (GET_CODE (XEXP (addr, 1)) == CONST_INT) \ - offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\ - else \ - base = XEXP (addr, 0), index = XEXP (addr, 1); \ - fputs (reg_names[REGNO (base)], FILE); \ - if (index == 0) \ - fprintf (FILE, "%+d", offset); \ - else if (GET_CODE (index) == REG) \ - fprintf (FILE, "+%s", reg_names[REGNO (index)]); \ - else if (GET_CODE (index) == SYMBOL_REF) \ - fputc ('+', FILE), output_addr_const (FILE, index); \ - else abort (); \ - } \ - else if (GET_CODE (addr) == MINUS \ - && GET_CODE (XEXP (addr, 1)) == LABEL_REF) \ - { \ - output_addr_const (FILE, XEXP (addr, 0)); \ - fputs ("-(", FILE); \ - output_addr_const (FILE, XEXP (addr, 1)); \ - fputs ("-.)", FILE); \ - } \ - else if (GET_CODE (addr) == LO_SUM) \ - { \ - output_operand (XEXP (addr, 0), 0); \ - fputs ("+%lo(", FILE); \ - output_address (XEXP (addr, 1)); \ - fputc (')', FILE); \ - } \ - else if (flag_pic && GET_CODE (addr) == CONST \ - && GET_CODE (XEXP (addr, 0)) == MINUS \ - && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST \ - && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS \ - && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx) \ - { \ - addr = XEXP (addr, 0); \ - output_addr_const (FILE, XEXP (addr, 0)); \ - /* Group the args of the second CONST in parenthesis. */ \ - fputs ("-(", FILE); \ - /* Skip past the second CONST--it does nothing for us. */\ - output_addr_const (FILE, XEXP (XEXP (addr, 1), 0)); \ - /* Close the parenthesis. */ \ - fputc (')', FILE); \ - } \ - else \ - { \ - output_addr_const (FILE, addr); \ - } \ -} - -/* Declare functions defined in sparc.c and used in templates. */ - -extern char *singlemove_string (); -extern char *output_move_double (); -extern char *output_move_quad (); -extern char *output_fp_move_double (); -extern char *output_fp_move_quad (); -extern char *output_block_move (); -extern char *output_scc_insn (); -extern char *output_cbranch (); -extern char *output_return (); - -/* Defined in flags.h, but insn-emit.c does not include flags.h. */ - -extern int flag_pic; diff --git a/gnu/usr.bin/gcc2/arch/sparc/tconfig.h b/gnu/usr.bin/gcc2/arch/sparc/tconfig.h deleted file mode 100644 index 5056c6add9e..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/tconfig.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Configuration for GNU C-compiler for Sun Sparc. - Copyright (C) 1988 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com). - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* #defines that need visibility everywhere. */ -#define FALSE 0 -#define TRUE 1 - -/* This describes the machine the compiler is hosted on. */ -#define HOST_BITS_PER_CHAR 8 -#define HOST_BITS_PER_SHORT 16 -#define HOST_BITS_PER_INT 32 -#define HOST_BITS_PER_LONG 32 -#define HOST_BITS_PER_LONGLONG 64 - -/* Doubles are stored in memory with the high order word first. This - matters when cross-compiling. */ -#define HOST_WORDS_BIG_ENDIAN 1 - -/* target machine dependencies. - tm.h is a symbolic link to the actual target specific file. */ -#include "tm.h" - -/* Arguments to use with `exit'. */ -#define SUCCESS_EXIT_CODE 0 -#define FATAL_EXIT_CODE 33 - -/* If compiled with Sun CC, the use of alloca requires this #include. */ -#ifndef __GNUC__ -#include "alloca.h" -#endif - -/* If compiled with GNU C, use the built-in alloca. */ -#ifdef __GNUC__ -/* Use an arg in this macro because that's what some other - system does--let's avoid conflict. */ -#define alloca(x) __builtin_alloca(x) -#endif diff --git a/gnu/usr.bin/gcc2/arch/sparc/tm.h b/gnu/usr.bin/gcc2/arch/sparc/tm.h deleted file mode 100644 index 5e476691846..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/tm.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Configuration for NetBSD Sparc */ -/* $Id: tm.h,v 1.1.1.1 1995/10/18 08:39:26 deraadt Exp $ */ - -#include "sparc/sparc.h" - -#undef LIB_SPEC -#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" - -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Dsparc -Dunix -D__NetBSD__ -D__sparc__ -D__GCC_NEW_VARARGS__" -/* Provide required defaults for linker -e and -d switches. */ - -#define LINK_SPEC \ - "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}" - -#define STARTFILE_SPEC \ - "%{pg:gcrt0.o%s}\ - %{!pg:%{p:mcrt0.o%s}\ - %{!p:%{static:scrt0.o%s}%{!static:crt0.o%s}}}" - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#define HAVE_ATEXIT - -/* - * Some imports from svr4.h in support of shared libraries. - */ - -#define HANDLE_SYSV_PRAGMA - -/* Define the strings used for the special svr4 .type and .size directives. - These strings generally do not vary from one system running svr4 to - another, but if a given system (e.g. m88k running svr) needs to use - different pseudo-op names for these, they may be overridden in the - file which includes this one. */ - -#define TYPE_ASM_OP ".type" -#define SIZE_ASM_OP ".size" -#define WEAK_ASM_OP ".weak" -#define SET_ASM_OP ".set" - -/* The following macro defines the format used to output the second - operand of the .type assembler directive. Different svr4 assemblers - expect various different forms for this operand. The one given here - is just a default. You may need to override it in your machine- - specific tm.h file (depending upon the particulars of your assembler). */ - -#define TYPE_OPERAND_FMT "@%s" - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ - putc ('\n', FILE); \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* Write the extra assembler code needed to declare an object properly. */ - -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ - assemble_name (FILE, NAME); \ - putc (',', FILE); \ - fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ - putc ('\n', FILE); \ - if (!flag_inhibit_size_directive) \ - { \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, NAME); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ - } while (0) - -/* This is how to declare the size of a function. */ - -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do { \ - if (!flag_inhibit_size_directive) \ - { \ - char label[256]; \ - static int labelno; \ - labelno++; \ - ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ - ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, (FNAME)); \ - fprintf (FILE, ","); \ - assemble_name (FILE, label); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, (FNAME)); \ - putc ('\n', FILE); \ - } \ - } while (0) - diff --git a/gnu/usr.bin/gcc2/arch/sparc/va-sparc.h b/gnu/usr.bin/gcc2/arch/sparc/va-sparc.h deleted file mode 100644 index 980ecd67ebe..00000000000 --- a/gnu/usr.bin/gcc2/arch/sparc/va-sparc.h +++ /dev/null @@ -1,85 +0,0 @@ -/* This is just like the default gvarargs.h - except for differences described below. */ - -/* Define __gnuc_va_list. */ - -#ifndef __GNUC_VA_LIST -#define __GNUC_VA_LIST - -#ifndef __svr4__ -/* This has to be a char * to be compatible with Sun. - i.e., we have to pass a `va_list' to vsprintf. */ -typedef char * __gnuc_va_list; -#else -/* This has to be a void * to be compatible with Sun svr4. - i.e., we have to pass a `va_list' to vsprintf. */ -typedef void * __gnuc_va_list; -#endif -#endif /* not __GNUC_VA_LIST */ - -/* If this is for internal libc use, don't define anything but - __gnuc_va_list. */ -#if defined (_STDARG_H) || defined (_VARARGS_H) - -#ifdef _STDARG_H - -#ifdef __GCC_NEW_VARARGS__ -#define va_start(AP, LASTARG) (AP = (char *) __builtin_saveregs ()) -#else -#define va_start(AP, LASTARG) \ - (__builtin_saveregs (), AP = ((char *) __builtin_next_arg ())) -#endif - -#else - -#define va_alist __builtin_va_alist -#define va_dcl int __builtin_va_alist; - -#ifdef __GCC_NEW_VARARGS__ -#define va_start(AP) ((AP) = (char *) __builtin_saveregs ()) -#else -#define va_start(AP) \ - (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist)) -#endif - -#endif - -#ifndef va_end -void va_end (__gnuc_va_list); /* Defined in libgcc.a */ -#endif -#define va_end(pvar) - -#define __va_rounded_size(TYPE) \ - (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) - -/* Avoid errors if compiling GCC v2 with GCC v1. */ -#if __GNUC__ == 1 -#define __extension__ -#endif - -/* RECORD_TYPE args passed using the C calling convention are - passed by invisible reference. ??? RECORD_TYPE args passed - in the stack are made to be word-aligned; for an aggregate that is - not word-aligned, we advance the pointer to the first non-reg slot. */ -/* We don't declare the union member `d' to have type TYPE - because that would lose in C++ if TYPE has a constructor. */ -/* We cast to void * and then to TYPE * because this avoids - a warning about increasing the alignment requirement. - The casts to char * avoid warnings about invalid pointer arithmetic. */ -#define va_arg(pvar,TYPE) \ -__extension__ \ -({ TYPE __va_temp; \ - ((__builtin_classify_type (__va_temp) >= 12) \ - ? ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE *), \ - **(TYPE **) (void *) ((char *)(pvar) - __va_rounded_size (TYPE *))) \ - : __va_rounded_size (TYPE) == 8 \ - ? ({ union {char __d[sizeof (TYPE)]; int __i[2];} __u; \ - __u.__i[0] = ((int *) (void *) (pvar))[0]; \ - __u.__i[1] = ((int *) (void *) (pvar))[1]; \ - (pvar) = (char *)(pvar) + 8; \ - *(TYPE *) (void *) __u.__d; }) \ - : ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE), \ - *((TYPE *) (void *) ((char *)(pvar) - __va_rounded_size (TYPE)))));}) - -#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ - diff --git a/gnu/usr.bin/gcc2/cc/Makefile b/gnu/usr.bin/gcc2/cc/Makefile deleted file mode 100644 index 4ad858c9a09..00000000000 --- a/gnu/usr.bin/gcc2/cc/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# from: @(#)Makefile 6.2 (Berkeley) 3/25/91 -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:26 deraadt Exp $ - -PROG= cc -SRCS= gcc.c version.c obstack.c -MAN= gcc.1 g++.1 -BINDIR= /usr/bin -CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../common \ - -I$(.CURDIR)/../arch -I$(.CURDIR)/../arch/$(MACHINE_ARCH) -LDADD+= -lgnumalloc -DPADD+= /usr/lib/libgnumalloc.a - -LINKS+= ${BINDIR}/cc ${BINDIR}/gcc -MLINKS= gcc.1 cc.1 g++.1 c++.1 - -.PATH: $(.CURDIR)/../common - -afterinstall: - install -c -o $(BINOWN) -g $(BINGRP) -m $(BINMODE) \ - $(.CURDIR)/g++.script $(DESTDIR)$(BINDIR)/g++ - @/bin/rm -rf ${DESTDIR}${BINDIR}/c++ - @ln ${DESTDIR}${BINDIR}/g++ ${DESTDIR}${BINDIR}/c++ - @echo ${DESTDIR}${BINDIR}/g++ -\> ${DESTDIR}${BINDIR}/c++ -.include diff --git a/gnu/usr.bin/gcc2/cc/g++.1 b/gnu/usr.bin/gcc2/cc/g++.1 deleted file mode 100644 index 22a16556da6..00000000000 --- a/gnu/usr.bin/gcc2/cc/g++.1 +++ /dev/null @@ -1,638 +0,0 @@ -.\" Copyright (c) 1991, 1992 Free Software Foundation -*- nroff -*- -.\" See section COPYING for conditions for redistribution -.\" -.\" $Id: g++.1,v 1.1.1.1 1995/10/18 08:39:26 deraadt Exp $ -.\" -.\" FIXME: no info here on predefines. Should there be? extra for C++... -.TH G++ 1 "30apr1993" "GNU Tools" "GNU Tools" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -g++ \- GNU project C++ Compiler (v2.4) -.SH SYNOPSIS -.RB g++ " [" \c -.IR option " | " filename " ].\|.\|. -.SH DESCRIPTION -The C and C++ compilers are integrated; -.B g++ -is a script to call -.B gcc with options to recognize C++. -.B gcc -processes input files -through one or more of four stages: preprocessing, compilation, -assembly, and linking. This man page contains full descriptions for -.I only -C++ specific aspects of the compiler, though it also contains -summaries of some general-purpose options. For a fuller explanation -of the compiler, see -.BR gcc ( 1 ). - -C++ source files use one of the suffixes `\|\c -.B .C\c -\&\|', `\|\c -.B .cc\c -\&\|', or `\|\c -.B .cxx\c -\&\|'; preprocessed C++ files use the suffix `\|\c -.B .ii\c -\&\|'. -.SH OPTIONS -There are many command-line options, including options to control -details of optimization, warnings, and code generation, which are -common to both -.B gcc -and -.B g++\c -\&. For full information on all options, see -.BR gcc ( 1 ). - -Options must be separate: `\|\c -.B \-dr\c -\&\|' is quite different from `\|\c -.B \-d \-r -\&\|'. - -Most `\|\c -.B \-f\c -\&\|' and `\|\c -.B \-W\c -\&\|' options have two contrary forms: -.BI \-f name -and -.BI \-fno\- name\c -\& (or -.BI \-W name -and -.BI \-Wno\- name\c -\&). Only the non-default forms are shown here. - -.TP -.B \-c -Compile or assemble the source files, but do not link. The compiler -output is an object file corresponding to each source file. -.TP -.BI \-D macro -Define macro \c -.I macro\c -\& with the string `\|\c -.B 1\c -\&\|' as its definition. -.TP -.BI \-D macro = defn -Define macro \c -.I macro\c -\& as \c -.I defn\c -\&. -.TP -.B \-E -Stop after the preprocessing stage; do not run the compiler proper. The -output is preprocessed source code, which is sent to the -standard output. -.TP -.B \-fall\-virtual -Treat all possible member functions as virtual, implicitly. All -member functions (except for constructor functions and -.B new -or -.B delete -member operators) are treated as virtual functions of the class where -they appear. - -This does not mean that all calls to these member functions will be -made through the internal table of virtual functions. Under some -circumstances, the compiler can determine that a call to a given -virtual function can be made directly; in these cases the calls are -direct in any case. -.TP -.B \-fdollars\-in\-identifiers -Permit the use of `\|\c -.B $\c -\&\|' in identifiers. -Traditional C allowed the character `\|\c -.B $\c -\&\|' to form part of identifiers; by default, GNU C also -allows this. However, ANSI C forbids `\|\c -.B $\c -\&\|' in identifiers, and GNU C++ also forbids it by default on most -platforms (though on some platforms it's enabled by default for GNU -C++ as well). -.TP -.B \-felide\-constructors -Use this option to instruct the compiler to be smarter about when it can -elide constructors. Without this flag, GNU C++ and cfront both -generate effectively the same code for: -.sp -.br -A\ foo\ (); -.br -A\ x\ (foo\ ());\ \ \ //\ x\ initialized\ by\ `foo\ ()',\ no\ ctor\ called -.br -A\ y\ =\ foo\ ();\ \ \ //\ call\ to\ `foo\ ()'\ heads\ to\ temporary, -.br -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ y\ is\ initialized\ from\ the\ temporary. -.br -.sp -Note the difference! With this flag, GNU C++ initializes `\|\c -.B y\c -\&\|' directly -from the call to -.B foo () -without going through a temporary. -.TP -.B \-fenum\-int\-equiv -Normally GNU C++ allows conversion of -.B enum -to -.B int\c -\&, but not the other way around. Use this option if you want GNU C++ -to allow conversion of -.B int -to -.B enum -as well. -.TP -.B \-fno\-gnu\-linker -Do not output global initializations (such as C++ constructors and -destructors) in the form used by the GNU linker (on systems where the GNU -linker is the standard method of handling them). Use this option when -you want to use a non-GNU linker, which also requires using the -.B collect2 -program to make sure the system linker includes -constructors and destructors. (\c -.B collect2 -is included in the GNU CC distribution.) For systems which -.I must -use -.B collect2\c -\&, the compiler driver -.B gcc -is configured to do this automatically. -.TP -.B \-fmemoize\-lookups -.TP -.B \-fsave\-memoized -These flags are used to get the compiler to compile programs faster -using heuristics. They are not on by default since they are only effective -about half the time. The other half of the time programs compile more -slowly (and take more memory). - -The first time the compiler must build a call to a member function (or -reference to a data member), it must (1) determine whether the class -implements member functions of that name; (2) resolve which member -function to call (which involves figuring out what sorts of type -conversions need to be made); and (3) check the visibility of the member -function to the caller. All of this adds up to slower compilation. -Normally, the second time a call is made to that member function (or -reference to that data member), it must go through the same lengthy -process again. This means that code like this -.sp -.br -\ \ cout\ <<\ "This\ "\ <<\ p\ <<\ "\ has\ "\ <<\ n\ <<\ "\ legs.\en"; -.br -.sp -makes six passes through all three steps. By using a software cache, -a ``hit'' significantly reduces this cost. Unfortunately, using the -cache introduces another layer of mechanisms which must be implemented, -and so incurs its own overhead. `\|\c -.B \-fmemoize\-lookups\c -\&\|' enables -the software cache. - -Because access privileges (visibility) to members and member functions -may differ from one function context to the next, -.B g++ -may need to flush the cache. With the `\|\c -.B \-fmemoize\-lookups\c -\&\|' flag, the cache is flushed after every -function that is compiled. The `\|\c -\-fsave\-memoized\c -\&\|' flag enables the same software cache, but when the compiler -determines that the context of the last function compiled would yield -the same access privileges of the next function to compile, it -preserves the cache. -This is most helpful when defining many member functions for the same -class: with the exception of member functions which are friends of -other classes, each member function has exactly the same access -privileges as every other, and the cache need not be flushed. -.TP -.B \-fno\-default\-inline -Do not make member functions inline by default merely because they are -defined inside the class scope. Otherwise, when you specify -.B \-O\c -\&, member functions defined inside class scope are compiled -inline by default; i.e., you don't need to add `\|\c -.B inline\c -\&\|' in front of -the member function name. -.TP -.B \-fno\-strict\-prototype -Consider the declaration \c -.B int foo ();\c -\&. In C++, this means that the -function \c -.B foo\c -\& takes no arguments. In ANSI C, this is declared -.B int foo(void);\c -\&. With the flag `\|\c -.B \-fno\-strict\-prototype\c -\&\|', -declaring functions with no arguments is equivalent to declaring its -argument list to be untyped, i.e., \c -.B int foo ();\c -\& is equivalent to -saying \c -.B int foo (...);\c -\&. -.TP -.B \-fnonnull\-objects -Normally, GNU C++ makes conservative assumptions about objects reached -through references. For example, the compiler must check that `\|\c -.B a\c -\&\|' is not null in code like the following: -.br -\ \ \ \ obj\ &a\ =\ g\ (); -.br -\ \ \ \ a.f\ (2); -.br -Checking that references of this sort have non-null values requires -extra code, however, and it is unnecessary for many programs. You can -use `\|\c -.B \-fnonnull\-objects\c -\&\|' to omit the checks for null, if your program doesn't require the -default checking. -.TP -.B \-fthis\-is\-variable -The incorporation of user-defined free store management into C++ has -made assignment to \c -.B this\c -\& an anachronism. Therefore, by default GNU -C++ treats the type of \c -.B this\c -\& in a member function of \c -.B class X\c -\& -to be \c -.B X *const\c -\&. In other words, it is illegal to assign to -\c -.B this\c -\& within a class member function. However, for backwards -compatibility, you can invoke the old behavior by using -\&`\|\c -.B \-fthis\-is\-variable\c -\&\|'. -.TP -.B \-g -Produce debugging information in the operating system's native format -(for DBX or SDB or DWARF). GDB also can work with this debugging -information. On most systems that use DBX format, `\|\c -.B \-g\c -\&\|' enables use -of extra debugging information that only GDB can use. - -Unlike most other C compilers, GNU CC allows you to use `\|\c -.B \-g\c -\&\|' with -`\|\c -.B \-O\c -\&\|'. The shortcuts taken by optimized code may occasionally -produce surprising results: some variables you declared may not exist -at all; flow of control may briefly move where you did not expect it; -some statements may not be executed because they compute constant -results or their values were already at hand; some statements may -execute in different places because they were moved out of loops. - -Nevertheless it proves possible to debug optimized output. This makes -it reasonable to use the optimizer for programs that might have bugs. -.TP -.BI "\-I" "dir"\c -\& -Append directory \c -.I dir\c -\& to the list of directories searched for include files. -.TP -.BI "\-L" "dir"\c -\& -Add directory \c -.I dir\c -\& to the list of directories to be searched -for `\|\c -.B \-l\c -\&\|'. -.TP -.BI \-l library\c -\& -Use the library named \c -.I library\c -\& when linking. (C++ programs often require `\|\c -\-lg++\c -\&\|' for successful linking.) -.TP -.B \-nostdinc -Do not search the standard system directories for header files. Only -the directories you have specified with -.B \-I -options (and the current directory, if appropriate) are searched. -.TP -.B \-nostdinc++ -Do not search for header files in the standard directories specific to -C++, but do still search the other standard directories. (This option -is used when building libg++.) -.TP -.B \-O -Optimize. Optimizing compilation takes somewhat more time, and a lot -more memory for a large function. -.TP -.BI "\-o " file\c -\& -Place output in file \c -.I file\c -\&. -.TP -.B \-S -Stop after the stage of compilation proper; do not assemble. The output -is an assembler code file for each non-assembler input -file specified. -.TP -.B \-traditional -Attempt to support some aspects of traditional C compilers. - -Specifically, for both C and C++ programs: -.TP -\ \ \ \(bu -In the preprocessor, comments convert to nothing at all, rather than -to a space. This allows traditional token concatenation. -.TP -\ \ \ \(bu -In the preprocessor, macro arguments are recognized within string -constants in a macro definition (and their values are stringified, -though without additional quote marks, when they appear in such a -context). The preprocessor always considers a string constant to end -at a newline. -.TP -\ \ \ \(bu -The preprocessor does not predefine the macro \c -.B __STDC__\c -\& when you use -`\|\c -.B \-traditional\c -\&\|', but still predefines\c -.B __GNUC__\c -\& (since the GNU extensions indicated by -.B __GNUC__\c -\& are not affected by -`\|\c -.B \-traditional\c -\&\|'). If you need to write header files that work -differently depending on whether `\|\c -.B \-traditional\c -\&\|' is in use, by -testing both of these predefined macros you can distinguish four -situations: GNU C, traditional GNU C, other ANSI C compilers, and -other old C compilers. -.TP -\ \ \ \(bu -In the preprocessor, comments convert to nothing at all, rather than -to a space. This allows traditional token concatenation. -.TP -\ \ \ \(bu -In the preprocessor, macro arguments are recognized within string -constants in a macro definition (and their values are stringified, -though without additional quote marks, when they appear in such a -context). The preprocessor always considers a string constant to end -at a newline. -.TP -\ \ \ \(bu -The preprocessor does not predefine the macro \c -.B __STDC__\c -\& when you use -`\|\c -.B \-traditional\c -\&\|', but still predefines\c -.B __GNUC__\c -\& (since the GNU extensions indicated by -.B __GNUC__\c -\& are not affected by -`\|\c -.B \-traditional\c -\&\|'). If you need to write header files that work -differently depending on whether `\|\c -.B \-traditional\c -\&\|' is in use, by -testing both of these predefined macros you can distinguish four -situations: GNU C, traditional GNU C, other ANSI C compilers, and -other old C compilers. -.PP -.TP -\ \ \ \(bu -String ``constants'' are not necessarily constant; they are stored in -writable space, and identical looking constants are allocated -separately. - -For C++ programs only (not C), `\|\c -.B \-traditional\c -\&\|' has one additional effect: assignment to -.B this -is permitted. This is the same as the effect of `\|\c -.B \-fthis\-is\-variable\c -\&\|'. -.TP -.BI \-U macro -Undefine macro \c -.I macro\c -\&. -.TP -.B \-Wall -Issue warnings for conditions which pertain to usage that we recommend -avoiding and that we believe is easy to avoid, even in conjunction -with macros. -.TP -.B \-Wenum\-clash -Warn when converting between different enumeration types. -.TP -.B \-Woverloaded\-virtual -In a derived class, the definitions of virtual functions must match -the type signature of a virtual function declared in the base class. -Use this option to request warnings when a derived class declares a -function that may be an erroneous attempt to define a virtual -function: that is, warn when a function with the same name as a -virtual function in the base class, but with a type signature that -doesn't match any virtual functions from the base class. -.TP -.B \-Wtemplate\-debugging -When using templates in a C++ program, warn if debugging is not yet -fully available. -.TP -.B \-w -Inhibit all warning messages. -.TP -.BI +e N -Control how virtual function definitions are used, in a fashion -compatible with -.B cfront -1.x. -.PP - -.SH PRAGMAS -Two `\|\c -.B #pragma\c -\&\|' directives are supported for GNU C++, to permit using the same -header file for two purposes: as a definition of interfaces to a given -object class, and as the full definition of the contents of that object class. -.TP -.B #pragma interface -Use this directive in header files that define object classes, to save -space in most of the object files that use those classes. Normally, -local copies of certain information (backup copies of inline member -functions, debugging information, and the internal tables that -implement virtual functions) must be kept in each object file that -includes class definitions. You can use this pragma to avoid such -duplication. When a header file containing `\|\c -.B #pragma interface\c -\&\|' is included in a compilation, this auxiliary information -will not be generated (unless the main input source file itself uses -`\|\c -.B #pragma implementation\c -\&\|'). Instead, the object files will contain references to be -resolved at link time. -.tr !" -.TP -.B #pragma implementation -.TP -.BI "#pragma implementation !" objects .h! -Use this pragma in a main input file, when you want full output from -included header files to be generated (and made globally visible). -The included header file, in turn, should use `\|\c -.B #pragma interface\c -\&\|'. -Backup copies of inline member functions, debugging information, and -the internal tables used to implement virtual functions are all -generated in implementation files. - -If you use `\|\c -.B #pragma implementation\c -\&\|' with no argument, it applies to an include file with the same -basename as your source file; for example, in `\|\c -.B allclass.cc\c -\&\|', `\|\c -.B #pragma implementation\c -\&\|' by itself is equivalent to `\|\c -.B -#pragma implementation "allclass.h"\c -\&\|'. Use the string argument if you want a single implementation -file to include code from multiple header files. - -There is no way to split up the contents of a single header file into -multiple implementation files. -.SH FILES -.ta \w'LIBDIR/g++\-include 'u -file.h C header (preprocessor) file -.br -file.i preprocessed C source file -.br -file.C C++ source file -.br -file.cc C++ source file -.br -file.cxx C++ source file -.br -file.s assembly language file -.br -file.o object file -.br -a.out link edited output -.br -\fITMPDIR\fR/cc\(** temporary files -.br -\fILIBDIR\fR/cpp preprocessor -.br -\fILIBDIR\fR/cc1plus compiler -.br -\fILIBDIR\fR/collect linker front end needed on some machines -.br -\fILIBDIR\fR/libgcc.a GCC subroutine library -.br -/lib/crt[01n].o start-up routine -.br -\fILIBDIR\fR/ccrt0 additional start-up routine for C++ -.br -/lib/libc.a standard C library, see -.IR intro (3) -.br -/usr/include standard directory for -.B #include -files -.br -\fILIBDIR\fR/include standard gcc directory for -.B #include -files -.br -\fILIBDIR\fR/g++\-include additional g++ directory for -.B #include -.sp -.I LIBDIR -is usually -.B /usr/local/lib/\c -.IR machine / version . -.br -.I TMPDIR -comes from the environment variable -.B TMPDIR -(default -.B /usr/tmp -if available, else -.B /tmp\c -\&). -.SH "SEE ALSO" -gcc(1), cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). -.br -.RB "`\|" gcc "\|', `\|" cpp \|', -.RB `\| as \|', `\| ld \|', -and -.RB `\| gdb \|' -entries in -.B info\c -\&. -.br -.I -Using and Porting GNU CC (for version 2.0)\c -, Richard M. Stallman; -.I -The C Preprocessor\c -, Richard M. Stallman; -.I -Debugging with GDB: the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch; -.I -Using as: the GNU Assembler\c -, Dean Elsner, Jay Fenlason & friends; -.I -gld: the GNU linker\c -, Steve Chamberlain and Roland Pesch. - -.SH BUGS -For instructions on how to report bugs, see the GCC manual. - -.SH COPYING -Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc. -.PP -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. -.SH AUTHORS -See the GNU CC Manual for the contributors to GNU CC. diff --git a/gnu/usr.bin/gcc2/cc/g++.script b/gnu/usr.bin/gcc2/cc/g++.script deleted file mode 100644 index d633e1c459a..00000000000 --- a/gnu/usr.bin/gcc2/cc/g++.script +++ /dev/null @@ -1,111 +0,0 @@ -#!/bin/sh -# Compile programs, treating .c files as C++. -: || exec /bin/sh -f $0 $argv:q - -# The compiler name might be different when doing cross-compilation -# (this should be configured) -gcc_name=gcc -speclang=-xnone - -# replace the command name by the name of the new command -progname=`basename $0` -case "$0" in - */*) - gcc=`echo $0 | sed -e "s;/[^/]*$;;"`/$gcc_name - ;; - *) - gcc=$gcc_name - ;; -esac - -# $first is yes for first arg, no afterwards. -first=yes -# If next arg is the argument of an option, $quote is non-empty. -# More precisely, it is the option that wants an argument. -quote= -# $library is made empty to disable use of libg++. -library=-lg++ -numargs=$# - -# ash requires the newline before `do'. -for arg -do - if [ $first = yes ] - then - # Need some 1st arg to `set' which does not begin with `-'. - # We get rid of it after the loop ends. - set gcc - first=no - fi - # If you have to ask what this does, you should not edit this file. :-) - # The ``S'' at the start is so that echo -nostdinc does not eat the - # -nostdinc. - arg=`echo "S$arg" | sed "s/^S//; s/'/'\\\\\\\\''/g"` - if [ x$quote != x ] - then - quote= - else - quote= - case $arg in - -nostdlib) - # Inhibit linking with -lg++. - library= - ;; - -lm | -lmath) - # Because libg++ uses things from the math library, make sure it - # always comes before the math library. We recognize both -lm - # and -lmath, since on some systems (e.g. m88k SVR3), it - # doesn't call it libm.a for some reason. - set "$@" $library - library="" - ;; - -[bBVDUoeTuIYmLiA] | -Tdata) - # these switches take following word as argument, - # so don't treat it as a file name. - quote=$arg - ;; - -[cSEM] | -MM) - # Don't specify libraries if we won't link, - # since that would cause a warning. - library= - ;; - -x*) - speclang=$arg - ;; - -v) - # catch `g++ -v' - if [ $numargs = 1 ] ; then library="" ; fi - ;; - -*) - # Pass other options through; they don't need -x and aren't inputs. - ;; - *) - # If file ends in .c or .i, put options around it. - # But not if a specified -x option is currently active. - case "$speclang $arg" in -xnone\ *.[ci]) - set "$@" -xc++ "'$arg'" -xnone - continue - esac - ;; - esac - fi - set "$@" "'$arg'" -done - -# Get rid of that initial 1st arg -if [ $first = no ]; then - shift -else - echo "$0: No input files specified." - exit 1 -fi - -if [ x$quote != x ] -then - echo "$0: argument to \`$quote' missing" - exit 1 -fi - -eval $gcc "$@" $library - - diff --git a/gnu/usr.bin/gcc2/cc/gcc.1 b/gnu/usr.bin/gcc2/cc/gcc.1 deleted file mode 100644 index fd73e50fc74..00000000000 --- a/gnu/usr.bin/gcc2/cc/gcc.1 +++ /dev/null @@ -1,4225 +0,0 @@ -.\" Copyright (c) 1991, 1992, 1993 Free Software Foundation -*- nroff -*- -.\" See section COPYING for conditions for redistribution -.\" -.\" $Id: gcc.1,v 1.1.1.1 1995/10/18 08:39:26 deraadt Exp $ -.\" -.TH GCC 1 "30apr1993" "GNU Tools" "GNU Tools" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -gcc, g++ \- GNU project C and C++ Compiler (v2.4) -.SH SYNOPSIS -.RB gcc " [" \c -.IR option " | " filename " ].\|.\|. -.br -.RB g++ " [" \c -.IR option " | " filename " ].\|.\|. -.SH WARNING -The information in this man page is an extract from the full -documentation of the GNU C compiler, and is limited to the meaning of -the options. This man page is not kept up to date except when -volunteers want to maintain it. - -For complete and current documentation, refer to the Info file `\|\c -.B gcc\c -\&\|' or the manual -.I -Using and Porting GNU CC (for version 2.0)\c -\&. Both are made from the Texinfo source file -.BR gcc.texinfo . -.SH DESCRIPTION -The C and C++ compilers are integrated. Both process input files -through one or more of four stages: preprocessing, compilation, -assembly, and linking. Source filename suffixes identify the source -language, but which name you use for the compiler governs default -assumptions: -.TP -.B gcc -assumes preprocessed (\c -.B .i\c -\&) files are C and assumes C style linking. -.TP -.B g++ -assumes preprocessed (\c -.B .i\c -\&) files are C++ and assumes C++ style linking. -.PP -Suffixes of source file names indicate the language and kind of -processing to be done: - -.ta \w'.cxx 'u -.B .c\c -\& C source; preprocess, compile, assemble -.br -.B .C\c -\& C++ source; preprocess, compile, assemble -.br -.B .cc\c -\& C++ source; preprocess, compile, assemble -.br -.B .cxx\c -\& C++ source; preprocess, compile, assemble -.br -.B .m\c -\& Objective-C source; preprocess, compile, assemble -.br -.B .i\c -\& preprocessed C; compile, assemble -.br -.B .ii\c -\& preprocessed C++; compile, assemble -.br -.B .s\c -\& Assembler source; assemble -.br -.B .S\c -\& Assembler source; preprocess, assemble -.br -.B .h\c -\& Preprocessor file; not usually named on command line - -.I ??\c -\& Other (unrecognized) files passed to linker. -.br -\& Common cases: -.br -.B .o\c -\& Object file -.br -.B .a\c -\& Archive file - -Linking is always the last stage unless you use one of the -.BR \-c , -.BR \-S , -or -.B \-E -options to avoid it (or unless compilation errors stop the whole -process). For the link stage, all -.B .o -files corresponding to source files, -.B \-l -libraries, unrecognized filenames (including named -.B .o -object files and -.B .a -archives) -are passed to the linker in command-line order. - -.SH OPTIONS -Options must be separate: `\|\c -.B \-dr\c -\&\|' is quite different from `\|\c -.B \-d \-r -\&\|'. - -Most `\|\c -.B \-f\c -\&\|' and `\|\c -.B \-W\c -\&\|' options have two contrary forms: -.BI \-f name -and -.BI \-fno\- name\c -\& (or -.BI \-W name -and -.BI \-Wno\- name\c -\&). Only the non-default forms are shown here. - -Here is a summary of all the options, grouped by type. Explanations are -in the following sections. - -.hy 0 -.na -.TP -.B Overall Options -.br -\-c -\-S -\-E -.RI "\-o " file -\-pipe -\-v -.RI "\-x " language - -.TP -.B Language Options -\-ansi -\-fall\-virtual -\-fcond\-mismatch -\-fdollars\-in\-identifiers -\-fenum\-int\-equiv -\-fno\-asm -\-fno\-builtin -\-fno\-strict\-prototype -\-fsigned\-bitfields -\-fsigned\-char -\-fthis\-is\-variable -\-funsigned\-bitfields -\-funsigned\-char -\-fwritable\-strings -\-traditional -\-traditional\-cpp -\-trigraphs - -.TP -.B Warning Options -\-fsyntax\-only -\-pedantic -\-pedantic\-errors -\-w -\-W -\-Wall -\-Waggregate\-return -\-Wcast\-align -\-Wcast\-qual -\-Wchar\-subscript -\-Wcomment -\-Wconversion -\-Wenum\-clash -\-Werror -\-Wformat -.RI \-Wid\-clash\- len -\-Wimplicit -\-Winline -\-Wmissing\-prototypes -\-Wnested\-externs -\-Wno\-import -\-Wparentheses -\-Wpointer\-arith -\-Wredundant\-decls -\-Wreturn\-type -\-Wshadow -\-Wstrict\-prototypes -\-Wswitch -\-Wtemplate\-debugging -\-Wtraditional -\-Wtrigraphs -\-Wuninitialized -\-Wunused -\-Wwrite\-strings - -.TP -.B Debugging Options -\-a -.RI \-d letters -\-fpretend\-float -\-g -.RI \-g level -\-gcoff -\-gxcoff -\-gxcoff+ -\-gdwarf -\-gdwarf+ -\-gstabs -\-gstabs+ -\-ggdb -\-p -\-pg -\-save\-temps -\-print\-libgcc\-file\-name - -.TP -.B Optimization Options -\-fcaller\-saves -\-fcse\-follow\-jumps -\-fcse\-skip\-blocks -\-fdelayed\-branch -\-felide\-constructors -\-fexpensive\-optimizations -\-ffast-\math -\-ffloat\-store -\-fforce\-addr -\-fforce\-mem -\-finline\-functions -\-fkeep\-inline\-functions -\-fmemoize\-lookups -\-fno\-default\-inline -\-fno\-defer\-pop -\-fno\-function\-cse -\-fno\-inline -\-fno\-peephole -\-fomit\-frame\-pointer -\-frerun\-cse\-after\-loop -\-fschedule\-insns -\-fschedule\-insns2 -\-fstrength\-reduce -\-fthread\-jumps -\-funroll\-all\-loops -\-funroll\-loops -\-O -\-O2 - -.TP -.B Preprocessor Options -.RI \-A assertion -\-C -\-dD -\-dM -\-dN -.RI \-D macro [\|= defn \|] -\-E -\-H -.RI "\-idirafter " dir -.RI "\-include " file -.RI "\-imacros " file -.RI "\-iprefix " file -.RI "\-iwithprefix " dir -\-M -\-MD -\-MM -\-MMD -\-nostdinc -\-P -.RI \-U macro -\-undef - -.TP -.B Assembler Option -.RI \-Wa, option - -.TP -.B Linker Options -.RI \-l library -\-nostartfiles -\-nostdlib -\-static -\-shared -\-symbolic -.RI "\-Xlinker\ " option -.RI \-Wl, option -.RI "\-u " symbol - -.TP -.B Directory Options -.RI \-B prefix -.RI \-I dir -\-I\- -.RI \-L dir - -.TP -.B Target Options -.RI "\-b " machine -.RI "\-V " version - -.TP -.B Configuration Dependent Options -.I M680x0\ Options -.br -\-m68000 -\-m68020 -\-m68020\-40 -\-m68030 -\-m68040 -\-m68881 -\-mbitfield -\-mc68000 -\-mc68020 -\-mfpa -\-mnobitfield -\-mrtd -\-mshort -\-msoft\-float - -.I VAX Options -.br -\-mg -\-mgnu -\-munix - -.I SPARC Options -.br -\-mepilogue -\-mfpu -\-mhard\-float -\-mno\-fpu -\-mno\-epilogue -\-msoft\-float -\-msparclite -\-mv8 - -.I Convex Options -.br -\-margcount -\-mc1 -\-mc2 -\-mnoargcount - -.I AMD29K Options -.br -\-m29000 -\-m29050 -\-mbw -\-mdw -\-mkernel\-registers -\-mlarge -\-mnbw -\-mnodw -\-msmall -\-mstack\-check -\-muser\-registers - -.I M88K Options -.br -\-m88000 -\-m88100 -\-m88110 -\-mbig\-pic -\-mcheck\-zero\-division -\-mhandle\-large\-shift -\-midentify\-revision -\-mno\-check\-zero\-division -\-mno\-ocs\-debug\-info -\-mno\-ocs\-frame\-position -\-mno\-optimize\-arg\-area -\-mno\-seriazlize\-volatile -\-mno\-underscores -\-mocs\-debug\-info -\-mocs\-frame\-position -\-moptimize\-arg\-area -\-mserialize\-volatile -.RI \-mshort\-data\- num -\-msvr3 -\-msvr4 -\-mtrap\-large\-shift -\-muse\-div\-instruction -\-mversion\-03.00 -\-mwarn\-passed\-structs - -.I RS6000 Options -.br -\-mfp\-in\-toc -\-mno\-fop\-in\-toc - -.I RT Options -.br -\-mcall\-lib\-mul -\-mfp\-arg\-in\-fpregs -\-mfp\-arg\-in\-gregs -\-mfull\-fp\-blocks -\-mhc\-struct\-return -\-min\-line\-mul -\-mminimum\-fp\-blocks -\-mnohc\-struct\-return - -.I MIPS Options -.br -\-mcpu=\fIcpu type\fP -\-mips2 -\-mips3 -\-mint64 -\-mlong64 -\-mlonglong128 -\-mmips\-as -\-mgas -\-mrnames -\-mno\-rnames -\-mgpopt -\-mno\-gpopt -\-mstats -\-mno\-stats -\-mmemcpy -\-mno\-memcpy -\-mno\-mips\-tfile -\-mmips\-tfile -\-msoft\-float -\-mhard\-float -\-mabicalls -\-mno\-abicalls -\-mhalf\-pic -\-mno\-half\-pic -\-G \fInum\fP -\-nocpp - -.I i386 Options -.br -\-m486 -\-mno\-486 -\-msoft\-float -\-mno\-fp\-ret\-in\-387 - -.I HPPA Options -.br -\-mpa\-risc\-1\-0 -\-mpa\-risc\-1\-1 -\-mkernel -\-mshared\-libs -\-mno\-shared\-libs -\-mlong\-calls -\-mdisable\-fpregs -\-mdisable\-indexing -\-mtrailing\-colon - -.I i960 Options -.br -\-m\fIcpu-type\fP -\-mnumerics -\-msoft\-float -\-mleaf\-procedures -\-mno\-leaf\-procedures -\-mtail\-call -\-mno\-tail\-call -\-mcomplex\-addr -\-mno\-complex\-addr -\-mcode\-align -\-mno\-code\-align -\-mic\-compat -\-mic2.0\-compat -\-mic3.0\-compat -\-masm\-compat -\-mintel\-asm -\-mstrict\-align -\-mno\-strict\-align -\-mold\-align -\-mno\-old\-align - -.I DEC Alpha Options -.br -\-mfp\-regs -\-mno\-fp\-regs -\-mno\-soft\-float -\-msoft\-float - -.I System V Options -.br -\-G -\-Qy -\-Qn -.RI \-YP, paths -.RI \-Ym, dir - -.TP -.B Code Generation Options -.RI \-fcall\-saved\- reg -.RI \-fcall\-used\- reg -.RI \-ffixed\- reg -\-finhibit\-size\-directive -\-fnonnull\-objects -\-fno\-common -\-fno\-ident -\-fno\-gnu\-linker -\-fpcc\-struct\-return -\-fpic -\-fPIC -\-freg\-struct\-returno -\-fshared\-data -\-fshort\-enums -\-fshort\-double -\-fvolatile -\-fvolatile\-global -\-fverbose\-asm -.ad b -.hy 1 - -.SH OVERALL OPTIONS -.TP -.BI "\-x " "language" -Specify explicitly the -.I language\c -\& for the following input files (rather than choosing a default based -on the file name suffix) . This option applies to all following input -files until the next `\|\c -.B \-x\c -\&\|' option. Possible values of \c -.I language\c -\& are -`\|\c -.B c\c -\&\|', `\|\c -.B objective\-c\c -\&\|', `\|\c -.B c\-header\c -\&\|', `\|\c -.B c++\c -\&\|', -`\|\c -.B cpp\-output\c -\&\|', `\|\c -.B assembler\c -\&\|', and `\|\c -.B assembler\-with\-cpp\c -\&\|'. -.TP -.B \-x none -Turn off any specification of a language, so that subsequent files are -handled according to their file name suffixes (as they are if `\|\c -.B \-x\c -\&\|' -has not been used at all). -.PP - -If you want only some of the four stages (preprocess, compile, -assemble, link), you can use -`\|\c -.B \-x\c -\&\|' (or filename suffixes) to tell \c -.B gcc\c -\& where to start, and -one of the options `\|\c -.B \-c\c -\&\|', `\|\c -.B \-S\c -\&\|', or `\|\c -.B \-E\c -\&\|' to say where -\c -.B gcc\c -\& is to stop. Note that some combinations (for example, -`\|\c -.B \-x cpp\-output \-E\c -\&\|') instruct \c -.B gcc\c -\& to do nothing at all. -.TP -.B \-c -Compile or assemble the source files, but do not link. The compiler -output is an object file corresponding to each source file. - -By default, GCC makes the object file name for a source file by replacing -the suffix `\|\c -.B .c\c -\&\|', `\|\c -.B .i\c -\&\|', `\|\c -.B .s\c -\&\|', etc., with `\|\c -.B .o\c -\&\|'. Use -.B \-o\c -\& to select another name. - -GCC ignores any unrecognized input files (those that do not require -compilation or assembly) with the -.B \-c -option. -.TP -.B \-S -Stop after the stage of compilation proper; do not assemble. The output -is an assembler code file for each non-assembler input -file specified. - -By default, GCC makes the assembler file name for a source file by -replacing the suffix `\|\c -.B .c\c -\&\|', `\|\c -.B .i\c -\&\|', etc., with `\|\c -.B .s\c -\&\|'. Use -.B \-o\c -\& to select another name. - - -GCC ignores any input files that don't require compilation. -.TP -.B \-E -Stop after the preprocessing stage; do not run the compiler proper. The -output is preprocessed source code, which is sent to the -standard output. - -GCC ignores input files which don't require preprocessing. -.TP -.BI "\-o " file\c -\& -Place output in file \c -.I file\c -\&. This applies regardless to whatever -sort of output GCC is producing, whether it be an executable file, -an object file, an assembler file or preprocessed C code. - -Since only one output file can be specified, it does not make sense to -use `\|\c -.B \-o\c -\&\|' when compiling more than one input file, unless you are -producing an executable file as output. - -If you do not specify `\|\c -.B \-o\c -\&\|', the default is to put an executable file -in `\|\c -.B a.out\c -\&\|', the object file for `\|\c -.B \c -.I source\c -\&.\c -.I suffix\c -\&\c -\&\|' in -`\|\c -.B \c -.I source\c -\&.o\c -\&\|', its assembler file in `\|\c -.B \c -.I source\c -\&.s\c -\&\|', and -all preprocessed C source on standard output. -.TP -.B \-v -Print (on standard error output) the commands executed to run the stages -of compilation. Also print the version number of the compiler driver -program and of the preprocessor and the compiler proper. -.TP -.B \-pipe -Use pipes rather than temporary files for communication between the -various stages of compilation. This fails to work on some systems where -the assembler cannot read from a pipe; but the GNU assembler has -no trouble. -.PP - -.SH LANGUAGE OPTIONS -The following options control the dialect of C that the compiler -accepts: -.TP -.B \-ansi -Support all ANSI standard C programs. - -This turns off certain features of GNU C that are incompatible with -ANSI C, such as the \c -.B asm\c -\&, \c -.B inline\c -\& and \c -.B typeof\c -\& -keywords, and predefined macros such as \c -.B unix\c -\& and \c -.B vax\c -\& -that identify the type of system you are using. It also enables the -undesirable and rarely used ANSI trigraph feature, and disallows `\|\c -.B $\c -\&\|' as part of identifiers. - -The alternate keywords \c -.B __asm__\c -\&, \c -.B __extension__\c -\&, -\c -.B __inline__\c -\& and \c -.B __typeof__\c -\& continue to work despite -`\|\c -.B \-ansi\c -\&\|'. You would not want to use them in an ANSI C program, of -course, but it is useful to put them in header files that might be included -in compilations done with `\|\c -.B \-ansi\c -\&\|'. Alternate predefined macros -such as \c -.B __unix__\c -\& and \c -.B __vax__\c -\& are also available, with or -without `\|\c -.B \-ansi\c -\&\|'. - -The `\|\c -.B \-ansi\c -\&\|' option does not cause non-ANSI programs to be -rejected gratuitously. For that, `\|\c -.B \-pedantic\c -\&\|' is required in -addition to `\|\c -.B \-ansi\c -\&\|'. - -The preprocessor predefines a macro \c -.B __STRICT_ANSI__\c -\& when you use the `\|\c -.B \-ansi\c -\&\|' -option. Some header files may notice this macro and refrain -from declaring certain functions or defining certain macros that the -ANSI standard doesn't call for; this is to avoid interfering with any -programs that might use these names for other things. -.TP -.B \-fno\-asm -Do not recognize \c -.B asm\c -\&, \c -.B inline\c -\& or \c -.B typeof\c -\& as a -keyword. These words may then be used as identifiers. You can -use \c -.B __asm__\c -\&, \c -.B __inline__\c -\& and \c -.B __typeof__\c -\& instead. -`\|\c -.B \-ansi\c -\&\|' implies `\|\c -.B \-fno\-asm\c -\&\|'. -.TP -.B \-fno\-builtin -Don't recognize built-in functions that do not begin with two leading -underscores. Currently, the functions affected include \c -.B _exit\c -\&, -\c -.B abort\c -\&, \c -.B abs\c -\&, \c -.B alloca\c -\&, \c -.B cos\c -\&, \c -.B exit\c -\&, -\c -.B fabs\c -\&, \c -.B labs\c -\&, \c -.B memcmp\c -\&, \c -.B memcpy\c -\&, \c -.B sin\c -\&, -\c -.B sqrt\c -\&, \c -.B strcmp\c -\&, \c -.B strcpy\c -\&, and \c -.B strlen\c -\&. - -The `\|\c -.B \-ansi\c -\&\|' option prevents \c -.B alloca\c -\& and \c -.B _exit\c -\& from -being builtin functions. -.TP -.B \-fno\-strict\-prototype -Treat a function declaration with no arguments, such as `\|\c -.B int foo -();\c -\&\|', as C would treat it\(em\&as saying nothing about the number of -arguments or their types (C++ only). Normally, such a declaration in -C++ means that the function \c -.B foo\c -\& takes no arguments. -.TP -.B \-trigraphs -Support ANSI C trigraphs. The `\|\c -.B \-ansi\c -\&\|' option implies `\|\c -.B \-trigraphs\c -\&\|'. -.TP -.B \-traditional -Attempt to support some aspects of traditional C compilers. -For details, see the GNU C Manual; the duplicate list here -has been deleted so that we won't get complaints when it -is out of date. - -But one note about C++ programs only (not C). `\|\c -.B \-traditional\c -\&\|' has one additional effect for C++: assignment to -.B this -is permitted. This is the same as the effect of `\|\c -.B \-fthis\-is\-variable\c -\&\|'. -.TP -.B \-traditional\-cpp -Attempt to support some aspects of traditional C preprocessors. -This includes the items that specifically mention the preprocessor above, -but none of the other effects of `\|\c -.B \-traditional\c -\&\|'. -.TP -.B \-fdollars\-in\-identifiers -Permit the use of `\|\c -.B $\c -\&\|' in identifiers (C++ only). You can also use -`\|\c -.B \-fno\-dollars\-in\-identifiers\c -\&\|' to explicitly prohibit use of -`\|\c -.B $\c -\&\|'. (GNU C++ allows `\|\c -.B $\c -\&\|' by default on some target systems -but not others.) -.TP -.B \-fenum\-int\-equiv -Permit implicit conversion of \c -.B int\c -\& to enumeration types (C++ -only). Normally GNU C++ allows conversion of \c -.B enum\c -\& to \c -.B int\c -\&, -but not the other way around. -.TP -.B \-fall\-virtual -Treat all possible member functions as virtual, implicitly. All -member functions (except for constructor functions and -.B new -or -.B delete -member operators) are treated as virtual functions of the class where -they appear. - -This does not mean that all calls to these member functions will be -made through the internal table of virtual functions. Under some -circumstances, the compiler can determine that a call to a given -virtual function can be made directly; in these cases the calls are -direct in any case. -.TP -.B \-fcond\-mismatch -Allow conditional expressions with mismatched types in the second and -third arguments. The value of such an expression is void. -.TP -.B \-fthis\-is\-variable -Permit assignment to \c -.B this\c -\& (C++ only). The incorporation of -user-defined free store management into C++ has made assignment to -`\|\c -.B this\c -\&\|' an anachronism. Therefore, by default it is invalid to -assign to \c -.B this\c -\& within a class member function. However, for -backwards compatibility, you can make it valid with -`\|\c -.B \-fthis-is-variable\c -\&\|'. -.TP -.B \-funsigned\-char -Let the type \c -.B char\c -\& be unsigned, like \c -.B unsigned char\c -\&. - -Each kind of machine has a default for what \c -.B char\c -\& should -be. It is either like \c -.B unsigned char\c -\& by default or like -\c -.B signed char\c -\& by default. - -Ideally, a portable program should always use \c -.B signed char\c -\& or -\c -.B unsigned char\c -\& when it depends on the signedness of an object. -But many programs have been written to use plain \c -.B char\c -\& and -expect it to be signed, or expect it to be unsigned, depending on the -machines they were written for. This option, and its inverse, let you -make such a program work with the opposite default. - -The type \c -.B char\c -\& is always a distinct type from each of -\c -.B signed char\c -\& and \c -.B unsigned char\c -\&, even though its behavior -is always just like one of those two. - -.TP -.B \-fsigned\-char -Let the type \c -.B char\c -\& be signed, like \c -.B signed char\c -\&. - -Note that this is equivalent to `\|\c -.B \-fno\-unsigned\-char\c -\&\|', which is -the negative form of `\|\c -.B \-funsigned\-char\c -\&\|'. Likewise, -`\|\c -.B \-fno\-signed\-char\c -\&\|' is equivalent to `\|\c -.B \-funsigned\-char\c -\&\|'. -.TP -.B \-fsigned\-bitfields -.TP -.B \-funsigned\-bitfields -.TP -.B \-fno\-signed\-bitfields -.TP -.B \-fno\-unsigned\-bitfields -These options control whether a bitfield is -signed or unsigned, when declared with no explicit `\|\c -.B signed\c -\&\|' or `\|\c -.B unsigned\c -\&\|' qualifier. By default, such a bitfield is -signed, because this is consistent: the basic integer types such as -\c -.B int\c -\& are signed types. - -However, when you specify `\|\c -.B \-traditional\c -\&\|', bitfields are all unsigned -no matter what. -.TP -.B \-fwritable\-strings -Store string constants in the writable data segment and don't uniquize -them. This is for compatibility with old programs which assume they -can write into string constants. `\|\c -.B \-traditional\c -\&\|' also has this -effect. - -Writing into string constants is a very bad idea; ``constants'' should -be constant. -.PP - -.SH PREPROCESSOR OPTIONS -These options control the C preprocessor, which is run on each C source -file before actual compilation. - -If you use the `\|\c -.B \-E\c -\&\|' option, GCC does nothing except preprocessing. -Some of these options make sense only together with `\|\c -.B \-E\c -\&\|' because -they cause the preprocessor output to be unsuitable for actual -compilation. -.TP -.BI "\-include " "file" -Process \c -.I file\c -\& as input before processing the regular input file. -In effect, the contents of \c -.I file\c -\& are compiled first. Any `\|\c -.B \-D\c -\&\|' -and `\|\c -.B \-U\c -\&\|' options on the command line are always processed before -`\|\c -.B \-include \c -.I file\c -\&\c -\&\|', regardless of the order in which they are -written. All the `\|\c -.B \-include\c -\&\|' and `\|\c -.B \-imacros\c -\&\|' options are -processed in the order in which they are written. -.TP -.BI "\-imacros " file -Process \c -.I file\c -\& as input, discarding the resulting output, before -processing the regular input file. Because the output generated from -\c -.I file\c -\& is discarded, the only effect of `\|\c -.B \-imacros \c -.I file\c -\&\c -\&\|' is to -make the macros defined in \c -.I file\c -\& available for use in the main -input. The preprocessor evaluates any `\|\c -.B \-D\c -\&\|' and `\|\c -.B \-U\c -\&\|' options -on the command line before processing `\|\c -.B \-imacros\c -.I file\c -\&\|', regardless of the order in -which they are written. All the `\|\c -.B \-include\c -\&\|' and `\|\c -.B \-imacros\c -\&\|' -options are processed in the order in which they are written. -.TP -.BI "-idirafter " "dir"\c -\& -Add the directory \c -.I dir\c -\& to the second include path. The directories -on the second include path are searched when a header file is not found -in any of the directories in the main include path (the one that -`\|\c -.B \-I\c -\&\|' adds to). -.TP -.BI "-iprefix " "prefix"\c -\& -Specify \c -.I prefix\c -\& as the prefix for subsequent `\|\c -.B \-iwithprefix\c -\&\|' -options. -.TP -.BI "-iwithprefix " "dir"\c -\& -Add a directory to the second include path. The directory's name is -made by concatenating \c -.I prefix\c -\& and \c -.I dir\c -\&, where \c -.I prefix\c -\& -was specified previously with `\|\c -.B \-iprefix\c -\&\|'. -.TP -.B \-nostdinc -Do not search the standard system directories for header files. Only -the directories you have specified with `\|\c -.B \-I\c -\&\|' options (and the -current directory, if appropriate) are searched. - -By using both `\|\c -.B \-nostdinc\c -\&\|' and `\|\c -.B \-I\-\c -\&\|', you can limit the include-file search file to only those -directories you specify explicitly. -.TP -.B \-nostdinc++ -Do not search for header files in the C++-specific standard directories, -but do still search the other standard directories. -(This option is used when building `\|\c -.B libg++\c -\&\|'.) -.TP -.B \-undef -Do not predefine any nonstandard macros. (Including architecture flags). -.TP -.B \-E -Run only the C preprocessor. Preprocess all the C source files -specified and output the results to standard output or to the -specified output file. -.TP -.B \-C -Tell the preprocessor not to discard comments. Used with the -`\|\c -.B \-E\c -\&\|' option. -.TP -.B \-P -Tell the preprocessor not to generate `\|\c -.B #line\c -\&\|' commands. -Used with the `\|\c -.B \-E\c -\&\|' option. -.TP -.B \-M -Tell the preprocessor to output a rule suitable for \c -.B make\c -\& -describing the dependencies of each object file. For each source file, -the preprocessor outputs one \c -.B make\c -\&-rule whose target is the object -file name for that source file and whose dependencies are all the files -`\|\c -.B #include\c -\&\|'d in it. This rule may be a single line or may be -continued with `\|\c -.B \e\c -\&\|'-newline if it is long. The list of rules is -printed on standard output instead of the preprocessed C program. - -`\|\c -.B \-M\c -\&\|' implies `\|\c -.B \-E\c -\&\|'. -.TP -.B \-MM -Like `\|\c -.B \-M\c -\&\|' but the output mentions only the user header files -included with `\|\c -.B #include "\c -.I file\c -\&"\c -\&\|'. System header files -included with `\|\c -.B #include <\c -.I file\c -\&>\c -\&\|' are omitted. -.TP -.B \-MD -Like `\|\c -.B \-M\c -\&\|' but the dependency information is written to files with -names made by replacing `\|\c -.B .o\c -\&\|' with `\|\c -.B .d\c -\&\|' at the end of the -output file names. This is in addition to compiling the file as -specified\(em\&`\|\c -.B \-MD\c -\&\|' does not inhibit ordinary compilation the way -`\|\c -.B \-M\c -\&\|' does. - -The Mach utility `\|\c -.B md\c -\&\|' can be used to merge the `\|\c -.B .d\c -\&\|' files -into a single dependency file suitable for using with the `\|\c -.B make\c -\&\|' -command. -.TP -.B \-MMD -Like `\|\c -.B \-MD\c -\&\|' except mention only user header files, not system -header files. -.TP -.B \-H -Print the name of each header file used, in addition to other normal -activities. -.TP -.BI "-A" "question" ( answer ) -Assert the answer -.I answer -for -.I question\c -\&, in case it is tested -with a preprocessor conditional such as `\|\c -.BI "#if #" question ( answer )\c -\&\|'. `\|\c -.B \-A\-\c -\&\|' disables the standard -assertions that normally describe the target machine. -.TP -.BI "-A" "question"\c -\&(\c -.I answer\c -\&) -Assert the answer \c -.I answer\c -\& for \c -.I question\c -\&, in case it is tested -with a preprocessor conditional such as `\|\c -.B #if -#\c -.I question\c -\&(\c -.I answer\c -\&)\c -\&\|'. `\|\c -.B \-A-\c -\&\|' disables the standard -assertions that normally describe the target machine. -.TP -.BI \-D macro -Define macro \c -.I macro\c -\& with the string `\|\c -.B 1\c -\&\|' as its definition. -.TP -.BI \-D macro = defn -Define macro \c -.I macro\c -\& as \c -.I defn\c -\&. All instances of `\|\c -.B \-D\c -\&\|' on -the command line are processed before any `\|\c -.B \-U\c -\&\|' options. -.TP -.BI \-U macro -Undefine macro \c -.I macro\c -\&. `\|\c -.B \-U\c -\&\|' options are evaluated after all `\|\c -.B \-D\c -\&\|' options, but before any `\|\c -.B \-include\c -\&\|' and `\|\c -.B \-imacros\c -\&\|' options. -.TP -.B \-dM -Tell the preprocessor to output only a list of the macro definitions -that are in effect at the end of preprocessing. Used with the `\|\c -.B \-E\c -\&\|' -option. -.TP -.B \-dD -Tell the preprocessor to pass all macro definitions into the output, in -their proper sequence in the rest of the output. -.TP -.B \-dN -Like `\|\c -.B \-dD\c -\&\|' except that the macro arguments and contents are omitted. -Only `\|\c -.B #define \c -.I name\c -\&\c -\&\|' is included in the output. -.PP - -.SH ASSEMBLER OPTION -.TP -.BI "-Wa," "option"\c -\& -Pass \c -.I option\c -\& as an option to the assembler. If \c -.I option\c -\& -contains commas, it is split into multiple options at the commas. -.PP - -.SH LINKER OPTIONS -These options come into play when the compiler links object files into -an executable output file. They are meaningless if the compiler is -not doing a link step. -.TP -.I object-file-name -A file name that does not end in a special recognized suffix is -considered to name an object file or library. (Object files are -distinguished from libraries by the linker according to the file -contents.) If GCC does a link step, these object files are used as input -to the linker. -.TP -.BI \-l library\c -\& -Use the library named \c -.I library\c -\& when linking. - -The linker searches a standard list of directories for the library, -which is actually a file named `\|\c -.B lib\c -.I library\c -\&.a\c -\&\|'. The linker -then uses this file as if it had been specified precisely by name. - -The directories searched include several standard system directories -plus any that you specify with `\|\c -.B \-L\c -\&\|'. - -Normally the files found this way are library files\(em\&archive files -whose members are object files. The linker handles an archive file by -scanning through it for members which define symbols that have so far -been referenced but not defined. However, if the linker finds an -ordinary object file rather than a library, the object file is linked -in the usual fashion. The only difference between using an `\|\c -.B \-l\c -\&\|' option and specifying a file -name is that `\|\c -.B \-l\c -\&\|' surrounds -.I library -with `\|\c -.B lib\c -\&\|' and `\|\c -.B .a\c -\&\|' and searches several directories. -.TP -.B \-lobjc -You need this special case of the -.B \-l -option in order to link an Objective C program. -.TP -.B \-nostartfiles -Do not use the standard system startup files when linking. -The standard libraries are used normally. -.TP -.B \-nostdlib -Don't use the standard system libraries and startup files when linking. -Only the files you specify will be passed to the linker. -.TP -.B \-static -On systems that support dynamic linking, this prevents linking with the shared -libraries. On other systems, this option has no effect. -.TP -.B \-shared -Produce a shared object which can then be linked with other objects to -form an executable. Only a few systems support this option. -.TP -.B \-symbolic -Bind references to global symbols when building a shared object. Warn -about any unresolved references (unless overridden by the link editor -option `\|\c -.B -\-Xlinker \-z \-Xlinker defs\c -\&\|'). Only a few systems support -this option. -.TP -.BI "-Xlinker " "option" -Pass \c -.I option -as an option to the linker. You can use this to -supply system-specific linker options which GNU CC does not know how to -recognize. - -If you want to pass an option that takes an argument, you must use -`\|\c -.B \-Xlinker\c -\&\|' twice, once for the option and once for the argument. -For example, to pass `\|\c -.B -\-assert definitions\c -\&\|', you must write -`\|\c -.B -\-Xlinker \-assert \-Xlinker definitions\c -\&\|'. It does not work to write -`\|\c -.B -\-Xlinker "-assert definitions"\c -\&\|', because this passes the entire -string as a single argument, which is not what the linker expects. -.TP -.BI "-Wl," "option"\c -\& -Pass \c -.I option\c -\& as an option to the linker. If \c -.I option\c -\& contains -commas, it is split into multiple options at the commas. -.TP -.BI "-u " "symbol" -Pretend the symbol -.I symbol -is undefined, to force linking of -library modules to define it. You can use `\|\c -.B \-u\c -\&\|' multiple times with -different symbols to force loading of additional library modules. -.PP - -.SH DIRECTORY OPTIONS -These options specify directories to search for header files, for -libraries and for parts of the compiler: -.TP -.BI "\-I" "dir"\c -\& -Append directory \c -.I dir\c -\& to the list of directories searched for include files. -.TP -.B \-I\- -Any directories you specify with `\|\c -.B \-I\c -\&\|' options before the `\|\c -.B \-I\-\c -\&\|' -option are searched only for the case of `\|\c -.B -#include "\c -.I file\c -.B -\&"\c -\&\|'; -they are not searched for `\|\c -.B #include <\c -.I file\c -\&>\c -\&\|'. - -If additional directories are specified with `\|\c -.B \-I\c -\&\|' options after -the `\|\c -.B \-I\-\c -\&\|', these directories are searched for all `\|\c -.B #include\c -\&\|' -directives. (Ordinarily \c -.I all\c -\& `\|\c -.B \-I\c -\&\|' directories are used -this way.) - -In addition, the `\|\c -.B \-I\-\c -\&\|' option inhibits the use of the current -directory (where the current input file came from) as the first search -directory for `\|\c -.B -#include "\c -.I file\c -.B -\&"\c -\&\|'. There is no way to -override this effect of `\|\c -.B \-I\-\c -\&\|'. With `\|\c -.B \-I.\c -\&\|' you can specify -searching the directory which was current when the compiler was -invoked. That is not exactly the same as what the preprocessor does -by default, but it is often satisfactory. - -`\|\c -.B \-I\-\c -\&\|' does not inhibit the use of the standard system directories -for header files. Thus, `\|\c -.B \-I\-\c -\&\|' and `\|\c -.B \-nostdinc\c -\&\|' are -independent. -.TP -.BI "\-L" "dir"\c -\& -Add directory \c -.I dir\c -\& to the list of directories to be searched -for `\|\c -.B \-l\c -\&\|'. -.TP -.BI "\-B" "prefix"\c -\& -This option specifies where to find the executables, libraries and -data files of the compiler itself. - -The compiler driver program runs one or more of the subprograms -`\|\c -.B cpp\c -\&\|', `\|\c -.B cc1\c -\&\|' (or, for C++, `\|\c -.B cc1plus\c -\&\|'), `\|\c -.B as\c -\&\|' and `\|\c -.B ld\c -\&\|'. It tries -\c -.I prefix\c -\& as a prefix for each program it tries to run, both with and -without `\|\c -.B \c -.I machine\c -\&/\c -.I version\c -\&/\c -\&\|'. - -For each subprogram to be run, the compiler driver first tries the -`\|\c -.B \-B\c -\&\|' prefix, if any. If that name is not found, or if `\|\c -.B \-B\c -\&\|' -was not specified, the driver tries two standard prefixes, which are -`\|\c -.B /usr/lib/gcc/\c -\&\|' and `\|\c -.B /usr/local/lib/gcc-lib/\c -\&\|'. If neither of -those results in a file name that is found, the compiler driver -searches for the unmodified program -name, using the directories specified in your -`\|\c -.B PATH\c -\&\|' environment variable. - -The run-time support file `\|\c -.B libgcc.a\c -\&\|' is also searched for using the -`\|\c -.B \-B\c -\&\|' prefix, if needed. If it is not found there, the two -standard prefixes above are tried, and that is all. The file is left -out of the link if it is not found by those means. Most of the time, -on most machines, `\|\c -.B libgcc.a\c -\&\|' is not actually necessary. - -You can get a similar result from the environment variable -\c -.B GCC_EXEC_PREFIX\c -\&; if it is defined, its value is used as a prefix -in the same way. If both the `\|\c -.B \-B\c -\&\|' option and the -\c -.B GCC_EXEC_PREFIX\c -\& variable are present, the `\|\c -.B \-B\c -\&\|' option is -used first and the environment variable value second. -.PP - -.SH WARNING OPTIONS -Warnings are diagnostic messages that report constructions which -are not inherently erroneous but which are risky or suggest there -may have been an error. - -These options control the amount and kinds of warnings produced by GNU -CC: -.TP -.B \-fsyntax\-only -Check the code for syntax errors, but don't emit any output. -.TP -.B \-w -Inhibit all warning messages. -.TP -.B \-Wno\-import -Inhibit warning messages about the use of -.BR #import . -.TP -.B \-pedantic -Issue all the warnings demanded by strict ANSI standard C; reject -all programs that use forbidden extensions. - -Valid ANSI standard C programs should compile properly with or without -this option (though a rare few will require `\|\c -.B \-ansi\c -\&\|'). However, -without this option, certain GNU extensions and traditional C features -are supported as well. With this option, they are rejected. There is -no reason to \c -.I use\c -\& this option; it exists only to satisfy pedants. - -`\|\c -.B \-pedantic\c -\&\|' does not cause warning messages for use of the -alternate keywords whose names begin and end with `\|\c -.B __\c -\&\|'. Pedantic -warnings are also disabled in the expression that follows -\c -.B __extension__\c -\&. However, only system header files should use -these escape routes; application programs should avoid them. -.TP -.B \-pedantic\-errors -Like `\|\c -.B \-pedantic\c -\&\|', except that errors are produced rather than -warnings. -.TP -.B \-W -Print extra warning messages for these events: -.TP -\ \ \ \(bu -A nonvolatile automatic variable might be changed by a call to -\c -.B longjmp\c -\&. These warnings are possible only in -optimizing compilation. - -The compiler sees only the calls to \c -.B setjmp\c -\&. It cannot know -where \c -.B longjmp\c -\& will be called; in fact, a signal handler could -call it at any point in the code. As a result, you may get a warning -even when there is in fact no problem because \c -.B longjmp\c -\& cannot -in fact be called at the place which would cause a problem. -.TP -\ \ \ \(bu -A function can return either with or without a value. (Falling -off the end of the function body is considered returning without -a value.) For example, this function would evoke such a -warning: -.sp -.br -foo\ (a) -.br -{ -.br -\ \ if\ (a\ >\ 0) -.br -\ \ \ \ return\ a; -.br -} -.br -.sp - -Spurious warnings can occur because GNU CC does not realize that -certain functions (including \c -.B abort\c -\& and \c -.B longjmp\c -\&) -will never return. -.TP -\ \ \ \(bu -An expression-statement contains no side effects. -.TP -\ \ \ \(bu -An unsigned value is compared against zero with `\|\c -.B >\c -\&\|' or `\|\c -.B <=\c -\&\|'. -.PP -.TP -.B \-Wimplicit -Warn whenever a function or parameter is implicitly declared. -.TP -.B \-Wreturn\-type -Warn whenever a function is defined with a return-type that defaults -to \c -.B int\c -\&. Also warn about any \c -.B return\c -\& statement with no -return-value in a function whose return-type is not \c -.B void\c -\&. -.TP -.B \-Wunused -Warn whenever a local variable is unused aside from its declaration, -whenever a function is declared static but never defined, and whenever -a statement computes a result that is explicitly not used. -.TP -.B \-Wswitch -Warn whenever a \c -.B switch\c -\& statement has an index of enumeral type -and lacks a \c -.B case\c -\& for one or more of the named codes of that -enumeration. (The presence of a \c -.B default\c -\& label prevents this -warning.) \c -.B case\c -\& labels outside the enumeration range also -provoke warnings when this option is used. -.TP -.B \-Wcomment -Warn whenever a comment-start sequence `\|\c -.B /*\c -\&\|' appears in a comment. -.TP -.B \-Wtrigraphs -Warn if any trigraphs are encountered (assuming they are enabled). -.TP -.B \-Wformat -Check calls to \c -.B printf\c -\& and \c -.B scanf\c -\&, etc., to make sure that -the arguments supplied have types appropriate to the format string -specified. -.TP -.B \-Wchar\-subscripts -Warn if an array subscript has type -.BR char . -This is a common cause of error, as programmers often forget that this -type is signed on some machines. -.TP -.B \-Wuninitialized -An automatic variable is used without first being initialized. - -These warnings are possible only in optimizing compilation, -because they require data flow information that is computed only -when optimizing. If you don't specify `\|\c -.B \-O\c -\&\|', you simply won't -get these warnings. - -These warnings occur only for variables that are candidates for -register allocation. Therefore, they do not occur for a variable that -is declared \c -.B volatile\c -\&, or whose address is taken, or whose size -is other than 1, 2, 4 or 8 bytes. Also, they do not occur for -structures, unions or arrays, even when they are in registers. - -Note that there may be no warning about a variable that is used only -to compute a value that itself is never used, because such -computations may be deleted by data flow analysis before the warnings -are printed. - -These warnings are made optional because GNU CC is not smart -enough to see all the reasons why the code might be correct -despite appearing to have an error. Here is one example of how -this can happen: - -.sp -.br -{ -.br -\ \ int\ x; -.br -\ \ switch\ (y) -.br -\ \ \ \ { -.br -\ \ \ \ case\ 1:\ x\ =\ 1; -.br -\ \ \ \ \ \ break; -.br -\ \ \ \ case\ 2:\ x\ =\ 4; -.br -\ \ \ \ \ \ break; -.br -\ \ \ \ case\ 3:\ x\ =\ 5; -.br -\ \ \ \ } -.br -\ \ foo\ (x); -.br -} -.br -.sp - - -If the value of \c -.B y\c -\& is always 1, 2 or 3, then \c -.B x\c -\& is -always initialized, but GNU CC doesn't know this. Here is -another common case: - -.sp -.br -{ -.br -\ \ int\ save_y; -.br -\ \ if\ (change_y)\ save_y\ =\ y,\ y\ =\ new_y; -.br -\ \ .\|.\|. -.br -\ \ if\ (change_y)\ y\ =\ save_y; -.br -} -.br -.sp - - -This has no bug because \c -.B save_y\c -\& is used only if it is set. - -Some spurious warnings can be avoided if you declare as -\c -.B volatile\c -\& all the functions you use that never return. -.TP -.B \-Wparentheses -Warn if parentheses are omitted in certain contexts. -.TP -.B \-Wtemplate\-debugging -When using templates in a C++ program, warn if debugging is not yet -fully available (C++ only). -.TP -.B \-Wall -All of the above `\|\c -.B \-W\c -\&\|' options combined. These are all the -options which pertain to usage that we recommend avoiding and that we -believe is easy to avoid, even in conjunction with macros. -.PP - -The remaining `\|\c -.B \-W.\|.\|.\c -\&\|' options are not implied by `\|\c -.B \-Wall\c -\&\|' -because they warn about constructions that we consider reasonable to -use, on occasion, in clean programs. -.TP -.B \-Wtraditional -Warn about certain constructs that behave differently in traditional and -ANSI C. -.TP -\ \ \ \(bu -Macro arguments occurring within string constants in the macro body. -These would substitute the argument in traditional C, but are part of -the constant in ANSI C. -.TP -\ \ \ \(bu -A function declared external in one block and then used after the end of -the block. -.TP -\ \ \ \(bu -A \c -.B switch\c -\& statement has an operand of type \c -.B long\c -\&. -.PP -.TP -.B \-Wshadow -Warn whenever a local variable shadows another local variable. -.TP -.BI "\-Wid\-clash\-" "len"\c -\& -Warn whenever two distinct identifiers match in the first \c -.I len\c -\& -characters. This may help you prepare a program that will compile -with certain obsolete, brain-damaged compilers. -.TP -.B \-Wpointer\-arith -Warn about anything that depends on the ``size of'' a function type or -of \c -.B void\c -\&. GNU C assigns these types a size of 1, for -convenience in calculations with \c -.B void *\c -\& pointers and pointers -to functions. -.TP -.B \-Wcast\-qual -Warn whenever a pointer is cast so as to remove a type qualifier from -the target type. For example, warn if a \c -.B const char *\c -\& is cast -to an ordinary \c -.B char *\c -\&. -.TP -.B \-Wcast\-align -Warn whenever a pointer is cast such that the required alignment of the -target is increased. For example, warn if a \c -.B char *\c -\& is cast to -an \c -.B int *\c -\& on machines where integers can only be accessed at -two- or four-byte boundaries. -.TP -.B \-Wwrite\-strings -Give string constants the type \c -.B const char[\c -.I length\c -\&]\c -\& so that -copying the address of one into a non-\c -.B const\c -\& \c -.B char *\c -\& -pointer will get a warning. These warnings will help you find at -compile time code that can try to write into a string constant, but -only if you have been very careful about using \c -.B const\c -\& in -declarations and prototypes. Otherwise, it will just be a nuisance; -this is why we did not make `\|\c -.B \-Wall\c -\&\|' request these warnings. -.TP -.B \-Wconversion -Warn if a prototype causes a type conversion that is different from what -would happen to the same argument in the absence of a prototype. This -includes conversions of fixed point to floating and vice versa, and -conversions changing the width or signedness of a fixed point argument -except when the same as the default promotion. -.TP -.B \-Waggregate\-return -Warn if any functions that return structures or unions are defined or -called. (In languages where you can return an array, this also elicits -a warning.) -.TP -.B \-Wstrict\-prototypes -Warn if a function is declared or defined without specifying the -argument types. (An old-style function definition is permitted without -a warning if preceded by a declaration which specifies the argument -types.) -.TP -.B \-Wmissing\-prototypes -Warn if a global function is defined without a previous prototype -declaration. This warning is issued even if the definition itself -provides a prototype. The aim is to detect global functions that fail -to be declared in header files. -.TP -.B \-Wredundant-decls -Warn if anything is declared more than once in the same scope, even in -cases where multiple declaration is valid and changes nothing. -.TP -.B \-Wnested-externs -Warn if an \c -.B extern\c -\& declaration is encountered within an function. -.TP -.B \-Wenum\-clash -Warn about conversion between different enumeration types (C++ only). -.TP -.B \-Woverloaded\-virtual -(C++ only.) -In a derived class, the definitions of virtual functions must match -the type signature of a virtual function declared in the base class. -Use this option to request warnings when a derived class declares a -function that may be an erroneous attempt to define a virtual -function: that is, warn when a function with the same name as a -virtual function in the base class, but with a type signature that -doesn't match any virtual functions from the base class. -.TP -.B \-Winline -Warn if a function can not be inlined, and either it was declared as inline, -or else the -.B \-finline\-functions -option was given. -.TP -.B \-Werror -Treat warnings as errors; abort compilation after any warning. -.PP - -.SH DEBUGGING OPTIONS -GNU CC has various special options that are used for debugging -either your program or GCC: -.TP -.B \-g -Produce debugging information in the operating system's native format -(stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging -information. - -On most systems that use stabs format, `\|\c -.B \-g\c -\&\|' enables use of extra -debugging information that only GDB can use; this extra information -makes debugging work better in GDB but will probably make other debuggers -crash or -refuse to read the program. If you want to control for certain whether -to generate the extra information, use `\|\c -.B \-gstabs+\c -\&\|', `\|\c -.B \-gstabs\c -\&\|', -`\|\c -.B \-gxcoff+\c -\&\|', `\|\c -.B \-gxcoff\c -\&\|', `\|\c -.B \-gdwarf+\c -\&\|', or `\|\c -.B \-gdwarf\c -\&\|' -(see below). - -Unlike most other C compilers, GNU CC allows you to use `\|\c -.B \-g\c -\&\|' with -`\|\c -.B \-O\c -\&\|'. The shortcuts taken by optimized code may occasionally -produce surprising results: some variables you declared may not exist -at all; flow of control may briefly move where you did not expect it; -some statements may not be executed because they compute constant -results or their values were already at hand; some statements may -execute in different places because they were moved out of loops. - -Nevertheless it proves possible to debug optimized output. This makes -it reasonable to use the optimizer for programs that might have bugs. - -The following options are useful when GNU CC is generated with the -capability for more than one debugging format. -.TP -.B \-ggdb -Produce debugging information in the native format (if that is supported), -including GDB extensions if at all possible. -.TP -.B \-gstabs -Produce debugging information in stabs format (if that is supported), -without GDB extensions. This is the format used by DBX on most BSD -systems. -.TP -.B \-gstabs+ -Produce debugging information in stabs format (if that is supported), -using GNU extensions understood only by the GNU debugger (GDB). The -use of these extensions is likely to make other debuggers crash or -refuse to read the program. -.TP -.B \-gcoff -Produce debugging information in COFF format (if that is supported). -This is the format used by SDB on most System V systems prior to -System V Release 4. -.TP -.B \-gxcoff -Produce debugging information in XCOFF format (if that is supported). -This is the format used by the DBX debugger on IBM RS/6000 systems. -.TP -.B \-gxcoff+ -Produce debugging information in XCOFF format (if that is supported), -using GNU extensions understood only by the GNU debugger (GDB). The -use of these extensions is likely to make other debuggers crash or -refuse to read the program. -.TP -.B \-gdwarf -Produce debugging information in DWARF format (if that is supported). -This is the format used by SDB on most System V Release 4 systems. -.TP -.B \-gdwarf+ -Produce debugging information in DWARF format (if that is supported), -using GNU extensions understood only by the GNU debugger (GDB). The -use of these extensions is likely to make other debuggers crash or -refuse to read the program. -.PP -.BI "\-g" "level" -.br -.BI "\-ggdb" "level" -.br -.BI "\-gstabs" "level" -.br -.BI "\-gcoff" "level" -.BI "\-gxcoff" "level" -.TP -.BI "\-gdwarf" "level" -Request debugging information and also use \c -.I level\c -\& to specify how -much information. The default level is 2. - -Level 1 produces minimal information, enough for making backtraces in -parts of the program that you don't plan to debug. This includes -descriptions of functions and external variables, but no information -about local variables and no line numbers. - -Level 3 includes extra information, such as all the macro definitions -present in the program. Some debuggers support macro expansion when -you use `\|\c -.B \-g3\c -\&\|'. -.TP -.B \-p -Generate extra code to write profile information suitable for the -analysis program \c -.B prof\c -\&. -.TP -.B \-pg -Generate extra code to write profile information suitable for the -analysis program \c -.B gprof\c -\&. -.TP -.B \-a -Generate extra code to write profile information for basic blocks, -which will record the number of times each basic block is executed. -This data could be analyzed by a program like \c -.B tcov\c -\&. Note, -however, that the format of the data is not what \c -.B tcov\c -\& expects. -Eventually GNU \c -.B gprof\c -\& should be extended to process this data. -.TP -.BI "\-d" "letters"\c -\& -Says to make debugging dumps during compilation at times specified by -\c -.I letters\c -\&. This is used for debugging the compiler. The file names -for most of the dumps are made by appending a word to the source file -name (e.g. `\|\c -.B foo.c.rtl\c -\&\|' or `\|\c -.B foo.c.jump\c -\&\|'). -.TP -.B \-dM -Dump all macro definitions, at the end of preprocessing, and write no -output. -.TP -.B \-dN -Dump all macro names, at the end of preprocessing. -.TP -.B \-dD -Dump all macro definitions, at the end of preprocessing, in addition to -normal output. -.TP -.B \-dy -Dump debugging information during parsing, to standard error. -.TP -.B \-dr -Dump after RTL generation, to `\|\c -.B \c -.I file\c -\&.rtl\c -\&\|'. -.TP -.B \-dx -Just generate RTL for a function instead of compiling it. Usually used -with `\|\c -.B r\c -\&\|'. -.TP -.B \-dj -Dump after first jump optimization, to `\|\c -.B \c -.I file\c -\&.jump\c -\&\|'. -.TP -.B \-ds -Dump after CSE (including the jump optimization that sometimes -follows CSE), to `\|\c -.B \c -.I file\c -\&.cse\c -\&\|'. -.TP -.B \-dL -Dump after loop optimization, to `\|\c -.B \c -.I file\c -\&.loop\c -\&\|'. -.TP -.B \-dt -Dump after the second CSE pass (including the jump optimization that -sometimes follows CSE), to `\|\c -.B \c -.I file\c -\&.cse2\c -\&\|'. -.TP -.B \-df -Dump after flow analysis, to `\|\c -.B \c -.I file\c -\&.flow\c -\&\|'. -.TP -.B \-dc -Dump after instruction combination, to `\|\c -.B \c -.I file\c -\&.combine\c -\&\|'. -.TP -.B \-dS -Dump after the first instruction scheduling pass, to -`\|\c -.B \c -.I file\c -\&.sched\c -\&\|'. -.TP -.B \-dl -Dump after local register allocation, to `\|\c -.B \c -.I file\c -\&.lreg\c -\&\|'. -.TP -.B \-dg -Dump after global register allocation, to `\|\c -.B \c -.I file\c -\&.greg\c -\&\|'. -.TP -.B \-dR -Dump after the second instruction scheduling pass, to -`\|\c -.B \c -.I file\c -\&.sched2\c -\&\|'. -.TP -.B \-dJ -Dump after last jump optimization, to `\|\c -.B \c -.I file\c -\&.jump2\c -\&\|'. -.TP -.B \-dd -Dump after delayed branch scheduling, to `\|\c -.B \c -.I file\c -\&.dbr\c -\&\|'. -.TP -.B \-dk -Dump after conversion from registers to stack, to `\|\c -.B \c -.I file\c -\&.stack\c -\&\|'. -.TP -.B \-da -Produce all the dumps listed above. -.TP -.B \-dm -Print statistics on memory usage, at the end of the run, to -standard error. -.TP -.B \-dp -Annotate the assembler output with a comment indicating which -pattern and alternative was used. -.TP -.B \-fpretend\-float -When running a cross-compiler, pretend that the target machine uses the -same floating point format as the host machine. This causes incorrect -output of the actual floating constants, but the actual instruction -sequence will probably be the same as GNU CC would make when running on -the target machine. -.TP -.B \-save\-temps -Store the usual ``temporary'' intermediate files permanently; place them -in the current directory and name them based on the source file. Thus, -compiling `\|\c -.B foo.c\c -\&\|' with `\|\c -.B \-c \-save\-temps\c -\&\|' would produce files -`\|\c -.B foo.cpp\c -\&\|' and `\|\c -.B foo.s\c -\&\|', as well as `\|\c -.B foo.o\c -\&\|'. -.TP -.B \-print\-libgcc\-file\-name -Print the full absolute name of the library file `\|\c -.B libgcc.a\c -\&\|' that -would be used when linking\(em\&and do not do anything else. With this -option, GNU CC does not compile or link anything; it just prints the -file name. -.PP - -.SH OPTIMIZATION OPTIONS -These options control various sorts of optimizations: -.PP -.B \-O -.TP -.B \-O1 -Optimize. Optimizing compilation takes somewhat more time, and a lot -more memory for a large function. - -Without `\|\c -.B \-O\c -\&\|', the compiler's goal is to reduce the cost of -compilation and to make debugging produce the expected results. -Statements are independent: if you stop the program with a breakpoint -between statements, you can then assign a new value to any variable or -change the program counter to any other statement in the function and -get exactly the results you would expect from the source code. - -Without `\|\c -.B \-O\c -\&\|', only variables declared \c -.B register\c -\& are -allocated in registers. The resulting compiled code is a little worse -than produced by PCC without `\|\c -.B \-O\c -\&\|'. - -With `\|\c -.B \-O\c -\&\|', the compiler tries to reduce code size and execution -time. - -When you specify `\|\c -.B \-O\c -\&\|', `\|\c -.B \-fthread\-jumps\c -\&\|' and -`\|\c -.B \-fdelayed\-branch\c -\&\|' are turned on. On some machines other -flags may also be turned on. -.TP -.B \-O2 -Optimize even more. Nearly all supported optimizations that do not -involve a space-speed tradeoff are performed. As compared to -.B \-O\c -\&, -this option increases both compilation time and the performance of the -generated code. - -.B \-O2 -turns on all -.BI \-f flag -options that enable more optimization, except for -.B \-funroll\-loops\c -\&, -.B \-funroll\-all\-loops -and -.BR \-fomit\-frame\-pointer . -.TP -.B \-O0 -Do not optimize. - -If you use multiple -.B \-O -options, with or without level numbers, the last such option is the -one that is effective. -.PP - -Options of the form `\|\c -.B \-f\c -.I flag\c -\&\c -\&\|' specify machine-independent -flags. Most flags have both positive and negative forms; the negative -form of `\|\c -.B \-ffoo\c -\&\|' would be `\|\c -.B \-fno\-foo\c -\&\|'. The following list shows -only one form\(em\&the one which is not the default. -You can figure out the other form by either removing `\|\c -.B no\-\c -\&\|' or -adding it. -.TP -.B \-ffloat\-store -Do not store floating point variables in registers. This -prevents undesirable excess precision on machines such as the -68000 where the floating registers (of the 68881) keep more -precision than a \c -.B double\c -\& is supposed to have. - -For most programs, the excess precision does only good, but a few -programs rely on the precise definition of IEEE floating point. -Use `\|\c -.B \-ffloat\-store\c -\&\|' for such programs. -.TP -.B \-fmemoize\-lookups -.TP -.B \-fsave\-memoized -Use heuristics to compile faster (C++ only). These heuristics are not -enabled by default, since they are only effective for certain input -files. Other input files compile more slowly. - -The first time the compiler must build a call to a member function (or -reference to a data member), it must (1) determine whether the class -implements member functions of that name; (2) resolve which member -function to call (which involves figuring out what sorts of type -conversions need to be made); and (3) check the visibility of the member -function to the caller. All of this adds up to slower compilation. -Normally, the second time a call is made to that member function (or -reference to that data member), it must go through the same lengthy -process again. This means that code like this -.sp -.br -cout\ <<\ "This\ "\ <<\ p\ <<\ "\ has\ "\ <<\ n\ <<\ "\ legs.\en"; -.br -.sp -makes six passes through all three steps. By using a software cache, -a ``hit'' significantly reduces this cost. Unfortunately, using the -cache introduces another layer of mechanisms which must be implemented, -and so incurs its own overhead. `\|\c -.B \-fmemoize\-lookups\c -\&\|' enables -the software cache. - -Because access privileges (visibility) to members and member functions -may differ from one function context to the next, -.B g++ -may need to flush the cache. With the `\|\c -.B \-fmemoize\-lookups\c -\&\|' flag, the cache is flushed after every -function that is compiled. The `\|\c -\-fsave\-memoized\c -\&\|' flag enables the same software cache, but when the compiler -determines that the context of the last function compiled would yield -the same access privileges of the next function to compile, it -preserves the cache. -This is most helpful when defining many member functions for the same -class: with the exception of member functions which are friends of -other classes, each member function has exactly the same access -privileges as every other, and the cache need not be flushed. -.TP -.B \-fno\-default\-inline -Don't make member functions inline by default merely because they are -defined inside the class scope (C++ only). -.TP -.B \-fno\-defer\-pop -Always pop the arguments to each function call as soon as that -function returns. For machines which must pop arguments after a -function call, the compiler normally lets arguments accumulate on the -stack for several function calls and pops them all at once. -.TP -.B \-fforce\-mem -Force memory operands to be copied into registers before doing -arithmetic on them. This may produce better code by making all -memory references potential common subexpressions. When they are -not common subexpressions, instruction combination should -eliminate the separate register-load. I am interested in hearing -about the difference this makes. -.TP -.B \-fforce\-addr -Force memory address constants to be copied into registers before -doing arithmetic on them. This may produce better code just as -`\|\c -.B \-fforce\-mem\c -\&\|' may. I am interested in hearing about the -difference this makes. -.TP -.B \-fomit\-frame\-pointer -Don't keep the frame pointer in a register for functions that -don't need one. This avoids the instructions to save, set up and -restore frame pointers; it also makes an extra register available -in many functions. \c -.I It also makes debugging impossible on -most machines.\c -\& - -On some machines, such as the Vax, this flag has no effect, because -the standard calling sequence automatically handles the frame pointer -and nothing is saved by pretending it doesn't exist. The -machine-description macro \c -.B FRAME_POINTER_REQUIRED\c -\& controls -whether a target machine supports this flag. -.TP -.B \-finline\-functions -Integrate all simple functions into their callers. The compiler -heuristically decides which functions are simple enough to be worth -integrating in this way. - -If all calls to a given function are integrated, and the function is -declared \c -.B static\c -\&, then GCC normally does not output the function as -assembler code in its own right. -.TP -.B \-fcaller\-saves -Enable values to be allocated in registers that will be clobbered by -function calls, by emitting extra instructions to save and restore the -registers around such calls. Such allocation is done only when it -seems to result in better code than would otherwise be produced. - -This option is enabled by default on certain machines, usually those -which have no call-preserved registers to use instead. -.TP -.B \-fkeep\-inline\-functions -Even if all calls to a given function are integrated, and the function -is declared \c -.B static\c -\&, nevertheless output a separate run-time -callable version of the function. -.TP -.B \-fno\-function\-cse -Do not put function addresses in registers; make each instruction that -calls a constant function contain the function's address explicitly. - -This option results in less efficient code, but some strange hacks -that alter the assembler output may be confused by the optimizations -performed when this option is not used. -.TP -.B \-fno\-peephole -Disable any machine-specific peephole optimizations. -.TP -.B \-ffast-math -This option allows GCC to violate some ANSI or IEEE rules/specifications -in the interest of optimizing code for speed. For example, it allows -the compiler to assume arguments to the \c -.B sqrt\c -\& function are -non-negative numbers. - -This option should never be turned on by any `\|\c -.B \-O\c -\&\|' option since -it can result in incorrect output for programs which depend on -an exact implementation of IEEE or ANSI rules/specifications for -math functions. -.PP - -The following options control specific optimizations. The `\|\c -.B \-O2\c -\&\|' -option turns on all of these optimizations except `\|\c -.B \-funroll\-loops\c -\&\|' -and `\|\c -.B \-funroll\-all\-loops\c -\&\|'. - -The `\|\c -.B \-O\c -\&\|' option usually turns on -the `\|\c -.B \-fthread\-jumps\c -\&\|' and `\|\c -.B \-fdelayed\-branch\c -\&\|' options, but -specific machines may change the default optimizations. - -You can use the following flags in the rare cases when ``fine-tuning'' -of optimizations to be performed is desired. -.TP -.B \-fstrength\-reduce -Perform the optimizations of loop strength reduction and -elimination of iteration variables. -.TP -.B \-fthread\-jumps -Perform optimizations where we check to see if a jump branches to a -location where another comparison subsumed by the first is found. If -so, the first branch is redirected to either the destination of the -second branch or a point immediately following it, depending on whether -the condition is known to be true or false. -.TP -.B \-funroll\-loops -Perform the optimization of loop unrolling. This is only done for loops -whose number of iterations can be determined at compile time or run time. -.TP -.B \-funroll\-all\-loops -Perform the optimization of loop unrolling. This is done for all loops. -This usually makes programs run more slowly. -.TP -.B \-fcse\-follow\-jumps -In common subexpression elimination, scan through jump instructions -when the target of the jump is not reached by any other path. For -example, when CSE encounters an \c -.B if\c -\& statement with an -\c -.B else\c -\& clause, CSE will follow the jump when the condition -tested is false. -.TP -.B \-fcse\-skip\-blocks -This is similar to `\|\c -.B \-fcse\-follow\-jumps\c -\&\|', but causes CSE to -follow jumps which conditionally skip over blocks. When CSE -encounters a simple \c -.B if\c -\& statement with no else clause, -`\|\c -.B \-fcse\-skip\-blocks\c -\&\|' causes CSE to follow the jump around the -body of the \c -.B if\c -\&. -.TP -.B \-frerun\-cse\-after\-loop -Re-run common subexpression elimination after loop optimizations has been -performed. -.TP -.B \-felide\-constructors -Elide constructors when this seems plausible (C++ only). With this -flag, GNU C++ initializes \c -.B y\c -\& directly from the call to \c -.B foo\c -\& -without going through a temporary in the following code: - -.sp -.br -A\ foo\ (); -.br -A\ y\ =\ foo\ (); -.br -.sp - -Without this option, GNU C++ first initializes \c -.B y\c -\& by calling the -appropriate constructor for type \c -.B A\c -\&; then assigns the result of -\c -.B foo\c -\& to a temporary; and, finally, replaces the initial valyue of -`\|\c -.B y\c -\&\|' with the temporary. - -The default behavior (`\|\c -.B \-fno\-elide\-constructors\c -\&\|') is specified by -the draft ANSI C++ standard. If your program's constructors have side -effects, using `\|\c -.B \-felide-constructors\c -\&\|' can make your program act -differently, since some constructor calls may be omitted. -.TP -.B \-fexpensive\-optimizations -Perform a number of minor optimizations that are relatively expensive. -.TP -.B \-fdelayed\-branch -If supported for the target machine, attempt to reorder instructions -to exploit instruction slots available after delayed branch -instructions. -.TP -.B \-fschedule\-insns -If supported for the target machine, attempt to reorder instructions to -eliminate execution stalls due to required data being unavailable. This -helps machines that have slow floating point or memory load instructions -by allowing other instructions to be issued until the result of the load -or floating point instruction is required. -.TP -.B \-fschedule\-insns2 -Similar to `\|\c -.B \-fschedule\-insns\c -\&\|', but requests an additional pass of -instruction scheduling after register allocation has been done. This is -especially useful on machines with a relatively small number of -registers and where memory load instructions take more than one cycle. -.PP - -.SH TARGET OPTIONS -By default, GNU CC compiles code for the same type of machine that you -are using. However, it can also be installed as a cross-compiler, to -compile for some other type of machine. In fact, several different -configurations of GNU CC, for different target machines, can be -installed side by side. Then you specify which one to use with the -`\|\c -.B \-b\c -\&\|' option. - -In addition, older and newer versions of GNU CC can be installed side -by side. One of them (probably the newest) will be the default, but -you may sometimes wish to use another. -.TP -.BI "\-b " "machine"\c -\& -The argument \c -.I machine\c -\& specifies the target machine for compilation. -This is useful when you have installed GNU CC as a cross-compiler. - -The value to use for \c -.I machine\c -\& is the same as was specified as the -machine type when configuring GNU CC as a cross-compiler. For -example, if a cross-compiler was configured with `\|\c -.B configure -i386v\c -\&\|', meaning to compile for an 80386 running System V, then you -would specify `\|\c -.B \-b i386v\c -\&\|' to run that cross compiler. - -When you do not specify `\|\c -.B \-b\c -\&\|', it normally means to compile for -the same type of machine that you are using. -.TP -.BI "\-V " "version"\c -\& -The argument \c -.I version\c -\& specifies which version of GNU CC to run. -This is useful when multiple versions are installed. For example, -\c -.I version\c -\& might be `\|\c -.B 2.0\c -\&\|', meaning to run GNU CC version 2.0. - -The default version, when you do not specify `\|\c -.B \-V\c -\&\|', is controlled -by the way GNU CC is installed. Normally, it will be a version that -is recommended for general use. -.PP - -.SH MACHINE DEPENDENT OPTIONS -Each of the target machine types can have its own special options, -starting with `\|\c -.B \-m\c -\&\|', to choose among various hardware models or -configurations\(em\&for example, 68010 vs 68020, floating coprocessor or -none. A single installed version of the compiler can compile for any -model or configuration, according to the options specified. - -Some configurations of the compiler also support additional special -options, usually for command-line compatibility with other compilers on -the same platform. - -These are the `\|\c -.B \-m\c -\&\|' options defined for the 68000 series: -.TP -.B \-m68000 -.TP -.B \-mc68000 -Generate output for a 68000. This is the default when the compiler is -configured for 68000-based systems. -.TP -.B \-m68020 -.TP -.B \-mc68020 -Generate output for a 68020 (rather than a 68000). This is the -default when the compiler is configured for 68020-based systems. -.TP -.B \-m68881 -Generate output containing 68881 instructions for floating point. -This is the default for most 68020-based systems unless -.B \-nfp -was specified when the compiler was configured. -.TP -.B \-m68030 -Generate output for a 68030. This is the default when the compiler is -configured for 68030-based systems. -.TP -.B \-m68040 -Generate output for a 68040. This is the default when the compiler is -configured for 68040-based systems. -.TP -.B \-m68020\-40 -Generate output for a 68040, without using any of the new instructions. -This results in code which can run relatively efficiently on either a -68020/68881 or a 68030 or a 68040. -.TP -.B \-mfpa -Generate output containing Sun FPA instructions for floating point. -.TP -.B \-msoft\-float -Generate output containing library calls for floating point. -.I -WARNING: -the requisite libraries are not part of GNU CC. Normally the -facilities of the machine's usual C compiler are used, but this can't -be done directly in cross-compilation. You must make your own -arrangements to provide suitable library functions for cross-compilation. -.TP -.B \-mshort -Consider type \c -.B int\c -\& to be 16 bits wide, like \c -.B short int\c -\&. -.TP -.B \-mnobitfield -Do not use the bit-field instructions. `\|\c -.B \-m68000\c -\&\|' implies -`\|\c -.B \-mnobitfield\c -\&\|'. -.TP -.B \-mbitfield -Do use the bit-field instructions. `\|\c -.B \-m68020\c -\&\|' implies -`\|\c -.B \-mbitfield\c -\&\|'. This is the default if you use the unmodified -sources. -.TP -.B \-mrtd -Use a different function-calling convention, in which functions -that take a fixed number of arguments return with the \c -.B rtd\c -\& -instruction, which pops their arguments while returning. This -saves one instruction in the caller since there is no need to pop -the arguments there. - -This calling convention is incompatible with the one normally -used on Unix, so you cannot use it if you need to call libraries -compiled with the Unix compiler. - -Also, you must provide function prototypes for all functions that -take variable numbers of arguments (including \c -.B printf\c -\&); -otherwise incorrect code will be generated for calls to those -functions. - -In addition, seriously incorrect code will result if you call a -function with too many arguments. (Normally, extra arguments are -harmlessly ignored.) - -The \c -.B rtd\c -\& instruction is supported by the 68010 and 68020 -processors, but not by the 68000. -.PP - -These `\|\c -.B \-m\c -\&\|' options are defined for the Vax: -.TP -.B \-munix -Do not output certain jump instructions (\c -.B aobleq\c -\& and so on) -that the Unix assembler for the Vax cannot handle across long -ranges. -.TP -.B \-mgnu -Do output those jump instructions, on the assumption that you -will assemble with the GNU assembler. -.TP -.B \-mg -Output code for g-format floating point numbers instead of d-format. -.PP - -These `\|\c -.B \-m\c -\&\|' switches are supported on the SPARC: - -.PP -.B \-mfpu -.TP -.B \-mhard\-float -Generate output containing floating point instructions. This is the -default. -.PP -.B \-mno\-fpu -.TP -.B \-msoft\-float -Generate output containing library calls for floating point. -.I Warning: -there is no GNU floating-point library for SPARC. -Normally the facilities of the machine's usual C compiler are used, but -this cannot be done directly in cross-compilation. You must make your -own arrangements to provide suitable library functions for -cross-compilation. - -.B \-msoft\-float -changes the calling convention in the output file; -therefore, it is only useful if you compile -.I all -of a program with this option. -.PP -.B \-mno\-epilogue -.TP -.B \-mepilogue -With -.B \-mepilogue -(the default), the compiler always emits code for -function exit at the end of each function. Any function exit in -the middle of the function (such as a return statement in C) will -generate a jump to the exit code at the end of the function. - -With -.BR \-mno\-epilogue , -the compiler tries to emit exit code inline at every function exit. -.PP -.B \-mv8 -.TP -.B \-msparclite -These two options select variations on the SPARC architecture. - -By default (unless specifically configured for the Fujitsu SPARClite), -GCC generates code for the v7 variant of the SPARC architecture. - -.B \-mv8 -will give you SPARC v8 code. The only difference from v7 -code is that the compiler emits the integer multiply and integer -divide instructions which exist in SPARC v8 but not in SPARC v7. - -.B \-msparclite -will give you SPARClite code. This adds the integer -multiply, integer divide step and scan (ffs) instructions which -exist in SPARClite but not in SPARC v7. -.PP - -These `\|\c -.B \-m\c -\&\|' options are defined for the Convex: -.TP -.B \-mc1 -Generate output for a C1. This is the default when the compiler is -configured for a C1. -.TP -.B \-mc2 -Generate output for a C2. This is the default when the compiler is -configured for a C2. -.TP -.B \-margcount -Generate code which puts an argument count in the word preceding each -argument list. Some nonportable Convex and Vax programs need this word. -(Debuggers don't, except for functions with variable-length argument -lists; this info is in the symbol table.) -.TP -.B \-mnoargcount -Omit the argument count word. This is the default if you use the -unmodified sources. -.PP - -These `\|\c -.B \-m\c -\&\|' options are defined for the AMD Am29000: -.TP -.B \-mdw -Generate code that assumes the DW bit is set, i.e., that byte and -halfword operations are directly supported by the hardware. This is the -default. -.TP -.B \-mnodw -Generate code that assumes the DW bit is not set. -.TP -.B \-mbw -Generate code that assumes the system supports byte and halfword write -operations. This is the default. -.TP -.B \-mnbw -Generate code that assumes the systems does not support byte and -halfword write operations. This implies `\|\c -.B \-mnodw\c -\&\|'. -.TP -.B \-msmall -Use a small memory model that assumes that all function addresses are -either within a single 256 KB segment or at an absolute address of less -than 256K. This allows the \c -.B call\c -\& instruction to be used instead -of a \c -.B const\c -\&, \c -.B consth\c -\&, \c -.B calli\c -\& sequence. -.TP -.B \-mlarge -Do not assume that the \c -.B call\c -\& instruction can be used; this is the -default. -.TP -.B \-m29050 -Generate code for the Am29050. -.TP -.B \-m29000 -Generate code for the Am29000. This is the default. -.TP -.B \-mkernel\-registers -Generate references to registers \c -.B gr64-gr95\c -\& instead of -\c -.B gr96-gr127\c -\&. This option can be used when compiling kernel code -that wants a set of global registers disjoint from that used by -user-mode code. - -Note that when this option is used, register names in `\|\c -.B \-f\c -\&\|' flags -must use the normal, user-mode, names. -.TP -.B \-muser\-registers -Use the normal set of global registers, \c -.B gr96-gr127\c -\&. This is the -default. -.TP -.B \-mstack\-check -Insert a call to \c -.B __msp_check\c -\& after each stack adjustment. This -is often used for kernel code. -.PP - -These `\|\c -.B \-m\c -\&\|' options are defined for Motorola 88K architectures: -.TP -.B \-m88000 -Generate code that works well on both the m88100 and the -m88110. -.TP -.B \-m88100 -Generate code that works best for the m88100, but that also -runs on the m88110. -.TP -.B \-m88110 -Generate code that works best for the m88110, and may not run -on the m88100. -.TP -.B \-midentify\-revision -Include an \c -.B ident\c -\& directive in the assembler output recording the -source file name, compiler name and version, timestamp, and compilation -flags used. -.TP -.B \-mno\-underscores -In assembler output, emit symbol names without adding an underscore -character at the beginning of each name. The default is to use an -underscore as prefix on each name. -.TP -.B \-mno\-check\-zero\-division -.TP -.B \-mcheck\-zero\-division -Early models of the 88K architecture had problems with division by zero; -in particular, many of them didn't trap. Use these options to avoid -including (or to include explicitly) additional code to detect division -by zero and signal an exception. All GCC configurations for the 88K use -`\|\c -.B \-mcheck\-zero\-division\c -\&\|' by default. -.TP -.B \-mocs\-debug\-info -.TP -.B \-mno\-ocs\-debug\-info -Include (or omit) additional debugging information (about -registers used in each stack frame) as specified in the 88Open Object -Compatibility Standard, ``OCS''. This extra information is not needed -by GDB. The default for DG/UX, SVr4, and Delta 88 SVr3.2 is to -include this information; other 88k configurations omit this information -by default. -.TP -.B \-mocs\-frame\-position -.TP -.B \-mno\-ocs\-frame\-position -Force (or do not require) register values to be stored in a particular -place in stack frames, as specified in OCS. The DG/UX, Delta88 SVr3.2, -and BCS configurations use `\|\c -.B \-mocs\-frame\-position\c -\&\|'; other 88k -configurations have the default `\|\c -.B \-mno\-ocs\-frame\-position\c -\&\|'. -.TP -.B \-moptimize\-arg\-area -.TP -.B \-mno\-optimize\-arg\-area -Control how to store function arguments in stack frames. -`\|\c -.B \-moptimize\-arg\-area\c -\&\|' saves space, but may break some -debuggers (not GDB). `\|\c -.B \-mno\-optimize\-arg\-area\c -\&\|' conforms better to -standards. By default GCC does not optimize the argument area. -.TP -.BI "\-mshort\-data\-" "num"\c -\& -.I num\c -\& -Generate smaller data references by making them relative to \c -.B r0\c -\&, -which allows loading a value using a single instruction (rather than the -usual two). You control which data references are affected by -specifying \c -.I num\c -\& with this option. For example, if you specify -`\|\c -.B \-mshort\-data\-512\c -\&\|', then the data references affected are those -involving displacements of less than 512 bytes. -`\|\c -.B \-mshort\-data\-\c -.I num\c -\&\c -\&\|' is not effective for \c -.I num\c -\& greater -than 64K. -.PP -.B \-mserialize-volatile -.TP -.B \-mno-serialize-volatile -Do, or do not, generate code to guarantee sequential consistency of -volatile memory references. - -GNU CC always guarantees consistency by default, for the preferred -processor submodel. How this is done depends on the submodel. - -The m88100 processor does not reorder memory references and so always -provides sequential consistency. If you use `\|\c -.B \-m88100\c -\&\|', GNU CC does -not generate any special instructions for sequential consistency. - -The order of memory references made by the m88110 processor does not -always match the order of the instructions requesting those references. -In particular, a load instruction may execute before a preceding store -instruction. Such reordering violates sequential consistency of -volatile memory references, when there are multiple processors. When -you use `\|\c -.B \-m88000\c -\&\|' or `\|\c -.B \-m88110\c -\&\|', GNU CC generates special -instructions when appropriate, to force execution in the proper order. - -The extra code generated to guarantee consistency may affect the -performance of your application. If you know that you can safely forgo -this guarantee, you may use the option `\|\c -.B \-mno-serialize-volatile\c -\&\|'. - -If you use the `\|\c -.B \-m88100\c -\&\|' option but require sequential consistency -when running on the m88110 processor, you should use -`\|\c -.B \-mserialize-volatile\c -\&\|'. -.PP -.B \-msvr4 -.TP -.B \-msvr3 -Turn on (`\|\c -.B \-msvr4\c -\&\|') or off (`\|\c -.B \-msvr3\c -\&\|') compiler extensions -related to System V release 4 (SVr4). This controls the following: -.TP -\ \ \ \(bu -Which variant of the assembler syntax to emit (which you can select -independently using `\|\c -.B \-mversion\-03.00\c -\&\|'). -.TP -\ \ \ \(bu -`\|\c -.B \-msvr4\c -\&\|' makes the C preprocessor recognize `\|\c -.B #pragma weak\c -\&\|' -.TP -\ \ \ \(bu -`\|\c -.B \-msvr4\c -\&\|' makes GCC issue additional declaration directives used in -SVr4. -.PP -`\|\c -.B \-msvr3\c -\&\|' is the default for all m88K configurations except -the SVr4 configuration. -.TP -.B \-mtrap\-large\-shift -.TP -.B \-mhandle\-large\-shift -Include code to detect bit-shifts of more than 31 bits; respectively, -trap such shifts or emit code to handle them properly. By default GCC -makes no special provision for large bit shifts. -.TP -.B \-muse\-div\-instruction -Very early models of the 88K architecture didn't have a divide -instruction, so GCC avoids that instruction by default. Use this option -to specify that it's safe to use the divide instruction. -.TP -.B \-mversion\-03.00 -In the DG/UX configuration, there are two flavors of SVr4. This option -modifies -.B \-msvr4 -to select whether the hybrid-COFF or real-ELF -flavor is used. All other configurations ignore this option. -.TP -.B \-mwarn\-passed\-structs -Warn when a function passes a struct as an argument or result. -Structure-passing conventions have changed during the evolution of the C -language, and are often the source of portability problems. By default, -GCC issues no such warning. -.PP -These options are defined for the IBM RS6000: - -.PP -.B \-mfp\-in\-toc -.TP -.B \-mno\-fp\-in\-toc -Control whether or not floating-point constants go in the Table of -Contents (TOC), a table of all global variable and function addresses. By -default GCC puts floating-point constants there; if the TOC overflows, -`\|\c -.B \-mno\-fp\-in\-toc\c -\&\|' will reduce the size of the TOC, which may avoid -the overflow. - -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the IBM RT PC: -.TP -.B \-min\-line\-mul -Use an in-line code sequence for integer multiplies. This is the -default. -.TP -.B \-mcall\-lib\-mul -Call \c -.B lmul$$\c -\& for integer multiples. -.TP -.B \-mfull\-fp\-blocks -Generate full-size floating point data blocks, including the minimum -amount of scratch space recommended by IBM. This is the default. -.TP -.B \-mminimum\-fp\-blocks -Do not include extra scratch space in floating point data blocks. This -results in smaller code, but slower execution, since scratch space must -be allocated dynamically. -.TP -.B \-mfp\-arg\-in\-fpregs -Use a calling sequence incompatible with the IBM calling convention in -which floating point arguments are passed in floating point registers. -Note that \c -.B varargs.h\c -\& and \c -.B stdargs.h\c -\& will not work with -floating point operands if this option is specified. -.TP -.B \-mfp\-arg\-in\-gregs -Use the normal calling convention for floating point arguments. This is -the default. -.TP -.B \-mhc\-struct\-return -Return structures of more than one word in memory, rather than in a -register. This provides compatibility with the MetaWare HighC (hc) -compiler. Use `\|\c -.B \-fpcc\-struct\-return\c -\&\|' for compatibility with the -Portable C Compiler (pcc). -.TP -.B \-mnohc\-struct\-return -Return some structures of more than one word in registers, when -convenient. This is the default. For compatibility with the -IBM-supplied compilers, use either `\|\c -.B \-fpcc\-struct\-return\c -\&\|' or -`\|\c -.B \-mhc\-struct\-return\c -\&\|'. -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the MIPS family of computers: -.TP -.BI "\-mcpu=" "cpu-type" -Assume the defaults for the machine type -.I cpu-type -when -scheduling instructions. The default -.I cpu-type -is -.BR default , -which picks the longest cycles times for any of the machines, in order -that the code run at reasonable rates on all MIPS cpu's. Other -choices for -.I cpu-type -are -.BR r2000 , -.BR r3000 , -.BR r4000 , -and -.BR r6000 . -While picking a specific -.I cpu-type -will schedule things appropriately for that particular chip, the -compiler will not generate any code that does not meet level 1 of the -MIPS ISA (instruction set architecture) without the -.B \-mips2 -or -.B \-mips3 -switches being used. -.TP -.B \-mips2 -Issue instructions from level 2 of the MIPS ISA (branch likely, square -root instructions). The -.B \-mcpu=r4000 -or -.B \-mcpu=r6000 -switch must be used in conjunction with -.BR \-mips2 . -.TP -.B \-mips3 -Issue instructions from level 3 of the MIPS ISA (64 bit instructions). -The -.B \-mcpu=r4000 -switch must be used in conjunction with -.BR \-mips2 . -.TP -.B \-mint64 -.TP -.B \-mlong64 -.TP -.B \-mlonglong128 -These options don't work at present. -.TP -.B \-mmips\-as -Generate code for the MIPS assembler, and invoke -.B mips\-tfile -to add normal debug information. This is the default for all -platforms except for the OSF/1 reference platform, using the OSF/rose -object format. If any of the -.BR \-ggdb , -.BR \-gstabs , -or -.B \-gstabs+ -switches are used, the -.B mips\-tfile -program will encapsulate the stabs within MIPS ECOFF. -.TP -.B \-mgas -Generate code for the GNU assembler. This is the default on the OSF/1 -reference platform, using the OSF/rose object format. -.TP -.B \-mrnames -.TP -.B \-mno\-rnames -The -.B \-mrnames -switch says to output code using the MIPS software names for the -registers, instead of the hardware names (ie, -.B a0 -instead of -.BR $4 ). -The GNU assembler does not support the -.B \-mrnames -switch, and the MIPS assembler will be instructed to run the MIPS C -preprocessor over the source file. The -.B \-mno\-rnames -switch is default. -.TP -.B \-mgpopt -.TP -.B \-mno\-gpopt -The -.B \-mgpopt -switch says to write all of the data declarations before the -instructions in the text section, to all the MIPS assembler to -generate one word memory references instead of using two words for -short global or static data items. This is on by default if -optimization is selected. -.TP -.B \-mstats -.TP -.B \-mno\-stats -For each non-inline function processed, the -.B \-mstats -switch causes the compiler to emit one line to the standard error file -to print statistics about the program (number of registers saved, -stack size, etc.). -.TP -.B \-mmemcpy -.TP -.B \-mno\-memcpy -The -.B \-mmemcpy -switch makes all block moves call the appropriate string function -.RB ( memcpy -or -.BR bcopy ) -instead of possibly generating inline code. -.TP -.B \-mmips\-tfile -.TP -.B \-mno\-mips\-tfile -The -.B \-mno\-mips\-tfile -switch causes the compiler not postprocess the object file with the -.B mips\-tfile -program, after the MIPS assembler has generated it to add debug -support. If -.B mips\-tfile -is not run, then no local variables will be available to the debugger. -In addition, -.B stage2 -and -.B stage3 -objects will have the temporary file names passed to the assembler -embedded in the object file, which means the objects will not compare -the same. -.TP -.B \-msoft\-float -Generate output containing library calls for floating point. -.I -WARNING: -the requisite libraries are not part of GNU CC. Normally the -facilities of the machine's usual C compiler are used, but this can't -be done directly in cross-compilation. You must make your own -arrangements to provide suitable library functions for cross-compilation. -.TP -.B \-mhard\-float -Generate output containing floating point instructions. This is the -default if you use the unmodified sources. -.TP -.B \-mfp64 -Assume that the -.B FR -bit in the status word is on, and that there are 32 64-bit floating -point registers, instead of 32 32-bit floating point registers. You -must also specify the -.B \-mcpu=r4000 -and -.B \-mips3 -switches. -.TP -.B \-mfp32 -Assume that there are 32 32-bit floating point registers. This is the -default. -.PP -.B \-mabicalls -.TP -.B \-mno\-abicalls -Emit (or do not emit) the -.BR \&.abicalls , -.BR \&.cpload , -and -.B \&.cprestore -pseudo operations that some System V.4 ports use for position -independent code. -.TP -.B \-mhalf\-pic -.TP -.B \-mno\-half\-pic -The -.B \-mhalf\-pic -switch says to put pointers to extern references into the data section -and load them up, rather than put the references in the text section. -This option does not work at present. -.B -.BI \-G num -Put global and static items less than or equal to -.I num -bytes into the small data or bss sections instead of the normal data -or bss section. This allows the assembler to emit one word memory -reference instructions based on the global pointer -.RB ( gp -or -.BR $28 ), -instead of the normal two words used. By default, -.I num -is 8 when the MIPS assembler is used, and 0 when the GNU -assembler is used. The -.BI \-G num -switch is also passed to the assembler and linker. All modules should -be compiled with the same -.BI \-G num -value. -.TP -.B \-nocpp -Tell the MIPS assembler to not run it's preprocessor over user -assembler files (with a `\|\c -.B .s\c -\&\|' suffix) when assembling them. -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the Intel 80386 family of computers: - -.B \-m486 -.TP -.B \-mno\-486 -Control whether or not code is optimized for a 486 instead of an -386. Code generated for a 486 will run on a 386 and vice versa. -.TP -.B \-msoft\-float -Generate output containing library calls for floating point. -.I Warning: -the requisite libraries are not part of GNU CC. -Normally the facilities of the machine's usual C compiler are used, but -this can't be done directly in cross-compilation. You must make your -own arrangements to provide suitable library functions for -cross-compilation. - -On machines where a function returns floating point results in the 80387 -register stack, some floating point opcodes may be emitted even if -`\|\c -.B \-msoft-float\c -\&\|' is used. -.TP -.B \-mno-fp-ret-in-387 -Do not use the FPU registers for return values of functions. - -The usual calling convention has functions return values of types -\c -.B float\c -\& and \c -.B double\c -\& in an FPU register, even if there -is no FPU. The idea is that the operating system should emulate -an FPU. - -The option `\|\c -.B \-mno-fp-ret-in-387\c -\&\|' causes such values to be returned -in ordinary CPU registers instead. -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the HPPA family of computers: -.TP -.B \-mpa-risc-1-0 -Generate code for a PA 1.0 processor. -.TP -.B \-mpa-risc-1-1 -Generate code for a PA 1.1 processor. -.TP -.B \-mkernel -Generate code which is suitable for use in kernels. Specifically, avoid -\c -.B add\c -\& instructions in which one of the arguments is the DP register; -generate \c -.B addil\c -\& instructions instead. This avoids a rather serious -bug in the HP-UX linker. -.TP -.B \-mshared-libs -Generate code that can be linked against HP-UX shared libraries. This option -is not fully function yet, and is not on by default for any PA target. Using -this option can cause incorrect code to be generated by the compiler. -.TP -.B \-mno-shared-libs -Don't generate code that will be linked against shared libraries. This is -the default for all PA targets. -.TP -.B \-mlong-calls -Generate code which allows calls to functions greater than 256K away from -the caller when the caller and callee are in the same source file. Do -not turn this option on unless code refuses to link with "branch out of -range errors" from the linker. -.TP -.B \-mdisable-fpregs -Prevent floating point registers from being used in any manner. This is -necessary for compiling kernels which perform lazy context switching of -floating point registers. If you use this option and attempt to perform -floating point operations, the compiler will abort. -.TP -.B \-mdisable-indexing -Prevent the compiler from using indexing address modes. This avoids some -rather obscure problems when compiling MIG generated code under MACH. -.TP -.B \-mtrailing-colon -Add a colon to the end of label definitions (for ELF assemblers). -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the Intel 80960 family of computers: -.TP -.BI "\-m" "cpu-type" -Assume the defaults for the machine type -.I cpu-type -for instruction and addressing-mode availability and alignment. -The default -.I cpu-type -is -.BR kb ; -other choices are -.BR ka , -.BR mc , -.BR ca , -.BR cf , -.BR sa , -and -.BR sb . -.TP -.B \-mnumerics -.TP -.B \-msoft\-float -The -.B \-mnumerics -option indicates that the processor does support -floating-point instructions. The -.B \-msoft\-float -option indicates -that floating-point support should not be assumed. -.TP -.B \-mleaf\-procedures -.TP -.B \-mno\-leaf\-procedures -Do (or do not) attempt to alter leaf procedures to be callable with the -.I bal -instruction as well as -.IR call . -This will result in more -efficient code for explicit calls when the -.I bal -instruction can be -substituted by the assembler or linker, but less efficient code in other -cases, such as calls via function pointers, or using a linker that doesn't -support this optimization. -.TP -.B \-mtail\-call -.TP -.B \-mno\-tail\-call -Do (or do not) make additional attempts (beyond those of the -machine-independent portions of the compiler) to optimize tail-recursive -calls into branches. You may not want to do this because the detection of -cases where this is not valid is not totally complete. The default is -.BR \-mno\-tail\-call . -.TP -.B \-mcomplex\-addr -.TP -.B \-mno\-complex\-addr -Assume (or do not assume) that the use of a complex addressing mode is a -win on this implementation of the i960. Complex addressing modes may not -be worthwhile on the K-series, but they definitely are on the C-series. -The default is currently -.B \-mcomplex\-addr -for all processors except -the CB and CC. -.TP -.B \-mcode\-align -.TP -.B \-mno\-code\-align -Align code to 8-byte boundaries for faster fetching (or don't bother). -Currently turned on by default for C-series implementations only. -.TP -.B \-mic\-compat -.TP -.B \-mic2.0\-compat -.TP -.B \-mic3.0\-compat -Enable compatibility with iC960 v2.0 or v3.0. -.TP -.B \-masm\-compat -.TP -.B \-mintel\-asm -Enable compatibility with the iC960 assembler. -.TP -.B \-mstrict\-align -.TP -.B \-mno\-strict\-align -Do not permit (do permit) unaligned accesses. -.TP -.B \-mold\-align -Enable structure-alignment compatibility with Intel's gcc release version -1.3 (based on gcc 1.37). Currently this is buggy in that -.B #pragma align 1 -is always assumed as well, and cannot be turned off. -.PP -These `\|\c -.B \-m\c -\&\|' options are defined for the DEC Alpha implementations: -.TP -.B \-mno-soft-float -.TP -.B \-msoft-float -Use (do not use) the hardware floating-point instructions for -floating-point operations. When \c -.B \-msoft-float\c -\& is specified, -functions in `\|\c -.B libgcc1.c\c -\&\|' will be used to perform floating-point -operations. Unless they are replaced by routines that emulate the -floating-point operations, or compiled in such a way as to call such -emulations routines, these routines will issue floating-point -operations. If you are compiling for an Alpha without floating-point -operations, you must ensure that the library is built so as not to call -them. - -Note that Alpha implementations without floating-point operations are -required to have floating-point registers. -.TP -.B \-mfp-reg -.TP -.B \-mno-fp-regs -Generate code that uses (does not use) the floating-point register set. -.B \-mno-fp-regs\c -\& implies \c -.B \-msoft-float\c -\&. If the floating-point -register set is not used, floating point operands are passed in integer -registers as if they were integers and floating-point results are passed -in $0 instead of $f0. This is a non-standard calling sequence, so any -function with a floating-point argument or return value called by code -compiled with \c -.B \-mno-fp-regs\c -\& must also be compiled with that -option. - -A typical use of this option is building a kernel that does not use, -and hence need not save and restore, any floating-point registers. -.PP -These additional options are available on System V Release 4 for -compatibility with other compilers on those systems: -.TP -.B \-G -On SVr4 systems, \c -.B gcc\c -\& accepts the option `\|\c -.B \-G\c -\&\|' (and passes -it to the system linker), for compatibility with other compilers. -However, we suggest you use `\|\c -.B \-symbolic\c -\&\|' or `\|\c -.B \-shared\c -\&\|' as -appropriate, instead of supplying linker options on the \c -.B gcc\c -\& -command line. -.TP -.B \-Qy -Identify the versions of each tool used by the compiler, in a -\c -.B .ident\c -\& assembler directive in the output. -.TP -.B \-Qn -Refrain from adding \c -.B .ident\c -\& directives to the output file (this is -the default). -.TP -.BI "-YP," "dirs"\c -\& -Search the directories \c -.I dirs\c -\&, and no others, for libraries -specified with `\|\c -.B \-l\c -\&\|'. You can separate directory entries in -\c -.I dirs\c -\& from one another with colons. -.TP -.BI "-Ym," "dir"\c -\& -Look in the directory \c -.I dir\c -\& to find the M4 preprocessor. -The assembler uses this option. -.PP - -.SH CODE GENERATION OPTIONS -These machine-independent options control the interface conventions -used in code generation. - -Most of them begin with `\|\c -\-f\c -\&\|'. These options have both positive and negative forms; the negative form -of `\|\c -.B \-ffoo\c -\&\|' would be `\|\c -.B \-fno\-foo\c -\&\|'. In the table below, only -one of the forms is listed\(em\&the one which is not the default. You -can figure out the other form by either removing `\|\c -.B no\-\c -\&\|' or adding -it. -.TP -.B \-fnonnull\-objects -Assume that objects reached through references are not null -(C++ only). - -Normally, GNU C++ makes conservative assumptions about objects reached -through references. For example, the compiler must check that \c -.B a\c -\& -is not null in code like the following: - -.sp -.br -obj\ &a\ =\ g\ (); -.br -a.f\ (2); -.br -.sp - -Checking that references of this sort have non-null values requires -extra code, however, and it is unnecessary for many programs. You can -use `\|\c -.B \-fnonnull-objects\c -\&\|' to omit the checks for null, if your -program doesn't require checking. -.TP -.B \-fpcc\-struct\-return -Use the same convention for returning \c -.B struct\c -\& and \c -.B union\c -\& -values that is used by the usual C compiler on your system. This -convention is less efficient for small structures, and on many -machines it fails to be reentrant; but it has the advantage of -allowing intercallability between GCC-compiled code and PCC-compiled -code. -.TP -.B \-freg\-struct\-return -Use the convention that -.B struct -and -.B union -values are returned in registers when possible. This is more -efficient for small structures than -.BR \-fpcc\-struct\-return . - -If you specify neither -.B \-fpcc\-struct\-return -nor -.BR \-freg\-struct\-return , -GNU CC defaults to whichever convention is standard for the target. -If there is no standard convention, GNU CC defaults to -.BR \-fpcc\-struct\-return . -.TP -.B \-fshort\-enums -Allocate to an \c -.B enum\c -\& type only as many bytes as it needs for the -declared range of possible values. Specifically, the \c -.B enum\c -\& type -will be equivalent to the smallest integer type which has enough room. -.TP -.B \-fshort\-double -Use the same size for -.B double -as for -.B float -\&. -.TP -.B \-fshared\-data -Requests that the data and non-\c -.B const\c -\& variables of this -compilation be shared data rather than private data. The distinction -makes sense only on certain operating systems, where shared data is -shared between processes running the same program, while private data -exists in one copy per process. -.TP -.B \-fno\-common -Allocate even uninitialized global variables in the bss section of the -object file, rather than generating them as common blocks. This has the -effect that if the same variable is declared (without \c -.B extern\c -\&) in -two different compilations, you will get an error when you link them. -The only reason this might be useful is if you wish to verify that the -program will work on other systems which always work this way. -.TP -.B \-fno\-ident -Ignore the `\|\c -.B #ident\c -\&\|' directive. -.TP -.B \-fno\-gnu\-linker -Do not output global initializations (such as C++ constructors and -destructors) in the form used by the GNU linker (on systems where the GNU -linker is the standard method of handling them). Use this option when -you want to use a non-GNU linker, which also requires using the -\c -.B collect2\c -\& program to make sure the system linker includes -constructors and destructors. (\c -.B collect2\c -\& is included in the GNU CC -distribution.) For systems which \c -.I must\c -\& use \c -.B collect2\c -\&, the -compiler driver \c -.B gcc\c -\& is configured to do this automatically. -.TP -.B \-finhibit-size-directive -Don't output a \c -.B .size\c -\& assembler directive, or anything else that -would cause trouble if the function is split in the middle, and the -two halves are placed at locations far apart in memory. This option is -used when compiling `\|\c -.B crtstuff.c\c -\&\|'; you should not need to use it -for anything else. -.TP -.B \-fverbose-asm -Put extra commentary information in the generated assembly code to -make it more readable. This option is generally only of use to those -who actually need to read the generated assembly code (perhaps while -debugging the compiler itself). -.TP -.B \-fvolatile -Consider all memory references through pointers to be volatile. -.TP -.B \-fvolatile\-global -Consider all memory references to extern and global data items to -be volatile. -.TP -.B \-fpic -If supported for the target machines, generate position-independent code, -suitable for use in a shared library. -.TP -.B \-fPIC -If supported for the target machine, emit position-independent code, -suitable for dynamic linking, even if branches need large displacements. -.TP -.BI "\-ffixed\-" "reg"\c -\& -Treat the register named \c -.I reg\c -\& as a fixed register; generated code -should never refer to it (except perhaps as a stack pointer, frame -pointer or in some other fixed role). - -\c -.I reg\c -\& must be the name of a register. The register names accepted -are machine-specific and are defined in the \c -.B REGISTER_NAMES\c -\& -macro in the machine description macro file. - -This flag does not have a negative form, because it specifies a -three-way choice. -.TP -.BI "\-fcall\-used\-" "reg"\c -\& -Treat the register named \c -.I reg\c -\& as an allocatable register that is -clobbered by function calls. It may be allocated for temporaries or -variables that do not live across a call. Functions compiled this way -will not save and restore the register \c -.I reg\c -\&. - -Use of this flag for a register that has a fixed pervasive role in the -machine's execution model, such as the stack pointer or frame pointer, -will produce disastrous results. - -This flag does not have a negative form, because it specifies a -three-way choice. -.TP -.BI "\-fcall\-saved\-" "reg"\c -\& -Treat the register named \c -.I reg\c -\& as an allocatable register saved by -functions. It may be allocated even for temporaries or variables that -live across a call. Functions compiled this way will save and restore -the register \c -.I reg\c -\& if they use it. - -Use of this flag for a register that has a fixed pervasive role in the -machine's execution model, such as the stack pointer or frame pointer, -will produce disastrous results. - -A different sort of disaster will result from the use of this flag for -a register in which function values may be returned. - -This flag does not have a negative form, because it specifies a -three-way choice. -.PP - -.SH PRAGMAS -Two `\|\c -.B #pragma\c -\&\|' directives are supported for GNU C++, to permit using the same -header file for two purposes: as a definition of interfaces to a given -object class, and as the full definition of the contents of that object class. -.TP -.B #pragma interface -(C++ only.) -Use this directive in header files that define object classes, to save -space in most of the object files that use those classes. Normally, -local copies of certain information (backup copies of inline member -functions, debugging information, and the internal tables that -implement virtual functions) must be kept in each object file that -includes class definitions. You can use this pragma to avoid such -duplication. When a header file containing `\|\c -.B #pragma interface\c -\&\|' is included in a compilation, this auxiliary information -will not be generated (unless the main input source file itself uses -`\|\c -.B #pragma implementation\c -\&\|'). Instead, the object files will contain references to be -resolved at link time. -.tr !" -.TP -.B #pragma implementation -.TP -.BI "#pragma implementation !" objects .h! -(C++ only.) -Use this pragma in a main input file, when you want full output from -included header files to be generated (and made globally visible). -The included header file, in turn, should use `\|\c -.B #pragma interface\c -\&\|'. -Backup copies of inline member functions, debugging information, and -the internal tables used to implement virtual functions are all -generated in implementation files. - -If you use `\|\c -.B #pragma implementation\c -\&\|' with no argument, it applies to an include file with the same -basename as your source file; for example, in `\|\c -.B allclass.cc\c -\&\|', `\|\c -.B #pragma implementation\c -\&\|' by itself is equivalent to `\|\c -.B -#pragma implementation "allclass.h"\c -\&\|'. Use the string argument if you want a single implementation -file to include code from multiple header files. - -There is no way to split up the contents of a single header file into -multiple implementation files. -.SH FILES -.ta \w'LIBDIR/g++\-include 'u -file.c C source file -.br -file.h C header (preprocessor) file -.br -file.i preprocessed C source file -.br -file.C C++ source file -.br -file.cc C++ source file -.br -file.cxx C++ source file -.br -file.m Objective-C source file -.br -file.s assembly language file -.br -file.o object file -.br -a.out link edited output -.br -\fITMPDIR\fR/cc\(** temporary files -.br -\fILIBDIR\fR/cpp preprocessor -.br -\fILIBDIR\fR/cc1 compiler for C -.br -\fILIBDIR\fR/cc1plus compiler for C++ -.br -\fILIBDIR\fR/collect linker front end needed on some machines -.br -\fILIBDIR\fR/libgcc.a GCC subroutine library -.br -/lib/crt[01n].o start-up routine -.br -\fILIBDIR\fR/ccrt0 additional start-up routine for C++ -.br -/lib/libc.a standard C library, see -.IR intro (3) -.br -/usr/include standard directory for -.B #include -files -.br -\fILIBDIR\fR/include standard gcc directory for -.B #include -files -.br -\fILIBDIR\fR/g++\-include additional g++ directory for -.B #include -.sp -.I LIBDIR -is usually -.B /usr/local/lib/\c -.IR machine / version . -.br -.I TMPDIR -comes from the environment variable -.B TMPDIR -(default -.B /usr/tmp -if available, else -.B /tmp\c -\&). -.SH "SEE ALSO" -cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). -.br -.RB "`\|" gcc "\|', `\|" cpp \|', -.RB `\| as \|', `\| ld \|', -and -.RB `\| gdb \|' -entries in -.B info\c -\&. -.br -.I -Using and Porting GNU CC (for version 2.0)\c -, Richard M. Stallman; -.I -The C Preprocessor\c -, Richard M. Stallman; -.I -Debugging with GDB: the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch; -.I -Using as: the GNU Assembler\c -, Dean Elsner, Jay Fenlason & friends; -.I -ld: the GNU linker\c -, Steve Chamberlain and Roland Pesch. - -.SH BUGS -For instructions on reporting bugs, see the GCC manual. - -.SH COPYING -Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc. -.PP -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. -.SH AUTHORS -See the GNU CC Manual for the contributors to GNU CC. diff --git a/gnu/usr.bin/gcc2/cc/gcc.c b/gnu/usr.bin/gcc2/cc/gcc.c deleted file mode 100644 index 128e746b551..00000000000 --- a/gnu/usr.bin/gcc2/cc/gcc.c +++ /dev/null @@ -1,4254 +0,0 @@ -/* Compiler driver program that can handle many languages. - Copyright (C) 1987, 1989, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. - -This paragraph is here to try to keep Sun CC from dying. -The number of chars here seems crucial!!!! */ - -#ifndef lint -static char rcsid[] = "$Id: gcc.c,v 1.1.1.1 1995/10/18 08:39:26 deraadt Exp $"; -#endif /* not lint */ - -/* This program is the user interface to the C compiler and possibly to -other compilers. It is used because compilation is a complicated procedure -which involves running several programs and passing temporary files between -them, forwarding the users switches to those programs selectively, -and deleting the temporary files at the end. - -CC recognizes how to compile each input file by suffixes in the file names. -Once it knows which kind of compilation to perform, the procedure for -compilation is specified by a string called a "spec". */ - -#include -#include -#include -#include -#include /* May get R_OK, etc. on some systems. */ - -#include "config.h" -#include "obstack.h" -#include "gvarargs.h" -#include - -#ifndef R_OK -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#endif - -/* Define a generic NULL if one hasn't already been defined. */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef GENERIC_PTR -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define GENERIC_PTR void * -#else -#define GENERIC_PTR char * -#endif -#endif - -#ifndef NULL_PTR -#define NULL_PTR ((GENERIC_PTR)0) -#endif - -#ifdef USG -#define vfork fork -#endif /* USG */ - -/* On MSDOS, write temp files in current dir - because there's no place else we can expect to use. */ -#if __MSDOS__ -#ifndef P_tmpdir -#define P_tmpdir "./" -#endif -#endif - -/* NetBSD defines P_tmpdir for standards compatibility. - However, it shouldn't be used. */ -#ifdef __NetBSD__ -#undef P_tmpdir -#endif - -/* Test if something is a normal file. */ -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -/* Test if something is a directory. */ -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -/* By default there is no special suffix for executables. */ -#ifndef EXECUTABLE_SUFFIX -#define EXECUTABLE_SUFFIX "" -#endif - -/* By default, colon separates directories in a path. */ -#ifndef PATH_SEPARATOR -#define PATH_SEPARATOR ':' -#endif - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void free (); -extern char *getenv (); - -extern int errno; - -extern int execv (), execvp (); - -/* If a stage of compilation returns an exit status >= 1, - compilation of that file ceases. */ - -#define MIN_FATAL_STATUS 1 - -/* Flag saying to print the full filename of libgcc.a - as found through our usual search mechanism. */ - -static int print_libgcc_file_name; - -/* Flag indicating whether we should print the command and arguments */ - -static int verbose_flag; - -/* Nonzero means write "temp" files in source directory - and use the source file's name in them, and don't delete them. */ - -static int save_temps_flag; - -/* The compiler version specified with -V */ - -static char *spec_version; - -/* The target machine specified with -b. */ - -static char *spec_machine = ""; - -/* Nonzero if cross-compiling. - When -b is used, the value comes from the `specs' file. */ - -#ifdef CROSS_COMPILE -static int cross_compile = 1; -#else -static int cross_compile = 0; -#endif - -/* The number of errors that have occurred; the link phase will not be - run if this is non-zero. */ -static int error_count = 0; - -/* This is the obstack which we use to allocate many strings. */ - -static struct obstack obstack; - -/* This is the obstack to build an environment variable to pass to - collect2 that describes all of the relevant switches of what to - pass the compiler in building the list of pointers to constructors - and destructors. */ - -static struct obstack collect_obstack; - -extern char *version_string; - -static void set_spec (); -static struct compiler *lookup_compiler (); -static char *find_a_file (); -static void add_prefix (); -static char *skip_whitespace (); -static void record_temp_file (); -static char *handle_braces (); -static char *save_string (); -static char *concat (); -static int do_spec (); -static int do_spec_1 (); -static char *find_file (); -static int is_directory (); -static void validate_switches (); -static void validate_all_switches (); -static void give_switch (); -static void pfatal_with_name (); -static void perror_with_name (); -static void perror_exec (); -static void fatal (); -static void error (); -void fancy_abort (); -char *xmalloc (); -char *xrealloc (); - -/* Specs are strings containing lines, each of which (if not blank) -is made up of a program name, and arguments separated by spaces. -The program name must be exact and start from root, since no path -is searched and it is unreliable to depend on the current working directory. -Redirection of input or output is not supported; the subprograms must -accept filenames saying what files to read and write. - -In addition, the specs can contain %-sequences to substitute variable text -or for conditional text. Here is a table of all defined %-sequences. -Note that spaces are not generated automatically around the results of -expanding these sequences; therefore, you can concatenate them together -or with constant text in a single argument. - - %% substitute one % into the program name or argument. - %i substitute the name of the input file being processed. - %b substitute the basename of the input file being processed. - This is the substring up to (and not including) the last period - and not including the directory. - %g substitute the temporary-file-name-base. This is a string chosen - once per compilation. Different temporary file names are made by - concatenation of constant strings on the end, as in `%g.s'. - %g also has the same effect of %d. - %u like %g, but make the temporary file name unique. - %U returns the last file name generated with %u. - %d marks the argument containing or following the %d as a - temporary file name, so that that file will be deleted if CC exits - successfully. Unlike %g, this contributes no text to the argument. - %w marks the argument containing or following the %w as the - "output file" of this compilation. This puts the argument - into the sequence of arguments that %o will substitute later. - %W{...} - like %{...} but mark last argument supplied within - as a file to be deleted on failure. - %o substitutes the names of all the output files, with spaces - automatically placed around them. You should write spaces - around the %o as well or the results are undefined. - %o is for use in the specs for running the linker. - Input files whose names have no recognized suffix are not compiled - at all, but they are included among the output files, so they will - be linked. - %p substitutes the standard macro predefinitions for the - current target machine. Use this when running cpp. - %P like %p, but puts `__' before and after the name of each macro. - (Except macros that already have __.) - This is for ANSI C. - %I Substitute a -iprefix option made from GCC_EXEC_PREFIX. - %s current argument is the name of a library or startup file of some sort. - Search for that file in a standard list of directories - and substitute the full name found. - %eSTR Print STR as an error message. STR is terminated by a newline. - Use this when inconsistent options are detected. - %x{OPTION} Accumulate an option for %X. - %X Output the accumulated linker options specified by compilations. - %Y Output the accumulated assembler options specified by compilations. - %a process ASM_SPEC as a spec. - This allows config.h to specify part of the spec for running as. - %A process ASM_FINAL_SPEC as a spec. A capital A is actually - used here. This can be used to run a post-processor after the - assembler has done it's job. - %D Dump out a -L option for each directory in startfile_prefix. - %l process LINK_SPEC as a spec. - %L process LIB_SPEC as a spec. - %S process STARTFILE_SPEC as a spec. A capital S is actually used here. - %E process ENDFILE_SPEC as a spec. A capital E is actually used here. - %c process SIGNED_CHAR_SPEC as a spec. - %C process CPP_SPEC as a spec. A capital C is actually used here. - %1 process CC1_SPEC as a spec. - %2 process CC1PLUS_SPEC as a spec. - %| output "-" if the input for the current command is coming from a pipe. - %* substitute the variable part of a matched option. (See below.) - Note that each comma in the substituted string is replaced by - a single space. - %{S} substitutes the -S switch, if that switch was given to CC. - If that switch was not specified, this substitutes nothing. - Here S is a metasyntactic variable. - %{S*} substitutes all the switches specified to CC whose names start - with -S. This is used for -o, -D, -I, etc; switches that take - arguments. CC considers `-o foo' as being one switch whose - name starts with `o'. %{o*} would substitute this text, - including the space; thus, two arguments would be generated. - %{S*:X} substitutes X if one or more switches whose names start with -S are - specified to CC. Note that the tail part of the -S option - (i.e. the part matched by the `*') will be substituted for each - occurrence of %* within X. - %{S:X} substitutes X, but only if the -S switch was given to CC. - %{!S:X} substitutes X, but only if the -S switch was NOT given to CC. - %{|S:X} like %{S:X}, but if no S switch, substitute `-'. - %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'. - %{.S:X} substitutes X, but only if processing a file with suffix S. - %{!.S:X} substitutes X, but only if NOT processing a file with suffix S. - %(Spec) processes a specification defined in a specs file as *Spec: - %[Spec] as above, but put __ around -D arguments - -The conditional text X in a %{S:X} or %{!S:X} construct may contain -other nested % constructs or spaces, or even newlines. They are -processed as usual, as described above. - -The character | is used to indicate that a command should be piped to -the following command, but only if -pipe is specified. - -Note that it is built into CC which switches take arguments and which -do not. You might think it would be useful to generalize this to -allow each compiler's spec to say which switches take arguments. But -this cannot be done in a consistent fashion. CC cannot even decide -which input files have been specified without knowing which switches -take arguments, and it must know which input files to compile in order -to tell which compilers to run. - -CC also knows implicitly that arguments starting in `-l' are to be -treated as compiler output files, and passed to the linker in their -proper position among the other output files. */ - -/* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1. */ - -/* config.h can define ASM_SPEC to provide extra args to the assembler - or extra switch-translations. */ -#ifndef ASM_SPEC -#define ASM_SPEC "" -#endif - -/* config.h can define ASM_FINAL_SPEC to run a post processor after - the assembler has run. */ -#ifndef ASM_FINAL_SPEC -#define ASM_FINAL_SPEC "" -#endif - -/* config.h can define CPP_SPEC to provide extra args to the C preprocessor - or extra switch-translations. */ -#ifndef CPP_SPEC -#define CPP_SPEC "" -#endif - -/* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus - or extra switch-translations. */ -#ifndef CC1_SPEC -#define CC1_SPEC "" -#endif - -/* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus - or extra switch-translations. */ -#ifndef CC1PLUS_SPEC -#define CC1PLUS_SPEC "" -#endif - -/* config.h can define LINK_SPEC to provide extra args to the linker - or extra switch-translations. */ -#ifndef LINK_SPEC -#define LINK_SPEC "" -#endif - -/* config.h can define LIB_SPEC to override the default libraries. */ -#ifndef LIB_SPEC -#define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" -#endif - -/* config.h can define STARTFILE_SPEC to override the default crt0 files. */ -#ifndef STARTFILE_SPEC -#define STARTFILE_SPEC \ - "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" -#endif - -/* config.h can define SWITCHES_NEED_SPACES to control passing -o and -L. - Make the string nonempty to require spaces there. */ -#ifndef SWITCHES_NEED_SPACES -#define SWITCHES_NEED_SPACES "" -#endif - -/* config.h can define ENDFILE_SPEC to override the default crtn files. */ -#ifndef ENDFILE_SPEC -#define ENDFILE_SPEC "" -#endif - -/* This spec is used for telling cpp whether char is signed or not. */ -#ifndef SIGNED_CHAR_SPEC -/* Use #if rather than ?: - because MIPS C compiler rejects like ?: in initializers. */ -#if DEFAULT_SIGNED_CHAR -#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}" -#else -#define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}" -#endif -#endif - -static char *cpp_spec = CPP_SPEC; -static char *cpp_predefines = CPP_PREDEFINES; -static char *cc1_spec = CC1_SPEC; -static char *cc1plus_spec = CC1PLUS_SPEC; -static char *signed_char_spec = SIGNED_CHAR_SPEC; -static char *asm_spec = ASM_SPEC; -static char *asm_final_spec = ASM_FINAL_SPEC; -static char *link_spec = LINK_SPEC; -static char *lib_spec = LIB_SPEC; -static char *endfile_spec = ENDFILE_SPEC; -static char *startfile_spec = STARTFILE_SPEC; -static char *switches_need_spaces = SWITCHES_NEED_SPACES; - -/* This defines which switch letters take arguments. */ - -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) \ - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ - || (CHAR) == 'I' || (CHAR) == 'm' \ - || (CHAR) == 'L' || (CHAR) == 'A') -#endif - -/* This defines which multi-letter switches take arguments. */ - -#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ - (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ - || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ - || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ - || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ - || !strcmp (STR, "iwithprefix")) - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - -/* Record the mapping from file suffixes for compilation specs. */ - -struct compiler -{ - char *suffix; /* Use this compiler for input files - whose names end in this suffix. */ - - char *spec[4]; /* To use this compiler, concatenate these - specs and pass to do_spec. */ -}; - -/* Pointer to a vector of `struct compiler' that gives the spec for - compiling a file, based on its suffix. - A file that does not end in any of these suffixes will be passed - unchanged to the loader and nothing else will be done to it. - - An entry containing two 0s is used to terminate the vector. - - If multiple entries match a file, the last matching one is used. */ - -static struct compiler *compilers; - -/* Number of entries in `compilers', not counting the null terminator. */ - -static int n_compilers; - -/* The default list of file name suffixes and their compilation specs. */ - -static struct compiler default_compilers[] = -{ - {".c", "@c"}, - {"@c", - "cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ - -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs} \ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \ - %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ - %{!pipe:%g.s} %A\n }}}}"}, - {"-", - "%{E:cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ - -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %W{o*}}\ - %{!E:%e-E required when input is from standard input}"}, - {".m", "@objective-c"}, - {"@objective-c", - "cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ - -undef -D__OBJC__ -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.i} %1 \ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ - %{!pipe:%g.s} %A\n }}}}"}, - {".h", "@c-header"}, - {"@c-header", - "%{!E:%eCompilation of header file requested} \ - cpp %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \ - -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %W{o*}"}, - {".cc", "@c++"}, - {".cxx", "@c++"}, - {".C", "@c++"}, - {"@c++", - "cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \ - -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus \ - %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional} %{trigraphs}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.i} %1 %2\ - %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ - %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ - %{!pipe:%g.s} %A\n }}}}"}, - {".i", "@cpp-output"}, - {"@cpp-output", - "cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ - %{v:-version} %{pg:-p} %{p} %{f*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n }"}, - {".ii", "@c++-cpp-output"}, - {"@c++-cpp-output", - "cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ - %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ - %{!pipe:%g.s} %A\n }"}, - {".s", "@assembler"}, - {"@assembler", - "%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %i %A\n }"}, - {".S", "@assembler-with-cpp"}, - {"@assembler-with-cpp", - "cpp -lang-asm %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{trigraphs} \ - -undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \ - %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ - %{!pipe:%g.s} %A\n }}}}"}, - /* Mark end of table */ - {0, 0} -}; - -/* Number of elements in default_compilers, not counting the terminator. */ - -static int n_default_compilers - = (sizeof default_compilers / sizeof (struct compiler)) - 1; - -/* Here is the spec for running the linker, after compiling all files. */ - -/* -u* was put back because both BSD and SysV seem to support it. */ -/* %{static:} simply prevents an error message if the target machine - doesn't handle -static. */ -#ifdef LINK_LIBGCC_SPECIAL_1 -/* Have gcc do the search for libgcc.a, but generate -L options as usual. */ -static char *link_command_spec = "\ -%{!fsyntax-only: \ - %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ - %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ - %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ - %{L*} %D %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}"; -#else -#ifdef LINK_LIBGCC_SPECIAL -/* Have gcc do the search for libgcc.a, and don't generate -L options. */ -static char *link_command_spec = "\ -%{!fsyntax-only: \ - %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ - %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ - %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ - %{L*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}"; -#else -/* Use -L and have the linker do the search for -lgcc. */ -static char *link_command_spec = "\ -%{!fsyntax-only: \ - %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ - %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ - %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ - %{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}"; -#endif -#endif - -/* A vector of options to give to the linker. - These options are accumulated by -Xlinker and -Wl, - and substituted into the linker command with %X. */ -static int n_linker_options; -static char **linker_options; - -/* A vector of options to give to the assembler. - These options are accumulated by -Wa, - and substituted into the assembler command with %X. */ -static int n_assembler_options; -static char **assembler_options; - -/* Define how to map long options into short ones. */ - -/* This structure describes one mapping. */ -struct option_map -{ - /* The long option's name. */ - char *name; - /* The equivalent short option. */ - char *equivalent; - /* Argument info. A string of flag chars; NULL equals no options. - a => argument required. - o => argument optional. - j => join argument to equivalent, making one word. - * => allow other text after NAME as an argument. */ - char *arg_info; -}; - -/* This is the table of mappings. Mappings are tried sequentially - for each option encountered; the first one that matches, wins. */ - -struct option_map option_map[] = - { - {"--profile-blocks", "-a", 0}, - {"--target", "-b", "a"}, - {"--compile", "-c", 0}, - {"--dump", "-d", "a"}, - {"--entry", "-e", 0}, - {"--debug", "-g", "oj"}, - {"--include", "-include", "a"}, - {"--imacros", "-imacros", "a"}, - {"--include-prefix", "-iprefix", "a"}, - {"--include-directory-after", "-idirafter", "a"}, - {"--include-with-prefix", "-iwithprefix", "a"}, - {"--machine-", "-m", "*j"}, - {"--machine", "-m", "aj"}, - {"--no-standard-includes", "-nostdinc", 0}, - {"--no-standard-libraries", "-nostdlib", 0}, - {"--no-precompiled-includes", "-noprecomp", 0}, - {"--output", "-o", "a"}, - {"--profile", "-p", 0}, - {"--quiet", "-q", 0}, - {"--silent", "-q", 0}, - {"--force-link", "-u", "a"}, - {"--verbose", "-v", 0}, - {"--no-warnings", "-w", 0}, - {"--language", "-x", "a"}, - - {"--assert", "-A", "a"}, - {"--prefix", "-B", "a"}, - {"--comments", "-C", 0}, - {"--define-macro", "-D", "a"}, - {"--preprocess", "-E", 0}, - {"--trace-includes", "-H", 0}, - {"--include-directory", "-I", "a"}, - {"--include-barrier", "-I-", 0}, - {"--library-directory", "-L", "a"}, - {"--dependencies", "-M", 0}, - {"--user-dependencies", "-MM", 0}, - {"--write-dependencies", "-MD", 0}, - {"--write-user-dependencies", "-MMD", 0}, - {"--optimize", "-O", "oj"}, - {"--no-line-commands", "-P", 0}, - {"--assemble", "-S", 0}, - {"--undefine-macro", "-U", "a"}, - {"--use-version", "-V", "a"}, - {"--for-assembler", "-Wa", "a"}, - {"--extra-warnings", "-W", 0}, - {"--all-warnings", "-Wall", 0}, - {"--warn-", "-W", "*j"}, - {"--for-linker", "-Xlinker", "a"}, - - {"--ansi", "-ansi", 0}, - {"--traditional", "-traditional", 0}, - {"--traditional-cpp", "-traditional-cpp", 0}, - {"--trigraphs", "-trigraphs", 0}, - {"--pipe", "-pipe", 0}, - {"--dumpbase", "-dumpbase", "a"}, - {"--pedantic", "-pedantic", 0}, - {"--pedantic-errors", "-pedantic-errors", 0}, - {"--save-temps", "-save-temps", 0}, - {"--print-libgcc-file-name", "-print-libgcc-file-name", 0}, - {"--static", "-static", 0}, - {"--shared", "-shared", 0}, - {"--symbolic", "-symbolic", 0}, - {"--", "-f", "*j"} - }; - -/* Translate the options described by *ARGCP and *ARGVP. - Make a new vector and store it back in *ARGVP, - and store its length in *ARGVC. */ - -static void -translate_options (argcp, argvp) - int *argcp; - char ***argvp; -{ - int i, j; - int argc = *argcp; - char **argv = *argvp; - char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *)); - int newindex = 0; - - i = 0; - newv[newindex++] = argv[i++]; - - while (i < argc) - { - /* Translate -- options. */ - if (argv[i][0] == '-' && argv[i][1] == '-') - { - /* Find a mapping that applies to this option. */ - for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++) - { - int optlen = strlen (option_map[j].name); - int complen = strlen (argv[i]); - char *arginfo = option_map[j].arg_info; - - if (arginfo == 0) - arginfo = ""; - if (complen > optlen) - complen = optlen; - if (!strncmp (argv[i], option_map[j].name, complen)) - { - int extra = strlen (argv[i]) > optlen; - char *arg = 0; - - if (extra) - { - /* If the option has an argument, accept that. */ - if (argv[i][optlen] == '=') - arg = argv[i] + optlen + 1; - /* If this mapping allows extra text at end of name, - accept that as "argument". */ - else if (index (arginfo, '*') != 0) - arg = argv[i] + optlen; - /* Otherwise, extra text at end means mismatch. - Try other mappings. */ - else - continue; - } - else if (index (arginfo, '*') != 0) - error ("Incomplete `%s' option", option_map[j].name); - - /* Handle arguments. */ - if (index (arginfo, 'o') != 0) - { - if (arg == 0) - { - if (i + 1 == argc) - error ("Missing argument to `%s' option", - option_map[j].name); - arg = argv[++i]; - } - } - else if (index (arginfo, 'a') == 0) - { - if (arg != 0) - error ("Extraneous argument to `%s' option", - option_map[j].name); - arg = 0; - } - - /* Store the translation as one argv elt or as two. */ - if (arg != 0 && index (arginfo, 'j') != 0) - newv[newindex++] = concat (option_map[j].equivalent, - arg, ""); - else if (arg != 0) - { - newv[newindex++] = option_map[j].equivalent; - newv[newindex++] = arg; - } - else - newv[newindex++] = option_map[j].equivalent; - - break; - } - } - i++; - } - /* Handle old-fashioned options--just copy them through, - with their arguments. */ - else if (argv[i][0] == '-') - { - char *p = argv[i] + 1; - int c = *p; - int nskip = 1; - - if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) - nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0); - else if (WORD_SWITCH_TAKES_ARG (p)) - nskip += WORD_SWITCH_TAKES_ARG (p); - - while (nskip > 0) - { - newv[newindex++] = argv[i++]; - nskip--; - } - } - else - /* Ordinary operands, or +e options. */ - newv[newindex++] = argv[i++]; - } - - newv[newindex] = 0; - - *argvp = newv; - *argcp = newindex; -} - -/* Read compilation specs from a file named FILENAME, - replacing the default ones. - - A suffix which starts with `*' is a definition for - one of the machine-specific sub-specs. The "suffix" should be - *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc. - The corresponding spec is stored in asm_spec, etc., - rather than in the `compilers' vector. - - Anything invalid in the file is a fatal error. */ - -static void -read_specs (filename) - char *filename; -{ - int desc; - struct stat statbuf; - char *buffer; - register char *p; - - if (verbose_flag) - fprintf (stderr, "Reading specs from %s\n", filename); - - /* Open and stat the file. */ - desc = open (filename, 0, 0); - if (desc < 0) - pfatal_with_name (filename); - if (stat (filename, &statbuf) < 0) - pfatal_with_name (filename); - - /* Read contents of file into BUFFER. */ - buffer = xmalloc ((unsigned) statbuf.st_size + 1); - read (desc, buffer, (unsigned) statbuf.st_size); - buffer[statbuf.st_size] = 0; - close (desc); - - /* Scan BUFFER for specs, putting them in the vector. */ - p = buffer; - while (1) - { - char *suffix; - char *spec; - char *in, *out, *p1, *p2; - - /* Advance P in BUFFER to the next nonblank nocomment line. */ - p = skip_whitespace (p); - if (*p == 0) - break; - - /* Find the colon that should end the suffix. */ - p1 = p; - while (*p1 && *p1 != ':' && *p1 != '\n') p1++; - /* The colon shouldn't be missing. */ - if (*p1 != ':') - fatal ("specs file malformed after %d characters", p1 - buffer); - /* Skip back over trailing whitespace. */ - p2 = p1; - while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--; - /* Copy the suffix to a string. */ - suffix = save_string (p, p2 - p); - /* Find the next line. */ - p = skip_whitespace (p1 + 1); - if (p[1] == 0) - fatal ("specs file malformed after %d characters", p - buffer); - p1 = p; - /* Find next blank line. */ - while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++; - /* Specs end at the blank line and do not include the newline. */ - spec = save_string (p, p1 - p); - p = p1; - - /* Delete backslash-newline sequences from the spec. */ - in = spec; - out = spec; - while (*in != 0) - { - if (in[0] == '\\' && in[1] == '\n') - in += 2; - else if (in[0] == '#') - { - while (*in && *in != '\n') in++; - } - else - *out++ = *in++; - } - *out = 0; - - if (suffix[0] == '*') - { - if (! strcmp (suffix, "*link_command")) - link_command_spec = spec; - else - set_spec (suffix + 1, spec); - } - else - { - /* Add this pair to the vector. */ - compilers - = ((struct compiler *) - xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler))); - compilers[n_compilers].suffix = suffix; - bzero (compilers[n_compilers].spec, - sizeof compilers[n_compilers].spec); - compilers[n_compilers].spec[0] = spec; - n_compilers++; - } - - if (*suffix == 0) - link_command_spec = spec; - } - - if (link_command_spec == 0) - fatal ("spec file has no spec for linking"); -} - -static char * -skip_whitespace (p) - char *p; -{ - while (1) - { - /* A fully-blank line is a delimiter in the SPEC file and shouldn't - be considered whitespace. */ - if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n') - return p + 1; - else if (*p == '\n' || *p == ' ' || *p == '\t') - p++; - else if (*p == '#') - { - while (*p != '\n') p++; - p++; - } - else - break; - } - - return p; -} - -/* Structure to keep track of the specs that have been defined so far. These - are accessed using %(specname) or %[specname] in a compiler or link spec. */ - -struct spec_list -{ - char *name; /* Name of the spec. */ - char *spec; /* The spec itself. */ - struct spec_list *next; /* Next spec in linked list. */ -}; - -/* List of specs that have been defined so far. */ - -static struct spec_list *specs = (struct spec_list *) 0; - -/* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is - removed; If the spec starts with a + then SPEC is added to the end of the - current spec. */ - -static void -set_spec (name, spec) - char *name; - char *spec; -{ - struct spec_list *sl; - char *old_spec; - - /* See if the spec already exists */ - for (sl = specs; sl; sl = sl->next) - if (strcmp (sl->name, name) == 0) - break; - - if (!sl) - { - /* Not found - make it */ - sl = (struct spec_list *) xmalloc (sizeof (struct spec_list)); - sl->name = save_string (name, strlen (name)); - sl->spec = save_string ("", 0); - sl->next = specs; - specs = sl; - } - - old_spec = sl->spec; - if (name && spec[0] == '+' && isspace (spec[1])) - sl->spec = concat (old_spec, spec + 1, ""); - else - sl->spec = save_string (spec, strlen (spec)); - - if (! strcmp (name, "asm")) - asm_spec = sl->spec; - else if (! strcmp (name, "asm_final")) - asm_final_spec = sl->spec; - else if (! strcmp (name, "cc1")) - cc1_spec = sl->spec; - else if (! strcmp (name, "cc1plus")) - cc1plus_spec = sl->spec; - else if (! strcmp (name, "cpp")) - cpp_spec = sl->spec; - else if (! strcmp (name, "endfile")) - endfile_spec = sl->spec; - else if (! strcmp (name, "lib")) - lib_spec = sl->spec; - else if (! strcmp (name, "link")) - link_spec = sl->spec; - else if (! strcmp (name, "predefines")) - cpp_predefines = sl->spec; - else if (! strcmp (name, "signed_char")) - signed_char_spec = sl->spec; - else if (! strcmp (name, "startfile")) - startfile_spec = sl->spec; - else if (! strcmp (name, "switches_need_spaces")) - switches_need_spaces = sl->spec; - else if (! strcmp (name, "cross_compile")) - cross_compile = atoi (sl->spec); - /* Free the old spec */ - if (old_spec) - free (old_spec); -} - -/* Accumulate a command (program name and args), and run it. */ - -/* Vector of pointers to arguments in the current line of specifications. */ - -static char **argbuf; - -/* Number of elements allocated in argbuf. */ - -static int argbuf_length; - -/* Number of elements in argbuf currently in use (containing args). */ - -static int argbuf_index; - -/* This is the list of suffixes and codes (%g/%u/%U) and the associated - temp file. Used only if MKTEMP_EACH_FILE. */ - -static struct temp_name { - char *suffix; /* suffix associated with the code. */ - int length; /* strlen (suffix). */ - int unique; /* Indicates whether %g or %u/%U was used. */ - char *filename; /* associated filename. */ - int filename_length; /* strlen (filename). */ - struct temp_name *next; -} *temp_names; - -/* Number of commands executed so far. */ - -static int execution_count; - -/* Number of commands that exited with a signal. */ - -static int signal_count; - -/* Name with which this program was invoked. */ - -static char *programname; - -/* Structures to keep track of prefixes to try when looking for files. */ - -struct prefix_list -{ - char *prefix; /* String to prepend to the path. */ - struct prefix_list *next; /* Next in linked list. */ - int require_machine_suffix; /* Don't use without machine_suffix. */ - /* 2 means try both machine_suffix and just_machine_suffix. */ - int *used_flag_ptr; /* 1 if a file was found with this prefix. */ -}; - -struct path_prefix -{ - struct prefix_list *plist; /* List of prefixes to try */ - int max_len; /* Max length of a prefix in PLIST */ - char *name; /* Name of this list (used in config stuff) */ -}; - -/* List of prefixes to try when looking for executables. */ - -static struct path_prefix exec_prefix = { 0, 0, "exec" }; - -/* List of prefixes to try when looking for startup (crt0) files. */ - -static struct path_prefix startfile_prefix = { 0, 0, "startfile" }; - -/* Suffix to attach to directories searched for commands. - This looks like `MACHINE/VERSION/'. */ - -static char *machine_suffix = 0; - -/* Suffix to attach to directories searched for commands. - This is just `MACHINE/'. */ - -static char *just_machine_suffix = 0; - -/* Adjusted value of GCC_EXEC_PREFIX envvar. */ - -static char *gcc_exec_prefix; - -/* Default prefixes to attach to command names. */ - -#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */ -#undef MD_EXEC_PREFIX -#undef MD_STARTFILE_PREFIX -#undef MD_STARTFILE_PREFIX_1 -#endif - -#ifndef STANDARD_EXEC_PREFIX -#define STANDARD_EXEC_PREFIX "/usr/libexec/" -#endif /* !defined STANDARD_EXEC_PREFIX */ - -static char *standard_exec_prefix = STANDARD_EXEC_PREFIX; -static char *standard_exec_prefix_1 = ""; -#ifdef MD_EXEC_PREFIX -static char *md_exec_prefix = MD_EXEC_PREFIX; -#endif - -#ifndef STANDARD_STARTFILE_PREFIX -#define STANDARD_STARTFILE_PREFIX "/usr/lib/" -#endif /* !defined STANDARD_STARTFILE_PREFIX */ - -#ifdef MD_STARTFILE_PREFIX -static char *md_startfile_prefix = MD_STARTFILE_PREFIX; -#endif -#ifdef MD_STARTFILE_PREFIX_1 -static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1; -#endif -static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX; -static char *standard_startfile_prefix_1 = "/lib/"; -static char *standard_startfile_prefix_2 = "/usr/lib/"; - -#if 0 -#ifndef TOOLDIR_BASE_PREFIX -#define TOOLDIR_BASE_PREFIX "/usr/local/" -#endif -static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX; -static char *tooldir_prefix; -#endif - -/* Clear out the vector of arguments (after a command is executed). */ - -static void -clear_args () -{ - argbuf_index = 0; -} - -/* Add one argument to the vector at the end. - This is done when a space is seen or at the end of the line. - If DELETE_ALWAYS is nonzero, the arg is a filename - and the file should be deleted eventually. - If DELETE_FAILURE is nonzero, the arg is a filename - and the file should be deleted if this compilation fails. */ - -static void -store_arg (arg, delete_always, delete_failure) - char *arg; - int delete_always, delete_failure; -{ - if (argbuf_index + 1 == argbuf_length) - { - argbuf = (char **) xrealloc (argbuf, (argbuf_length *= 2) * sizeof (char *)); - } - - argbuf[argbuf_index++] = arg; - argbuf[argbuf_index] = 0; - - if (delete_always || delete_failure) - record_temp_file (arg, delete_always, delete_failure); -} - -/* Record the names of temporary files we tell compilers to write, - and delete them at the end of the run. */ - -/* This is the common prefix we use to make temp file names. - It is chosen once for each run of this program. - It is substituted into a spec by %g. - Thus, all temp file names contain this prefix. - In practice, all temp file names start with this prefix. - - This prefix comes from the envvar TMPDIR if it is defined; - otherwise, from the P_tmpdir macro if that is defined; - otherwise, in /usr/tmp or /tmp. */ - -static char *temp_filename; - -/* Length of the prefix. */ - -static int temp_filename_length; - -/* Define the list of temporary files to delete. */ - -struct temp_file -{ - char *name; - struct temp_file *next; -}; - -/* Queue of files to delete on success or failure of compilation. */ -static struct temp_file *always_delete_queue; -/* Queue of files to delete on failure of compilation. */ -static struct temp_file *failure_delete_queue; - -/* Record FILENAME as a file to be deleted automatically. - ALWAYS_DELETE nonzero means delete it if all compilation succeeds; - otherwise delete it in any case. - FAIL_DELETE nonzero means delete it if a compilation step fails; - otherwise delete it in any case. */ - -static void -record_temp_file (filename, always_delete, fail_delete) - char *filename; - int always_delete; - int fail_delete; -{ - register char *name; - name = xmalloc (strlen (filename) + 1); - strcpy (name, filename); - - if (always_delete) - { - register struct temp_file *temp; - for (temp = always_delete_queue; temp; temp = temp->next) - if (! strcmp (name, temp->name)) - goto already1; - temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); - temp->next = always_delete_queue; - temp->name = name; - always_delete_queue = temp; - already1:; - } - - if (fail_delete) - { - register struct temp_file *temp; - for (temp = failure_delete_queue; temp; temp = temp->next) - if (! strcmp (name, temp->name)) - goto already2; - temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); - temp->next = failure_delete_queue; - temp->name = name; - failure_delete_queue = temp; - already2:; - } -} - -/* Delete all the temporary files whose names we previously recorded. */ - -static void -delete_temp_files () -{ - register struct temp_file *temp; - - for (temp = always_delete_queue; temp; temp = temp->next) - { -#ifdef DEBUG - int i; - printf ("Delete %s? (y or n) ", temp->name); - fflush (stdout); - i = getchar (); - if (i != '\n') - while (getchar () != '\n') ; - if (i == 'y' || i == 'Y') -#endif /* DEBUG */ - { - struct stat st; - if (stat (temp->name, &st) >= 0) - { - /* Delete only ordinary files. */ - if (S_ISREG (st.st_mode)) - if (unlink (temp->name) < 0) - if (verbose_flag) - perror_with_name (temp->name); - } - } - } - - always_delete_queue = 0; -} - -/* Delete all the files to be deleted on error. */ - -static void -delete_failure_queue () -{ - register struct temp_file *temp; - - for (temp = failure_delete_queue; temp; temp = temp->next) - { -#ifdef DEBUG - int i; - printf ("Delete %s? (y or n) ", temp->name); - fflush (stdout); - i = getchar (); - if (i != '\n') - while (getchar () != '\n') ; - if (i == 'y' || i == 'Y') -#endif /* DEBUG */ - { - if (unlink (temp->name) < 0) - if (verbose_flag) - perror_with_name (temp->name); - } - } -} - -static void -clear_failure_queue () -{ - failure_delete_queue = 0; -} - -/* Compute a string to use as the base of all temporary file names. - It is substituted for %g. */ - -static void -choose_temp_base () -{ - char *base = getenv ("TMPDIR"); - int len; - - if (base == (char *)0) - { -#ifdef P_tmpdir - if (access (P_tmpdir, R_OK | W_OK) == 0) - base = P_tmpdir; -#endif - if (base == (char *)0) - { - if (access ("/usr/tmp", R_OK | W_OK) == 0) - base = "/usr/tmp/"; - else - base = "/tmp/"; - } - } - - len = strlen (base); - temp_filename = xmalloc (len + sizeof("/ccXXXXXX")); - strcpy (temp_filename, base); - if (len > 0 && temp_filename[len-1] != '/') - temp_filename[len++] = '/'; - strcpy (temp_filename + len, "ccXXXXXX"); - - mktemp (temp_filename); - temp_filename_length = strlen (temp_filename); - if (temp_filename_length == 0) - abort (); -} - - -/* Routine to add variables to the environment. We do this to pass - the pathname of the gcc driver, and the directories search to the - collect2 program, which is being run as ld. This way, we can be - sure of executing the right compiler when collect2 wants to build - constructors and destructors. Since the environment variables we - use come from an obstack, we don't have to worry about allocating - space for them. */ - -#ifndef HAVE_PUTENV - -void -putenv (str) - char *str; -{ -#ifndef VMS /* nor about VMS */ - - extern char **environ; - char **old_environ = environ; - char **envp; - int num_envs = 0; - int name_len = 1; - int str_len = strlen (str); - char *p = str; - int ch; - - while ((ch = *p++) != '\0' && ch != '=') - name_len++; - - if (!ch) - abort (); - - /* Search for replacing an existing environment variable, and - count the number of total environment variables. */ - for (envp = old_environ; *envp; envp++) - { - num_envs++; - if (!strncmp (str, *envp, name_len)) - { - *envp = str; - return; - } - } - - /* Add a new environment variable */ - environ = (char **) xmalloc (sizeof (char *) * (num_envs+2)); - *environ = str; - bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1)); - -#endif /* VMS */ -} - -#endif /* HAVE_PUTENV */ - - -/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */ - -static void -putenv_from_prefixes (paths, env_var) - struct path_prefix *paths; - char *env_var; -{ - int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0; - int just_suffix_len - = (just_machine_suffix) ? strlen (just_machine_suffix) : 0; - int first_time = TRUE; - struct prefix_list *pprefix; - - obstack_grow (&collect_obstack, env_var, strlen (env_var)); - - for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next) - { - int len = strlen (pprefix->prefix); - - if (machine_suffix - && is_directory (pprefix->prefix, machine_suffix, 0)) - { - if (!first_time) - obstack_1grow (&collect_obstack, PATH_SEPARATOR); - - first_time = FALSE; - obstack_grow (&collect_obstack, pprefix->prefix, len); - obstack_grow (&collect_obstack, machine_suffix, suffix_len); - } - - if (just_machine_suffix - && pprefix->require_machine_suffix == 2 - && is_directory (pprefix->prefix, just_machine_suffix, 0)) - { - if (!first_time) - obstack_1grow (&collect_obstack, PATH_SEPARATOR); - - first_time = FALSE; - obstack_grow (&collect_obstack, pprefix->prefix, len); - obstack_grow (&collect_obstack, just_machine_suffix, - just_suffix_len); - } - - if (!pprefix->require_machine_suffix) - { - if (!first_time) - obstack_1grow (&collect_obstack, PATH_SEPARATOR); - - first_time = FALSE; - obstack_grow (&collect_obstack, pprefix->prefix, len); - } - } - obstack_1grow (&collect_obstack, '\0'); - putenv (obstack_finish (&collect_obstack)); -} - - -/* Search for NAME using the prefix list PREFIXES. MODE is passed to - access to check permissions. - Return 0 if not found, otherwise return its name, allocated with malloc. */ - -static char * -find_a_file (pprefix, name, mode) - struct path_prefix *pprefix; - char *name; - int mode; -{ - char *temp; - char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : ""); - struct prefix_list *pl; - int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; - - if (machine_suffix) - len += strlen (machine_suffix); - - temp = xmalloc (len); - - /* Determine the filename to execute (special case for absolute paths). */ - - if (*name == '/') - { - if (access (name, mode)) - { - strcpy (temp, name); - return temp; - } - } - else - for (pl = pprefix->plist; pl; pl = pl->next) - { - if (machine_suffix) - { - strcpy (temp, pl->prefix); - strcat (temp, machine_suffix); - strcat (temp, name); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - /* Some systems have a suffix for executable files. - So try appending that. */ - if (file_suffix[0] != 0) - { - strcat (temp, file_suffix); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - } - } - /* Certain prefixes are tried with just the machine type, - not the version. This is used for finding as, ld, etc. */ - if (just_machine_suffix && pl->require_machine_suffix == 2) - { - strcpy (temp, pl->prefix); - strcat (temp, just_machine_suffix); - strcat (temp, name); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - /* Some systems have a suffix for executable files. - So try appending that. */ - if (file_suffix[0] != 0) - { - strcat (temp, file_suffix); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - } - } - /* Certain prefixes can't be used without the machine suffix - when the machine or version is explicitly specified. */ - if (!pl->require_machine_suffix) - { - strcpy (temp, pl->prefix); - strcat (temp, name); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - /* Some systems have a suffix for executable files. - So try appending that. */ - if (file_suffix[0] != 0) - { - strcat (temp, file_suffix); - if (access (temp, mode) == 0) - { - if (pl->used_flag_ptr != 0) - *pl->used_flag_ptr = 1; - return temp; - } - } - } - } - - free (temp); - return 0; -} - -/* Add an entry for PREFIX in PLIST. If FIRST is set, it goes - at the start of the list, otherwise it goes at the end. - - If WARN is nonzero, we will warn if no file is found - through this prefix. WARN should point to an int - which will be set to 1 if this entry is used. - - REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without - the complete value of machine_suffix. - 2 means try both machine_suffix and just_machine_suffix. */ - -static void -add_prefix (pprefix, prefix, first, require_machine_suffix, warn) - struct path_prefix *pprefix; - char *prefix; - int first; - int require_machine_suffix; - int *warn; -{ - struct prefix_list *pl, **prev; - int len; - - if (!first && pprefix->plist) - { - for (pl = pprefix->plist; pl->next; pl = pl->next) - ; - prev = &pl->next; - } - else - prev = &pprefix->plist; - - /* Keep track of the longest prefix */ - - len = strlen (prefix); - if (len > pprefix->max_len) - pprefix->max_len = len; - - pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); - pl->prefix = save_string (prefix, len); - pl->require_machine_suffix = require_machine_suffix; - pl->used_flag_ptr = warn; - if (warn) - *warn = 0; - - if (*prev) - pl->next = *prev; - else - pl->next = (struct prefix_list *) 0; - *prev = pl; -} - -/* Print warnings for any prefixes in the list PPREFIX that were not used. */ - -static void -unused_prefix_warnings (pprefix) - struct path_prefix *pprefix; -{ - struct prefix_list *pl = pprefix->plist; - - while (pl) - { - if (pl->used_flag_ptr != 0 && !*pl->used_flag_ptr) - { - error ("file path prefix `%s' never used", - pl->prefix); - /* Prevent duplicate warnings. */ - *pl->used_flag_ptr = 1; - } - pl = pl->next; - } -} - -/* Get rid of all prefixes built up so far in *PLISTP. */ - -static void -free_path_prefix (pprefix) - struct path_prefix *pprefix; -{ - struct prefix_list *pl = pprefix->plist; - struct prefix_list *temp; - - while (pl) - { - temp = pl; - pl = pl->next; - free (temp->prefix); - free ((char *) temp); - } - pprefix->plist = (struct prefix_list *) 0; -} - -/* stdin file number. */ -#define STDIN_FILE_NO 0 - -/* stdout file number. */ -#define STDOUT_FILE_NO 1 - -/* value of `pipe': port index for reading. */ -#define READ_PORT 0 - -/* value of `pipe': port index for writing. */ -#define WRITE_PORT 1 - -/* Pipe waiting from last process, to be used as input for the next one. - Value is STDIN_FILE_NO if no pipe is waiting - (i.e. the next command is the first of a group). */ - -static int last_pipe_input; - -/* Fork one piped subcommand. FUNC is the system call to use - (either execv or execvp). ARGV is the arg vector to use. - NOT_LAST is nonzero if this is not the last subcommand - (i.e. its output should be piped to the next one.) */ - -#ifndef OS2 -#ifdef __MSDOS__ - -/* Declare these to avoid compilation error. They won't be called. */ -int execv(const char *a, const char **b){} -int execvp(const char *a, const char **b){} - -static int -pexecute (search_flag, program, argv, not_last) - int search_flag; - char *program; - char *argv[]; - int not_last; -{ - char *scmd; - FILE *argfile; - int i; - - scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 6); - sprintf (scmd, "%s @%s.gp", program, temp_filename); - argfile = fopen (scmd+strlen (program) + 2, "w"); - if (argfile == 0) - pfatal_with_name (scmd + strlen (program) + 2); - - for (i=1; argv[i]; i++) - { - char *cp; - for (cp = argv[i]; *cp; cp++) - { - if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) - fputc ('\\', argfile); - fputc (*cp, argfile); - } - fputc ('\n', argfile); - } - fclose (argfile); - - i = system (scmd); - - remove (scmd + strlen (program) + 2); - return i << 8; -} - -#else /* not __MSDOS__ */ - -static int -pexecute (search_flag, program, argv, not_last) - int search_flag; - char *program; - char *argv[]; - int not_last; -{ - int (*func)() = (search_flag ? execv : execvp); - int pid; - int pdes[2]; - int input_desc = last_pipe_input; - int output_desc = STDOUT_FILE_NO; - int retries, sleep_interval; - - /* If this isn't the last process, make a pipe for its output, - and record it as waiting to be the input to the next process. */ - - if (not_last) - { - if (pipe (pdes) < 0) - pfatal_with_name ("pipe"); - output_desc = pdes[WRITE_PORT]; - last_pipe_input = pdes[READ_PORT]; - } - else - last_pipe_input = STDIN_FILE_NO; - - /* Fork a subprocess; wait and retry if it fails. */ - sleep_interval = 1; - for (retries = 0; retries < 4; retries++) - { - pid = vfork (); - if (pid >= 0) - break; - sleep (sleep_interval); - sleep_interval *= 2; - } - - switch (pid) - { - case -1: -#ifdef vfork - pfatal_with_name ("fork"); -#else - pfatal_with_name ("vfork"); -#endif - /* NOTREACHED */ - return 0; - - case 0: /* child */ - /* Move the input and output pipes into place, if nec. */ - if (input_desc != STDIN_FILE_NO) - { - close (STDIN_FILE_NO); - dup (input_desc); - close (input_desc); - } - if (output_desc != STDOUT_FILE_NO) - { - close (STDOUT_FILE_NO); - dup (output_desc); - close (output_desc); - } - - /* Close the parent's descs that aren't wanted here. */ - if (last_pipe_input != STDIN_FILE_NO) - close (last_pipe_input); - - /* Exec the program. */ - (*func) (program, argv); - perror_exec (program); - exit (-1); - /* NOTREACHED */ - return 0; - - default: - /* In the parent, after forking. - Close the descriptors that we made for this child. */ - if (input_desc != STDIN_FILE_NO) - close (input_desc); - if (output_desc != STDOUT_FILE_NO) - close (output_desc); - - /* Return child's process number. */ - return pid; - } -} - -#endif /* not __MSDOS__ */ -#else /* not OS2 */ - -static int -pexecute (search_flag, program, argv, not_last) - int search_flag; - char *program; - char *argv[]; - int not_last; -{ - return (search_flag ? spawnv : spawnvp) (1, program, argv); -} -#endif /* not OS2 */ - -/* Execute the command specified by the arguments on the current line of spec. - When using pipes, this includes several piped-together commands - with `|' between them. - - Return 0 if successful, -1 if failed. */ - -static int -execute () -{ - int i; - int n_commands; /* # of command. */ - char *string; - struct command - { - char *prog; /* program name. */ - char **argv; /* vector of args. */ - int pid; /* pid of process for this command. */ - }; - - struct command *commands; /* each command buffer with above info. */ - - /* Count # of piped commands. */ - for (n_commands = 1, i = 0; i < argbuf_index; i++) - if (strcmp (argbuf[i], "|") == 0) - n_commands++; - - /* Get storage for each command. */ - commands - = (struct command *) alloca (n_commands * sizeof (struct command)); - - /* Split argbuf into its separate piped processes, - and record info about each one. - Also search for the programs that are to be run. */ - - commands[0].prog = argbuf[0]; /* first command. */ - commands[0].argv = &argbuf[0]; - string = find_a_file (&exec_prefix, commands[0].prog, X_OK); - if (string) - commands[0].argv[0] = string; - - for (n_commands = 1, i = 0; i < argbuf_index; i++) - if (strcmp (argbuf[i], "|") == 0) - { /* each command. */ -#ifdef __MSDOS__ - fatal ("-pipe not supported under MS-DOS"); -#endif - argbuf[i] = 0; /* termination of command args. */ - commands[n_commands].prog = argbuf[i + 1]; - commands[n_commands].argv = &argbuf[i + 1]; - string = find_a_file (&exec_prefix, commands[n_commands].prog, X_OK); - if (string) - commands[n_commands].argv[0] = string; - n_commands++; - } - - argbuf[argbuf_index] = 0; - - /* If -v, print what we are about to do, and maybe query. */ - - if (verbose_flag) - { - /* Print each piped command as a separate line. */ - for (i = 0; i < n_commands ; i++) - { - char **j; - - for (j = commands[i].argv; *j; j++) - fprintf (stderr, " %s", *j); - - /* Print a pipe symbol after all but the last command. */ - if (i + 1 != n_commands) - fprintf (stderr, " |"); - fprintf (stderr, "\n"); - } - fflush (stderr); -#ifdef DEBUG - fprintf (stderr, "\nGo ahead? (y or n) "); - fflush (stderr); - i = getchar (); - if (i != '\n') - while (getchar () != '\n') ; - if (i != 'y' && i != 'Y') - return 0; -#endif /* DEBUG */ - } - - /* Run each piped subprocess. */ - - last_pipe_input = STDIN_FILE_NO; - for (i = 0; i < n_commands; i++) - { - char *string = commands[i].argv[0]; - - commands[i].pid = pexecute (string != commands[i].prog, - string, commands[i].argv, - i + 1 < n_commands); - - if (string != commands[i].prog) - free (string); - } - - execution_count++; - - /* Wait for all the subprocesses to finish. - We don't care what order they finish in; - we know that N_COMMANDS waits will get them all. */ - - { - int ret_code = 0; - - for (i = 0; i < n_commands; i++) - { - int status; - int pid; - char *prog; - -#ifdef __MSDOS__ - status = pid = commands[i].pid; -#else - pid = wait (&status); -#endif - if (pid < 0) - abort (); - - if (status != 0) - { - int j; - for (j = 0; j < n_commands; j++) - if (commands[j].pid == pid) - prog = commands[j].prog; - - if ((status & 0x7F) != 0) - { - fatal ("Internal compiler error: program %s got fatal signal %d", - prog, (status & 0x7F)); - signal_count++; - } - if (((status & 0xFF00) >> 8) >= MIN_FATAL_STATUS) - ret_code = -1; - } - } - return ret_code; - } -} - -/* Find all the switches given to us - and make a vector describing them. - The elements of the vector are strings, one per switch given. - If a switch uses following arguments, then the `part1' field - is the switch itself and the `args' field - is a null-terminated vector containing the following arguments. - The `valid' field is nonzero if any spec has looked at this switch; - if it remains zero at the end of the run, it must be meaningless. */ - -struct switchstr -{ - char *part1; - char **args; - int valid; -}; - -static struct switchstr *switches; - -static int n_switches; - -struct infile -{ - char *name; - char *language; -}; - -/* Also a vector of input files specified. */ - -static struct infile *infiles; - -static int n_infiles; - -/* And a vector of corresponding output files is made up later. */ - -static char **outfiles; - -/* Create the vector `switches' and its contents. - Store its length in `n_switches'. */ - -static void -process_command (argc, argv) - int argc; - char **argv; -{ - register int i; - char *temp; - char *spec_lang = 0; - int last_language_n_infiles; - - gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX"); - - n_switches = 0; - n_infiles = 0; - - /* Default for -V is our version number, ending at first space. */ - spec_version = save_string (version_string, strlen (version_string)); - for (temp = spec_version; *temp && *temp != ' '; temp++); - if (*temp) *temp = '\0'; - - /* Set up the default search paths. */ - - if (gcc_exec_prefix) - { - add_prefix (&exec_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); - add_prefix (&startfile_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); - } - - /* COMPILER_PATH and LIBRARY_PATH have values - that are lists of directory names with colons. */ - - temp = getenv ("COMPILER_PATH"); - if (temp) - { - char *startp, *endp; - char *nstore = (char *) alloca (strlen (temp) + 3); - - startp = endp = temp; - while (1) - { - if (*endp == PATH_SEPARATOR || *endp == 0) - { - strncpy (nstore, startp, endp-startp); - if (endp == startp) - { - strcpy (nstore, "./"); - } - else if (endp[-1] != '/') - { - nstore[endp-startp] = '/'; - nstore[endp-startp+1] = 0; - } - else - nstore[endp-startp] = 0; - add_prefix (&exec_prefix, nstore, 0, 0, NULL_PTR); - if (*endp == 0) - break; - endp = startp = endp + 1; - } - else - endp++; - } - } - - temp = getenv ("LIBRARY_PATH"); - if (temp) - { - char *startp, *endp; - char *nstore = (char *) alloca (strlen (temp) + 3); - - startp = endp = temp; - while (1) - { - if (*endp == PATH_SEPARATOR || *endp == 0) - { - strncpy (nstore, startp, endp-startp); - if (endp == startp) - { - strcpy (nstore, "./"); - } - else if (endp[-1] != '/') - { - nstore[endp-startp] = '/'; - nstore[endp-startp+1] = 0; - } - else - nstore[endp-startp] = 0; - add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); - if (*endp == 0) - break; - endp = startp = endp + 1; - } - else - endp++; - } - } - - /* Use LPATH like LIBRARY_PATH (for the CMU build program). */ - temp = getenv ("LPATH"); - if (temp) - { - char *startp, *endp; - char *nstore = (char *) alloca (strlen (temp) + 3); - - startp = endp = temp; - while (1) - { - if (*endp == PATH_SEPARATOR || *endp == 0) - { - strncpy (nstore, startp, endp-startp); - if (endp == startp) - { - strcpy (nstore, "./"); - } - else if (endp[-1] != '/') - { - nstore[endp-startp] = '/'; - nstore[endp-startp+1] = 0; - } - else - nstore[endp-startp] = 0; - add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); - if (*endp == 0) - break; - endp = startp = endp + 1; - } - else - endp++; - } - } - - /* Convert new-style -- options to old-style. */ - translate_options (&argc, &argv); - - /* Scan argv twice. Here, the first time, just count how many switches - there will be in their vector, and how many input files in theirs. - Here we also parse the switches that cc itself uses (e.g. -v). */ - - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "-dumpspecs")) - { - printf ("*asm:\n%s\n\n", asm_spec); - printf ("*asm_final:\n%s\n\n", asm_final_spec); - printf ("*cpp:\n%s\n\n", cpp_spec); - printf ("*cc1:\n%s\n\n", cc1_spec); - printf ("*cc1plus:\n%s\n\n", cc1plus_spec); - printf ("*endfile:\n%s\n\n", endfile_spec); - printf ("*link:\n%s\n\n", link_spec); - printf ("*lib:\n%s\n\n", lib_spec); - printf ("*startfile:\n%s\n\n", startfile_spec); - printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces); - printf ("*signed_char:\n%s\n\n", signed_char_spec); - printf ("*predefines:\n%s\n\n", cpp_predefines); - printf ("*cross_compile:\n%d\n\n", cross_compile); - - exit (0); - } - else if (! strcmp (argv[i], "-dumpversion")) - { - printf ("%s\n", version_string); - exit (0); - } - else if (! strcmp (argv[i], "-print-libgcc-file-name")) - { - print_libgcc_file_name = 1; - } - else if (! strcmp (argv[i], "-Xlinker")) - { - /* Pass the argument of this option to the linker when we link. */ - - if (i + 1 == argc) - fatal ("argument to `-Xlinker' is missing"); - - n_linker_options++; - if (!linker_options) - linker_options - = (char **) xmalloc (n_linker_options * sizeof (char **)); - else - linker_options - = (char **) xrealloc (linker_options, - n_linker_options * sizeof (char **)); - - linker_options[n_linker_options - 1] = argv[++i]; - } - else if (! strncmp (argv[i], "-Wl,", 4)) - { - int prev, j; - /* Pass the rest of this option to the linker when we link. */ - - n_linker_options++; - if (!linker_options) - linker_options - = (char **) xmalloc (n_linker_options * sizeof (char **)); - else - linker_options - = (char **) xrealloc (linker_options, - n_linker_options * sizeof (char **)); - - /* Split the argument at commas. */ - prev = 4; - for (j = 4; argv[i][j]; j++) - if (argv[i][j] == ',') - { - linker_options[n_linker_options - 1] - = save_string (argv[i] + prev, j - prev); - n_linker_options++; - linker_options - = (char **) xrealloc (linker_options, - n_linker_options * sizeof (char **)); - prev = j + 1; - } - /* Record the part after the last comma. */ - linker_options[n_linker_options - 1] = argv[i] + prev; - } - else if (! strncmp (argv[i], "-Wa,", 4)) - { - int prev, j; - /* Pass the rest of this option to the assembler. */ - - n_assembler_options++; - if (!assembler_options) - assembler_options - = (char **) xmalloc (n_assembler_options * sizeof (char **)); - else - assembler_options - = (char **) xrealloc (assembler_options, - n_assembler_options * sizeof (char **)); - - /* Split the argument at commas. */ - prev = 4; - for (j = 4; argv[i][j]; j++) - if (argv[i][j] == ',') - { - assembler_options[n_assembler_options - 1] - = save_string (argv[i] + prev, j - prev); - n_assembler_options++; - assembler_options - = (char **) xrealloc (assembler_options, - n_assembler_options * sizeof (char **)); - prev = j + 1; - } - /* Record the part after the last comma. */ - assembler_options[n_assembler_options - 1] = argv[i] + prev; - } - else if (argv[i][0] == '+' && argv[i][1] == 'e') - /* The +e options to the C++ front-end. */ - n_switches++; - else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') - { - register char *p = &argv[i][1]; - register int c = *p; - - switch (c) - { - case 'b': - if (p[1] == 0 && i + 1 == argc) - fatal ("argument to `-b' is missing"); - if (p[1] == 0) - spec_machine = argv[++i]; - else - spec_machine = p + 1; - break; - - case 'B': - { - int *temp = (int *) xmalloc (sizeof (int)); - char *value; - if (p[1] == 0 && i + 1 == argc) - fatal ("argument to `-B' is missing"); - if (p[1] == 0) - value = argv[++i]; - else - value = p + 1; - add_prefix (&exec_prefix, value, 1, 0, temp); - add_prefix (&startfile_prefix, value, 1, 0, temp); - } - break; - - case 'v': /* Print our subcommands and print versions. */ - n_switches++; - /* If they do anything other than exactly `-v', don't set - verbose_flag; rather, continue on to give the error. */ - if (p[1] != 0) - break; - verbose_flag++; - break; - - case 'V': - if (p[1] == 0 && i + 1 == argc) - fatal ("argument to `-V' is missing"); - if (p[1] == 0) - spec_version = argv[++i]; - else - spec_version = p + 1; - break; - - case 's': - if (!strcmp (p, "save-temps")) - { - save_temps_flag = 1; - n_switches++; - break; - } - default: - n_switches++; - - if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) - i += SWITCH_TAKES_ARG (c) - (p[1] != 0); - else if (WORD_SWITCH_TAKES_ARG (p)) - i += WORD_SWITCH_TAKES_ARG (p); - } - } - else - n_infiles++; - } - - /* Set up the search paths before we go looking for config files. */ - - /* These come before the md prefixes so that we will find gcc's subcommands - (such as cpp) rather than those of the host system. */ - /* Use 2 as fourth arg meaning try just the machine as a suffix, - as well as trying the machine and the version. */ - add_prefix (&exec_prefix, standard_exec_prefix, 0, 2, NULL_PTR); - add_prefix (&exec_prefix, standard_exec_prefix_1, 0, 2, NULL_PTR); - - add_prefix (&startfile_prefix, standard_exec_prefix, 0, 1, NULL_PTR); - add_prefix (&startfile_prefix, standard_exec_prefix_1, 0, 1, NULL_PTR); - -#if 0 - tooldir_prefix = concat (tooldir_base_prefix, spec_machine, "/"); - - /* If tooldir is relative, base it on exec_prefix. A relative - tooldir lets us move the installed tree as a unit. - - If GCC_EXEC_PREFIX is defined, then we want to add two relative - directories, so that we can search both the user specified directory - and the standard place. */ - - if (*tooldir_prefix != '/') - { - if (gcc_exec_prefix) - { - char *gcc_exec_tooldir_prefix - = concat (concat (gcc_exec_prefix, spec_machine, "/"), - concat (spec_version, "/", tooldir_prefix), - ""); - - add_prefix (&exec_prefix, concat (gcc_exec_tooldir_prefix, "bin", "/"), - 0, 0, NULL_PTR); - add_prefix (&startfile_prefix, concat (gcc_exec_tooldir_prefix, "lib", "/"), - 0, 0, NULL_PTR); - } - - tooldir_prefix = concat (concat (standard_exec_prefix, spec_machine, "/"), - concat (spec_version, "/", tooldir_prefix), - ""); - } - - add_prefix (&exec_prefix, concat (tooldir_prefix, "bin", "/"), - 0, 0, NULL_PTR); - add_prefix (&startfile_prefix, concat (tooldir_prefix, "lib", "/"), - 0, 0, NULL_PTR); - - /* More prefixes are enabled in main, after we read the specs file - and determine whether this is cross-compilation or not. */ -#endif - - /* Then create the space for the vectors and scan again. */ - - switches = ((struct switchstr *) - xmalloc ((n_switches + 1) * sizeof (struct switchstr))); - infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile)); - n_switches = 0; - n_infiles = 0; - last_language_n_infiles = -1; - - /* This, time, copy the text of each switch and store a pointer - to the copy in the vector of switches. - Store all the infiles in their vector. */ - - for (i = 1; i < argc; i++) - { - /* Just skip the switches that were handled by the preceding loop. */ - if (!strcmp (argv[i], "-Xlinker")) - i++; - else if (! strncmp (argv[i], "-Wl,", 4)) - ; - else if (! strncmp (argv[i], "-Wa,", 4)) - ; - else if (! strcmp (argv[i], "-print-libgcc-file-name")) - ; - else if (argv[i][0] == '+' && argv[i][1] == 'e') - { - /* Compensate for the +e options to the C++ front-end; - they're there simply for cfront call-compatibility. We do - some magic in default_compilers to pass them down properly. - Note we deliberately start at the `+' here, to avoid passing - -e0 or -e1 down into the linker. */ - switches[n_switches].part1 = &argv[i][0]; - switches[n_switches].args = 0; - switches[n_switches].valid = 0; - n_switches++; - } - else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') - { - register char *p = &argv[i][1]; - register int c = *p; - - if (c == 'B' || c == 'b' || c == 'V') - { - /* Skip a separate arg, if any. */ - if (p[1] == 0) - i++; - continue; - } - if (c == 'x') - { - if (p[1] == 0 && i + 1 == argc) - fatal ("argument to `-x' is missing"); - if (p[1] == 0) - spec_lang = argv[++i]; - else - spec_lang = p + 1; - if (! strcmp (spec_lang, "none")) - /* Suppress the warning if -xnone comes after the last input file, - because alternate command interfaces like g++ might find it - useful to place -xnone after each input file. */ - spec_lang = 0; - else - last_language_n_infiles = n_infiles; - continue; - } - switches[n_switches].part1 = p; - /* Deal with option arguments in separate argv elements. */ - if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) - || WORD_SWITCH_TAKES_ARG (p)) { - int j = 0; - int n_args = WORD_SWITCH_TAKES_ARG (p); - - if (n_args == 0) { - /* Count only the option arguments in separate argv elements. */ - n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); - } - if (i + n_args >= argc) - fatal ("argument to `-%s' is missing", p); - switches[n_switches].args - = (char **) xmalloc ((n_args + 1) * sizeof (char *)); - while (j < n_args) - switches[n_switches].args[j++] = argv[++i]; - /* Null-terminate the vector. */ - switches[n_switches].args[j] = 0; - } else if (*switches_need_spaces != 0 && (c == 'o' || c == 'L')) { - /* On some systems, ld cannot handle -o or -L without space. - So split the -o or -L from its argument. */ - switches[n_switches].part1 = (c == 'o' ? "o" : "L"); - switches[n_switches].args = (char **) xmalloc (2 * sizeof (char *)); - switches[n_switches].args[0] = xmalloc (strlen (p)); - strcpy (switches[n_switches].args[0], &p[1]); - switches[n_switches].args[1] = 0; - } else - switches[n_switches].args = 0; - switches[n_switches].valid = 0; - /* This is always valid, since gcc.c itself understands it. */ - if (!strcmp (p, "save-temps")) - switches[n_switches].valid = 1; - n_switches++; - } - else - { - if ((argv[i][0] != '-' || argv[i][1] != 'l') - && access (argv[i], R_OK) < 0) - { - perror_with_name (argv[i]); - error_count++; - } - else - { - infiles[n_infiles].language = spec_lang; - infiles[n_infiles++].name = argv[i]; - } - } - } - - if (n_infiles == last_language_n_infiles) - error ("Warning: `-x %s' after last input file has no effect", spec_lang); - - switches[n_switches].part1 = 0; - infiles[n_infiles].name = 0; - - /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */ - if (gcc_exec_prefix) - { - temp = (char *) xmalloc (strlen (gcc_exec_prefix) + strlen (spec_version) - + strlen (spec_machine) + 3); - strcpy (temp, gcc_exec_prefix); - strcat (temp, spec_machine); - strcat (temp, "/"); - strcat (temp, spec_version); - strcat (temp, "/"); - gcc_exec_prefix = temp; - } -} - -/* Process a spec string, accumulating and running commands. */ - -/* These variables describe the input file name. - input_file_number is the index on outfiles of this file, - so that the output file name can be stored for later use by %o. - input_basename is the start of the part of the input file - sans all directory names, and basename_length is the number - of characters starting there excluding the suffix .c or whatever. */ - -static char *input_filename; -static int input_file_number; -static int input_filename_length; -static int basename_length; -static char *input_basename; -static char *input_suffix; - -/* These are variables used within do_spec and do_spec_1. */ - -/* Nonzero if an arg has been started and not yet terminated - (with space, tab or newline). */ -static int arg_going; - -/* Nonzero means %d or %g has been seen; the next arg to be terminated - is a temporary file name. */ -static int delete_this_arg; - -/* Nonzero means %w has been seen; the next arg to be terminated - is the output file name of this compilation. */ -static int this_is_output_file; - -/* Nonzero means %s has been seen; the next arg to be terminated - is the name of a library file and we should try the standard - search dirs for it. */ -static int this_is_library_file; - -/* Nonzero means that the input of this command is coming from a pipe. */ -static int input_from_pipe; - -/* Process the spec SPEC and run the commands specified therein. - Returns 0 if the spec is successfully processed; -1 if failed. */ - -static int -do_spec (spec) - char *spec; -{ - int value; - - clear_args (); - arg_going = 0; - delete_this_arg = 0; - this_is_output_file = 0; - this_is_library_file = 0; - input_from_pipe = 0; - - value = do_spec_1 (spec, 0, NULL_PTR); - - /* Force out any unfinished command. - If -pipe, this forces out the last command if it ended in `|'. */ - if (value == 0) - { - if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|")) - argbuf_index--; - - if (argbuf_index > 0) - value = execute (); - } - - return value; -} - -/* Process the sub-spec SPEC as a portion of a larger spec. - This is like processing a whole spec except that we do - not initialize at the beginning and we do not supply a - newline by default at the end. - INSWITCH nonzero means don't process %-sequences in SPEC; - in this case, % is treated as an ordinary character. - This is used while substituting switches. - INSWITCH nonzero also causes SPC not to terminate an argument. - - Value is zero unless a line was finished - and the command on that line reported an error. */ - -static int -do_spec_1 (spec, inswitch, soft_matched_part) - char *spec; - int inswitch; - char *soft_matched_part; -{ - register char *p = spec; - register int c; - int i; - char *string; - int value; - - while (c = *p++) - /* If substituting a switch, treat all chars like letters. - Otherwise, NL, SPC, TAB and % are special. */ - switch (inswitch ? 'a' : c) - { - case '\n': - /* End of line: finish any pending argument, - then run the pending command if one has been started. */ - if (arg_going) - { - obstack_1grow (&obstack, 0); - string = obstack_finish (&obstack); - if (this_is_library_file) - string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); - if (this_is_output_file) - outfiles[input_file_number] = string; - } - arg_going = 0; - - if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|")) - { - int i; - for (i = 0; i < n_switches; i++) - if (!strcmp (switches[i].part1, "pipe")) - break; - - /* A `|' before the newline means use a pipe here, - but only if -pipe was specified. - Otherwise, execute now and don't pass the `|' as an arg. */ - if (i < n_switches) - { - input_from_pipe = 1; - switches[i].valid = 1; - break; - } - else - argbuf_index--; - } - - if (argbuf_index > 0) - { - value = execute (); - if (value) - return value; - } - /* Reinitialize for a new command, and for a new argument. */ - clear_args (); - arg_going = 0; - delete_this_arg = 0; - this_is_output_file = 0; - this_is_library_file = 0; - input_from_pipe = 0; - break; - - case '|': - /* End any pending argument. */ - if (arg_going) - { - obstack_1grow (&obstack, 0); - string = obstack_finish (&obstack); - if (this_is_library_file) - string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); - if (this_is_output_file) - outfiles[input_file_number] = string; - } - - /* Use pipe */ - obstack_1grow (&obstack, c); - arg_going = 1; - break; - - case '\t': - case ' ': - /* Space or tab ends an argument if one is pending. */ - if (arg_going) - { - obstack_1grow (&obstack, 0); - string = obstack_finish (&obstack); - if (this_is_library_file) - string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); - if (this_is_output_file) - outfiles[input_file_number] = string; - } - /* Reinitialize for a new argument. */ - arg_going = 0; - delete_this_arg = 0; - this_is_output_file = 0; - this_is_library_file = 0; - break; - - case '%': - switch (c = *p++) - { - case 0: - fatal ("Invalid specification! Bug in cc."); - - case 'b': - obstack_grow (&obstack, input_basename, basename_length); - arg_going = 1; - break; - - case 'd': - delete_this_arg = 2; - break; - - /* Dump out the directories specified with LIBRARY_PATH, - followed by the absolute directories - that we search for startfiles. */ - case 'D': - { - struct prefix_list *pl = startfile_prefix.plist; - int bufsize = 100; - char *buffer = (char *) xmalloc (bufsize); - int idx; - - for (; pl; pl = pl->next) - { -#ifdef RELATIVE_PREFIX_NOT_LINKDIR - /* Used on systems which record the specified -L dirs - and use them to search for dynamic linking. */ - /* Relative directories always come from -B, - and it is better not to use them for searching - at run time. In particular, stage1 loses */ - if (pl->prefix[0] != '/') - continue; -#endif - if (machine_suffix) - { - if (is_directory (pl->prefix, machine_suffix, 1)) - { - do_spec_1 ("-L", 0, NULL_PTR); -#ifdef SPACE_AFTER_L_OPTION - do_spec_1 (" ", 0, NULL_PTR); -#endif - do_spec_1 (pl->prefix, 1, NULL_PTR); - /* Remove slash from machine_suffix. */ - if (strlen (machine_suffix) >= bufsize) - bufsize = strlen (machine_suffix) * 2 + 1; - buffer = (char *) xrealloc (buffer, bufsize); - strcpy (buffer, machine_suffix); - idx = strlen (buffer); - if (buffer[idx - 1] == '/') - buffer[idx - 1] = 0; - do_spec_1 (buffer, 1, NULL_PTR); - /* Make this a separate argument. */ - do_spec_1 (" ", 0, NULL_PTR); - } - } - if (!pl->require_machine_suffix) - { - if (is_directory (pl->prefix, "", 1)) - { - do_spec_1 ("-L", 0, NULL_PTR); -#ifdef SPACE_AFTER_L_OPTION - do_spec_1 (" ", 0, NULL_PTR); -#endif - /* Remove slash from pl->prefix. */ - if (strlen (pl->prefix) >= bufsize) - bufsize = strlen (pl->prefix) * 2 + 1; - buffer = (char *) xrealloc (buffer, bufsize); - strcpy (buffer, pl->prefix); - idx = strlen (buffer); - if (buffer[idx - 1] == '/') - buffer[idx - 1] = 0; - do_spec_1 (buffer, 1, NULL_PTR); - /* Make this a separate argument. */ - do_spec_1 (" ", 0, NULL_PTR); - } - } - } - free (buffer); - } - break; - - case 'e': - /* {...:%efoo} means report an error with `foo' as error message - and don't execute any more commands for this file. */ - { - char *q = p; - char *buf; - while (*p != 0 && *p != '\n') p++; - buf = (char *) alloca (p - q + 1); - strncpy (buf, q, p - q); - buf[p - q] = 0; - error ("%s", buf); - return -1; - } - break; - - case 'g': - case 'u': - case 'U': - if (save_temps_flag) - obstack_grow (&obstack, input_basename, basename_length); - else - { -#ifdef MKTEMP_EACH_FILE - /* ??? This has a problem: the total number of - values mktemp can return is limited. - That matters for the names of object files. - In 2.4, do something about that. */ - struct temp_name *t; - char *suffix = p; - while (*p == '.' || isalpha (*p)) - p++; - - /* See if we already have an association of %g/%u/%U and - suffix. */ - for (t = temp_names; t; t = t->next) - if (t->length == p - suffix - && strncmp (t->suffix, suffix, p - suffix) == 0 - && t->unique == (c != 'g')) - break; - - /* Make a new association if needed. %u requires one. */ - if (t == 0 || c == 'u') - { - if (t == 0) - { - t = (struct temp_name *) xmalloc (sizeof (struct temp_name)); - t->next = temp_names; - temp_names = t; - } - t->length = p - suffix; - t->suffix = save_string (suffix, p - suffix); - t->unique = (c != 'g'); - choose_temp_base (); - t->filename = temp_filename; - t->filename_length = temp_filename_length; - } - - obstack_grow (&obstack, t->filename, t->filename_length); - delete_this_arg = 1; -#else - obstack_grow (&obstack, temp_filename, temp_filename_length); - if (c == 'u' || c == 'U') - { - static int unique; - char buff[9]; - if (c == 'u') - unique++; - sprintf (buff, "%d", unique); - obstack_grow (&obstack, buff, strlen (buff)); - } -#endif - delete_this_arg = 1; - } - arg_going = 1; - break; - - case 'i': - obstack_grow (&obstack, input_filename, input_filename_length); - arg_going = 1; - break; - - case 'I': - if (gcc_exec_prefix) - { - do_spec_1 ("-iprefix", 1, NULL_PTR); - /* Make this a separate argument. */ - do_spec_1 (" ", 0, NULL_PTR); - do_spec_1 (gcc_exec_prefix, 1, NULL_PTR); - do_spec_1 (" ", 0, NULL_PTR); - } - break; - - case 'o': - { - register int f; - for (f = 0; f < n_infiles; f++) - store_arg (outfiles[f], 0, 0); - } - break; - - case 's': - this_is_library_file = 1; - break; - - case 'w': - this_is_output_file = 1; - break; - - case 'W': - { - int index = argbuf_index; - /* Handle the {...} following the %W. */ - if (*p != '{') - abort (); - p = handle_braces (p + 1); - if (p == 0) - return -1; - /* If any args were output, mark the last one for deletion - on failure. */ - if (argbuf_index != index) - record_temp_file (argbuf[argbuf_index - 1], 0, 1); - break; - } - - /* %x{OPTION} records OPTION for %X to output. */ - case 'x': - { - char *p1 = p; - char *string; - - /* Skip past the option value and make a copy. */ - if (*p != '{') - abort (); - while (*p++ != '}') - ; - string = save_string (p1 + 1, p - p1 - 2); - - /* See if we already recorded this option. */ - for (i = 0; i < n_linker_options; i++) - if (! strcmp (string, linker_options[i])) - { - free (string); - return 0; - } - - /* This option is new; add it. */ - n_linker_options++; - if (!linker_options) - linker_options - = (char **) xmalloc (n_linker_options * sizeof (char **)); - else - linker_options - = (char **) xrealloc (linker_options, - n_linker_options * sizeof (char **)); - - linker_options[n_linker_options - 1] = string; - } - break; - - /* Dump out the options accumulated previously using %x, - -Xlinker and -Wl,. */ - case 'X': - for (i = 0; i < n_linker_options; i++) - { - do_spec_1 (linker_options[i], 1, NULL_PTR); - /* Make each accumulated option a separate argument. */ - do_spec_1 (" ", 0, NULL_PTR); - } - break; - - /* Dump out the options accumulated previously using -Wa,. */ - case 'Y': - for (i = 0; i < n_assembler_options; i++) - { - do_spec_1 (assembler_options[i], 1, NULL_PTR); - /* Make each accumulated option a separate argument. */ - do_spec_1 (" ", 0, NULL_PTR); - } - break; - - /* Here are digits and numbers that just process - a certain constant string as a spec. */ - - case '1': - value = do_spec_1 (cc1_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case '2': - value = do_spec_1 (cc1plus_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'a': - value = do_spec_1 (asm_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'A': - value = do_spec_1 (asm_final_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'c': - value = do_spec_1 (signed_char_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'C': - value = do_spec_1 (cpp_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'E': - value = do_spec_1 (endfile_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'l': - value = do_spec_1 (link_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'L': - value = do_spec_1 (lib_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - case 'p': - { - char *x = (char *) alloca (strlen (cpp_predefines) + 1); - char *buf = x; - char *y; - - /* Copy all of the -D options in CPP_PREDEFINES into BUF. */ - y = cpp_predefines; - while (*y != 0) - { - if (! strncmp (y, "-D", 2)) - /* Copy the whole option. */ - while (*y && *y != ' ' && *y != '\t') - *x++ = *y++; - else if (*y == ' ' || *y == '\t') - /* Copy whitespace to the result. */ - *x++ = *y++; - /* Don't copy other options. */ - else - y++; - } - - *x = 0; - - value = do_spec_1 (buf, 0, NULL_PTR); - if (value != 0) - return value; - } - break; - - case 'P': - { - char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1); - char *buf = x; - char *y; - - /* Copy all of CPP_PREDEFINES into BUF, - but put __ after every -D and at the end of each arg. */ - y = cpp_predefines; - while (*y != 0) - { - if (! strncmp (y, "-D", 2)) - { - int flag = 0; - - *x++ = *y++; - *x++ = *y++; - - if (strncmp (y, "__", 2)) - { - /* Stick __ at front of macro name. */ - *x++ = '_'; - *x++ = '_'; - /* Arrange to stick __ at the end as well. */ - flag = 1; - } - - /* Copy the macro name. */ - while (*y && *y != '=' && *y != ' ' && *y != '\t') - *x++ = *y++; - - if (flag) - { - *x++ = '_'; - *x++ = '_'; - } - - /* Copy the value given, if any. */ - while (*y && *y != ' ' && *y != '\t') - *x++ = *y++; - } - else if (*y == ' ' || *y == '\t') - /* Copy whitespace to the result. */ - *x++ = *y++; - /* Don't copy -A options */ - else - y++; - } - *x++ = ' '; - - /* Copy all of CPP_PREDEFINES into BUF, - but put __ after every -D. */ - y = cpp_predefines; - while (*y != 0) - { - if (! strncmp (y, "-D", 2)) - { - *x++ = *y++; - *x++ = *y++; - - if (strncmp (y, "__", 2)) - { - /* Stick __ at front of macro name. */ - *x++ = '_'; - *x++ = '_'; - } - - /* Copy the macro name. */ - while (*y && *y != '=' && *y != ' ' && *y != '\t') - *x++ = *y++; - - /* Copy the value given, if any. */ - while (*y && *y != ' ' && *y != '\t') - *x++ = *y++; - } - else if (*y == ' ' || *y == '\t') - /* Copy whitespace to the result. */ - *x++ = *y++; - /* Don't copy -A options */ - else - y++; - } - *x++ = ' '; - - /* Copy all of the -A options in CPP_PREDEFINES into BUF. */ - y = cpp_predefines; - while (*y != 0) - { - if (! strncmp (y, "-A", 2)) - /* Copy the whole option. */ - while (*y && *y != ' ' && *y != '\t') - *x++ = *y++; - else if (*y == ' ' || *y == '\t') - /* Copy whitespace to the result. */ - *x++ = *y++; - /* Don't copy other options. */ - else - y++; - } - - *x = 0; - - value = do_spec_1 (buf, 0, NULL_PTR); - if (value != 0) - return value; - } - break; - - case 'S': - value = do_spec_1 (startfile_spec, 0, NULL_PTR); - if (value != 0) - return value; - break; - - /* Here we define characters other than letters and digits. */ - - case '{': - p = handle_braces (p); - if (p == 0) - return -1; - break; - - case '%': - obstack_1grow (&obstack, '%'); - break; - - case '*': - do_spec_1 (soft_matched_part, 1, NULL_PTR); - do_spec_1 (" ", 0, NULL_PTR); - break; - - /* Process a string found as the value of a spec given by name. - This feature allows individual machine descriptions - to add and use their own specs. - %[...] modifies -D options the way %P does; - %(...) uses the spec unmodified. */ - case '(': - case '[': - { - char *name = p; - struct spec_list *sl; - int len; - - /* The string after the S/P is the name of a spec that is to be - processed. */ - while (*p && *p != ')' && *p != ']') - p++; - - /* See if it's in the list */ - for (len = p - name, sl = specs; sl; sl = sl->next) - if (strncmp (sl->name, name, len) == 0 && !sl->name[len]) - { - name = sl->spec; - break; - } - - if (sl) - { - if (c == '(') - { - value = do_spec_1 (name, 0, NULL_PTR); - if (value != 0) - return value; - } - else - { - char *x = (char *) alloca (strlen (name) * 2 + 1); - char *buf = x; - char *y = name; - - /* Copy all of NAME into BUF, but put __ after - every -D and at the end of each arg, */ - while (1) - { - if (! strncmp (y, "-D", 2)) - { - *x++ = '-'; - *x++ = 'D'; - *x++ = '_'; - *x++ = '_'; - y += 2; - } - else if (*y == ' ' || *y == 0) - { - *x++ = '_'; - *x++ = '_'; - if (*y == 0) - break; - else - *x++ = *y++; - } - else - *x++ = *y++; - } - *x = 0; - - value = do_spec_1 (buf, 0, NULL_PTR); - if (value != 0) - return value; - } - } - - /* Discard the closing paren or bracket. */ - if (*p) - p++; - } - break; - - case '|': - if (input_from_pipe) - do_spec_1 ("-", 0, NULL_PTR); - break; - - default: - abort (); - } - break; - - case '\\': - /* Backslash: treat next character as ordinary. */ - c = *p++; - - /* fall through */ - default: - /* Ordinary character: put it into the current argument. */ - obstack_1grow (&obstack, c); - arg_going = 1; - } - - return 0; /* End of string */ -} - -/* Return 0 if we call do_spec_1 and that returns -1. */ - -static char * -handle_braces (p) - register char *p; -{ - register char *q; - char *filter; - int pipe = 0; - int negate = 0; - int suffix = 0; - - if (*p == '|') - /* A `|' after the open-brace means, - if the test fails, output a single minus sign rather than nothing. - This is used in %{|!pipe:...}. */ - pipe = 1, ++p; - - if (*p == '!') - /* A `!' after the open-brace negates the condition: - succeed if the specified switch is not present. */ - negate = 1, ++p; - - if (*p == '.') - /* A `.' after the open-brace means test against the current suffix. */ - { - if (pipe) - abort (); - - suffix = 1; - ++p; - } - - filter = p; - while (*p != ':' && *p != '}') p++; - if (*p != '}') - { - register int count = 1; - q = p + 1; - while (count > 0) - { - if (*q == '{') - count++; - else if (*q == '}') - count--; - else if (*q == 0) - abort (); - q++; - } - } - else - q = p + 1; - - if (suffix) - { - int found = (input_suffix != 0 - && strlen (input_suffix) == p - filter - && strncmp (input_suffix, filter, p - filter) == 0); - - if (p[0] == '}') - abort (); - - if (negate != found - && do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) - return 0; - - return q; - } - else if (p[-1] == '*' && p[0] == '}') - { - /* Substitute all matching switches as separate args. */ - register int i; - --p; - for (i = 0; i < n_switches; i++) - if (!strncmp (switches[i].part1, filter, p - filter)) - give_switch (i, 0); - } - else - { - /* Test for presence of the specified switch. */ - register int i; - int present = 0; - - /* If name specified ends in *, as in {x*:...}, - check for %* and handle that case. */ - if (p[-1] == '*' && !negate) - { - int substitution; - char *r = p; - - /* First see whether we have %*. */ - substitution = 0; - while (r < q) - { - if (*r == '%' && r[1] == '*') - substitution = 1; - r++; - } - /* If we do, handle that case. */ - if (substitution) - { - /* Substitute all matching switches as separate args. - But do this by substituting for %* - in the text that follows the colon. */ - - unsigned hard_match_len = p - filter - 1; - char *string = save_string (p + 1, q - p - 2); - - for (i = 0; i < n_switches; i++) - if (!strncmp (switches[i].part1, filter, hard_match_len)) - { - do_spec_1 (string, 0, &switches[i].part1[hard_match_len]); - /* Pass any arguments this switch has. */ - give_switch (i, 1); - } - - return q; - } - } - - /* If name specified ends in *, as in {x*:...}, - check for presence of any switch name starting with x. */ - if (p[-1] == '*') - { - for (i = 0; i < n_switches; i++) - { - unsigned hard_match_len = p - filter - 1; - - if (!strncmp (switches[i].part1, filter, hard_match_len)) - { - switches[i].valid = 1; - present = 1; - } - } - } - /* Otherwise, check for presence of exact name specified. */ - else - { - for (i = 0; i < n_switches; i++) - { - if (!strncmp (switches[i].part1, filter, p - filter) - && switches[i].part1[p - filter] == 0) - { - switches[i].valid = 1; - present = 1; - break; - } - } - } - - /* If it is as desired (present for %{s...}, absent for %{-s...}) - then substitute either the switch or the specified - conditional text. */ - if (present != negate) - { - if (*p == '}') - { - give_switch (i, 0); - } - else - { - if (do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) - return 0; - } - } - else if (pipe) - { - /* Here if a %{|...} conditional fails: output a minus sign, - which means "standard output" or "standard input". */ - do_spec_1 ("-", 0, NULL_PTR); - } - } - - return q; -} - -/* Pass a switch to the current accumulating command - in the same form that we received it. - SWITCHNUM identifies the switch; it is an index into - the vector of switches gcc received, which is `switches'. - This cannot fail since it never finishes a command line. - - If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */ - -static void -give_switch (switchnum, omit_first_word) - int switchnum; - int omit_first_word; -{ - if (!omit_first_word) - { - do_spec_1 ("-", 0, NULL_PTR); - do_spec_1 (switches[switchnum].part1, 1, NULL_PTR); - } - do_spec_1 (" ", 0, NULL_PTR); - if (switches[switchnum].args != 0) - { - char **p; - for (p = switches[switchnum].args; *p; p++) - { - do_spec_1 (*p, 1, NULL_PTR); - do_spec_1 (" ", 0, NULL_PTR); - } - } - switches[switchnum].valid = 1; -} - -/* Search for a file named NAME trying various prefixes including the - user's -B prefix and some standard ones. - Return the absolute file name found. If nothing is found, return NAME. */ - -static char * -find_file (name) - char *name; -{ - char *newname; - - newname = find_a_file (&startfile_prefix, name, R_OK); - return newname ? newname : name; -} - -/* Determine whether a directory exists. If LINKER, return 0 for - certain fixed names not needed by the linker. If not LINKER, it is - only important to return 0 if the host machine has a small ARG_MAX - limit. */ - -static int -is_directory (path1, path2, linker) - char *path1; - char *path2; - int linker; -{ - int len1 = strlen (path1); - int len2 = strlen (path2); - char *path = (char *) alloca (3 + len1 + len2); - char *cp; - struct stat st; - -#ifndef SMALL_ARG_MAX - if (! linker) - return 1; -#endif - - /* Construct the path from the two parts. Ensure the string ends with "/.". - The resulting path will be a directory even if the given path is a - symbolic link. */ - bcopy (path1, path, len1); - bcopy (path2, path + len1, len2); - cp = path + len1 + len2; - if (cp[-1] != '/') - *cp++ = '/'; - *cp++ = '.'; - *cp = '\0'; - - /* Exclude directories that the linker is known to search. */ - if (linker - && ((cp - path == 6 && strcmp (path, "/lib/.") == 0) - || (cp - path == 10 && strcmp (path, "/usr/lib/.") == 0))) - return 0; - - return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode)); -} - -/* On fatal signals, delete all the temporary files. */ - -static void -fatal_error (signum) - int signum; -{ - signal (signum, SIG_DFL); - delete_failure_queue (); - delete_temp_files (); - /* Get the same signal again, this time not handled, - so its normal effect occurs. */ - kill (getpid (), signum); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - register int i; - int j; - int value; - int linker_was_run = 0; - char *explicit_link_files; - char *specs_file; - char *p; - - p = argv[0] + strlen (argv[0]); - while (p != argv[0] && p[-1] != '/') --p; - programname = p; - - if (signal (SIGINT, SIG_IGN) != SIG_IGN) - signal (SIGINT, fatal_error); -#ifdef SIGHUP - if (signal (SIGHUP, SIG_IGN) != SIG_IGN) - signal (SIGHUP, fatal_error); -#endif - if (signal (SIGTERM, SIG_IGN) != SIG_IGN) - signal (SIGTERM, fatal_error); -#ifdef SIGPIPE - if (signal (SIGPIPE, SIG_IGN) != SIG_IGN) - signal (SIGPIPE, fatal_error); -#endif - - argbuf_length = 10; - argbuf = (char **) xmalloc (argbuf_length * sizeof (char *)); - - obstack_init (&obstack); - - /* Set up to remember the pathname of gcc and any options - needed for collect. We use argv[0] instead of programname because - we need the complete pathname. */ - obstack_init (&collect_obstack); - obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1); - obstack_grow (&collect_obstack, argv[0], strlen (argv[0])+1); - putenv (obstack_finish (&collect_obstack)); - - /* Choose directory for temp files. */ - - choose_temp_base (); - - /* Make a table of what switches there are (switches, n_switches). - Make a table of specified input files (infiles, n_infiles). - Decode switches that are handled locally. */ - - process_command (argc, argv); - - /* Initialize the vector of specs to just the default. - This means one element containing 0s, as a terminator. */ - - compilers = (struct compiler *) xmalloc (sizeof default_compilers); - bcopy (default_compilers, compilers, sizeof default_compilers); - n_compilers = n_default_compilers; - - /* Read specs from a file if there is one. */ - - machine_suffix = concat (spec_machine, "/", concat (spec_version, "/", "")); - just_machine_suffix = concat (spec_machine, "/", ""); - - specs_file = find_a_file (&startfile_prefix, "specs", R_OK); - /* Read the specs file unless it is a default one. */ - if (specs_file != 0 && strcmp (specs_file, "specs")) - read_specs (specs_file); - - /* If not cross-compiling, look for startfiles in the standard places. */ - /* The fact that these are done here, after reading the specs file, - means that it cannot be found in these directories. - But that's okay. It should never be there anyway. */ - if (!cross_compile) - { -#ifdef MD_EXEC_PREFIX - add_prefix (&exec_prefix, md_exec_prefix, 0, 0, NULL_PTR); - add_prefix (&startfile_prefix, md_exec_prefix, 0, 0, NULL_PTR); -#endif - -#ifdef MD_STARTFILE_PREFIX - add_prefix (&startfile_prefix, md_startfile_prefix, 0, 0, NULL_PTR); -#endif - -#ifdef MD_STARTFILE_PREFIX_1 - add_prefix (&startfile_prefix, md_startfile_prefix_1, 0, 0, NULL_PTR); -#endif - - add_prefix (&startfile_prefix, standard_startfile_prefix, 0, 0, - NULL_PTR); - add_prefix (&startfile_prefix, standard_startfile_prefix_1, 0, 0, - NULL_PTR); - add_prefix (&startfile_prefix, standard_startfile_prefix_2, 0, 0, - NULL_PTR); -#if 0 /* Can cause surprises, and one can use -B./ instead. */ - add_prefix (&startfile_prefix, "./", 0, 1, NULL_PTR); -#endif - } - - /* Now we have the specs. - Set the `valid' bits for switches that match anything in any spec. */ - - validate_all_switches (); - - /* Warn about any switches that no pass was interested in. */ - - for (i = 0; i < n_switches; i++) - if (! switches[i].valid) - error ("unrecognized option `-%s'", switches[i].part1); - - if (print_libgcc_file_name) - { - printf ("%s\n", find_file ("libgcc.a")); - exit (0); - } - - /* Obey some of the options. */ - - if (verbose_flag) - { - fprintf (stderr, "gcc version %s\n", version_string); - if (n_infiles == 0) - exit (0); - } - - if (n_infiles == 0) - fatal ("No input files specified."); - - /* Make a place to record the compiler output file names - that correspond to the input files. */ - - outfiles = (char **) xmalloc (n_infiles * sizeof (char *)); - bzero (outfiles, n_infiles * sizeof (char *)); - - /* Record which files were specified explicitly as link input. */ - - explicit_link_files = xmalloc (n_infiles); - bzero (explicit_link_files, n_infiles); - - for (i = 0; i < n_infiles; i++) - { - register struct compiler *cp = 0; - int this_file_error = 0; - - /* Tell do_spec what to substitute for %i. */ - - input_filename = infiles[i].name; - input_filename_length = strlen (input_filename); - input_file_number = i; - - /* Use the same thing in %o, unless cp->spec says otherwise. */ - - outfiles[i] = input_filename; - - /* Figure out which compiler from the file's suffix. */ - - cp = lookup_compiler (infiles[i].name, input_filename_length, - infiles[i].language); - - if (cp) - { - /* Ok, we found an applicable compiler. Run its spec. */ - /* First say how much of input_filename to substitute for %b */ - register char *p; - int len; - - input_basename = input_filename; - for (p = input_filename; *p; p++) - if (*p == '/') - input_basename = p + 1; - - /* Find a suffix starting with the last period, - and set basename_length to exclude that suffix. */ - basename_length = strlen (input_basename); - p = input_basename + basename_length; - while (p != input_basename && *p != '.') --p; - if (*p == '.' && p != input_basename) - { - basename_length = p - input_basename; - input_suffix = p + 1; - } - else - input_suffix = ""; - - len = 0; - for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++) - if (cp->spec[j]) - len += strlen (cp->spec[j]); - - p = (char *) xmalloc (len + 1); - - len = 0; - for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++) - if (cp->spec[j]) - { - strcpy (p + len, cp->spec[j]); - len += strlen (cp->spec[j]); - } - - value = do_spec (p); - free (p); - if (value < 0) - this_file_error = 1; - } - - /* If this file's name does not contain a recognized suffix, - record it as explicit linker input. */ - - else - explicit_link_files[i] = 1; - - /* Clear the delete-on-failure queue, deleting the files in it - if this compilation failed. */ - - if (this_file_error) - { - delete_failure_queue (); - error_count++; - } - /* If this compilation succeeded, don't delete those files later. */ - clear_failure_queue (); - } - - /* Run ld to link all the compiler output files. */ - - if (error_count == 0) - { - int tmp = execution_count; - int i; - int first_time; - - /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables - for collect. */ - putenv_from_prefixes (&exec_prefix, "COMPILER_PATH="); - putenv_from_prefixes (&startfile_prefix, "LIBRARY_PATH="); - - /* Build COLLECT_GCC_OPTIONS to have all of the options specified to - the compiler. */ - obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=", - sizeof ("COLLECT_GCC_OPTIONS=")-1); - - first_time = TRUE; - for (i = 0; i < n_switches; i++) - { - char **args; - if (!first_time) - obstack_grow (&collect_obstack, " ", 1); - - first_time = FALSE; - obstack_grow (&collect_obstack, "-", 1); - obstack_grow (&collect_obstack, switches[i].part1, - strlen (switches[i].part1)); - - for (args = switches[i].args; args && *args; args++) - { - obstack_grow (&collect_obstack, " ", 1); - obstack_grow (&collect_obstack, *args, strlen (*args)); - } - } - obstack_grow (&collect_obstack, "\0", 1); - putenv (obstack_finish (&collect_obstack)); - - value = do_spec (link_command_spec); - if (value < 0) - error_count = 1; - linker_was_run = (tmp != execution_count); - } - - /* Warn if a -B option was specified but the prefix was never used. */ - unused_prefix_warnings (&exec_prefix); - unused_prefix_warnings (&startfile_prefix); - - /* If options said don't run linker, - complain about input files to be given to the linker. */ - - if (! linker_was_run && error_count == 0) - for (i = 0; i < n_infiles; i++) - if (explicit_link_files[i]) - error ("%s: linker input file unused since linking not done", - outfiles[i]); - - /* Delete some or all of the temporary files we made. */ - - if (error_count) - delete_failure_queue (); - delete_temp_files (); - - exit (error_count > 0 ? (signal_count ? 2 : 1) : 0); - /* NOTREACHED */ - return 0; -} - -/* Find the proper compilation spec for the file name NAME, - whose length is LENGTH. LANGUAGE is the specified language, - or 0 if none specified. */ - -static struct compiler * -lookup_compiler (name, length, language) - char *name; - int length; - char *language; -{ - struct compiler *cp; - - /* Look for the language, if one is spec'd. */ - if (language != 0) - { - for (cp = compilers + n_compilers - 1; cp >= compilers; cp--) - { - if (language != 0) - { - if (cp->suffix[0] == '@' - && !strcmp (cp->suffix + 1, language)) - return cp; - } - } - error ("language %s not recognized", language); - } - - /* Look for a suffix. */ - for (cp = compilers + n_compilers - 1; cp >= compilers; cp--) - { - if (/* The suffix `-' matches only the file name `-'. */ - (!strcmp (cp->suffix, "-") && !strcmp (name, "-")) - || - (strlen (cp->suffix) < length - /* See if the suffix matches the end of NAME. */ - && !strcmp (cp->suffix, - name + length - strlen (cp->suffix)))) - { - if (cp->spec[0][0] == '@') - { - struct compiler *new; - /* An alias entry maps a suffix to a language. - Search for the language; pass 0 for NAME and LENGTH - to avoid infinite recursion if language not found. - Construct the new compiler spec. */ - language = cp->spec[0] + 1; - new = (struct compiler *) xmalloc (sizeof (struct compiler)); - new->suffix = cp->suffix; - bcopy (lookup_compiler (NULL_PTR, 0, language)->spec, - new->spec, sizeof new->spec); - return new; - } - /* A non-alias entry: return it. */ - return cp; - } - } - - return 0; -} - -char * -xmalloc (size) - unsigned size; -{ - register char *value = (char *) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; -{ - register char *value = (char *) realloc (ptr, size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ - -static char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - *(result + len1 + len2 + len3) = 0; - - return result; -} - -static char * -save_string (s, len) - char *s; - int len; -{ - register char *result = xmalloc (len + 1); - - bcopy (s, result, len); - result[len] = 0; - return result; -} - -static void -pfatal_with_name (name) - char *name; -{ - char *s; - - if (errno < sys_nerr) - s = concat ("%s: ", sys_errlist[errno], ""); - else - s = "cannot open %s"; - fatal (s, name); -} - -static void -perror_with_name (name) - char *name; -{ - char *s; - - if (errno < sys_nerr) - s = concat ("%s: ", sys_errlist[errno], ""); - else - s = "cannot open %s"; - error (s, name); -} - -static void -perror_exec (name) - char *name; -{ - char *s; - - if (errno < sys_nerr) - s = concat ("installation problem, cannot exec %s: ", - sys_errlist[errno], ""); - else - s = "installation problem, cannot exec %s"; - error (s, name); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - -#ifdef HAVE_VPRINTF - -/* Output an error message and exit */ - -static void -fatal (va_alist) - va_dcl -{ - va_list ap; - char *format; - - va_start (ap); - format = va_arg (ap, char *); - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, format, ap); - va_end (ap); - fprintf (stderr, "\n"); - delete_temp_files (); - exit (1); -} - -static void -error (va_alist) - va_dcl -{ - va_list ap; - char *format; - - va_start (ap); - format = va_arg (ap, char *); - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, format, ap); - va_end (ap); - - fprintf (stderr, "\n"); -} - -#else /* not HAVE_VPRINTF */ - -static void -fatal (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - error (msg, arg1, arg2); - delete_temp_files (); - exit (1); -} - -static void -error (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - fprintf (stderr, "%s: ", programname); - fprintf (stderr, msg, arg1, arg2); - fprintf (stderr, "\n"); -} - -#endif /* not HAVE_VPRINTF */ - - -static void -validate_all_switches () -{ - struct compiler *comp; - register char *p; - register char c; - struct spec_list *spec; - - for (comp = compilers; comp->spec[0]; comp++) - { - int i; - for (i = 0; i < sizeof comp->spec / sizeof comp->spec[0] && comp->spec[i]; i++) - { - p = comp->spec[i]; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - } - } - - /* look through the linked list of extra specs read from the specs file */ - for (spec = specs; spec ; spec = spec->next) - { - p = spec->spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - } - - p = link_command_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - /* Now notice switches mentioned in the machine-specific specs. */ - - p = asm_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = asm_final_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = cpp_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = signed_char_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = cc1_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = cc1plus_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = link_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = lib_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); - - p = startfile_spec; - while (c = *p++) - if (c == '%' && *p == '{') - /* We have a switch spec. */ - validate_switches (p + 1); -} - -/* Look at the switch-name that comes after START - and mark as valid all supplied switches that match it. */ - -static void -validate_switches (start) - char *start; -{ - register char *p = start; - char *filter; - register int i; - int suffix = 0; - - if (*p == '|') - ++p; - - if (*p == '!') - ++p; - - if (*p == '.') - suffix = 1, ++p; - - filter = p; - while (*p != ':' && *p != '}') p++; - - if (suffix) - ; - else if (p[-1] == '*') - { - /* Mark all matching switches as valid. */ - --p; - for (i = 0; i < n_switches; i++) - if (!strncmp (switches[i].part1, filter, p - filter)) - switches[i].valid = 1; - } - else - { - /* Mark an exact matching switch as valid. */ - for (i = 0; i < n_switches; i++) - { - if (!strncmp (switches[i].part1, filter, p - filter) - && switches[i].part1[p - filter] == 0) - switches[i].valid = 1; - } - } -} diff --git a/gnu/usr.bin/gcc2/cc1/Makefile b/gnu/usr.bin/gcc2/cc1/Makefile deleted file mode 100644 index 4e5529d0803..00000000000 --- a/gnu/usr.bin/gcc2/cc1/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# from: @(#)Makefile 6.2 (Berkeley) 2/2/91 -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $ - -PROG= cc1 - -SRCS= c-parse.c c-lang.c c-lex.c c-pragma.c c-decl.c \ - c-typeck.c c-convert.c c-aux-info.c c-iterate.c - -.if make(clean) || make(cleandir) -.include <../Makefile.cc1> -.elif ${MACHINE} == "pc532" - -all: - @echo "The standard cc1 for the pc532 is not working." - @echo "Use the distribution /usr/libexec/cc1." - -install: - @echo "The standard cc1 for the pc532 is not working." - @echo "Use the distribution /usr/libexec/cc1." - -.else -.include <../Makefile.cc1> -.endif diff --git a/gnu/usr.bin/gcc2/cc1/c-aux-info.c b/gnu/usr.bin/gcc2/cc1/c-aux-info.c deleted file mode 100644 index 7f89d64f5fa..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-aux-info.c +++ /dev/null @@ -1,646 +0,0 @@ -/* Generate information regarding function declarations and definitions based - on information stored in GCC's tree structure. This code implements the - -aux-info option. - - This code was written by Ron Guilmette (rfg@mcc.com). - - Copyright (C) 1989, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-aux-info.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "flags.h" -#include "tree.h" -#include "c-tree.h" - -extern char* xmalloc (); - -enum formals_style_enum { - ansi, - k_and_r_names, - k_and_r_decls -}; -typedef enum formals_style_enum formals_style; - - -static char* data_type; - -static char * concat (); -static char * concat3 (); -static char * gen_formal_list_for_type (); -static int deserves_ellipsis (); -static char * gen_formal_list_for_func_def (); -static char * gen_type (); -static char * gen_decl (); -void gen_aux_info_record (); - -/* Take two strings and mash them together into a newly allocated area. */ - -static char* -concat (s1, s2) - char* s1; - char* s2; -{ - int size1, size2; - char* ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - ret_val = xmalloc (size1 + size2 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - return ret_val; -} - -/* Take three strings and mash them together into a newly allocated area. */ - -static char* -concat3 (s1, s2, s3) - char* s1; - char* s2; - char* s3; -{ - int size1, size2, size3; - char* ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - if (!s3) - s3 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - size3 = strlen (s3); - ret_val = xmalloc (size1 + size2 + size3 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - strcpy (&ret_val[size1+size2], s3); - return ret_val; -} - -/* Given a string representing an entire type or an entire declaration - which only lacks the actual "data-type" specifier (at its left end), - affix the data-type specifier to the left end of the given type - specification or object declaration. - - Because of C language weirdness, the data-type specifier (which normally - goes in at the very left end) may have to be slipped in just to the - right of any leading "const" or "volatile" qualifiers (there may be more - than one). Actually this may not be strictly necessary because it seems - that GCC (at least) accepts ` const foo;' and treats it the - same as `const foo;' but people are accustomed to seeing - `const char *foo;' and *not* `char const *foo;' so we try to create types - that look as expected. */ - -static char* -affix_data_type (type_or_decl) - char *type_or_decl; -{ - char *p = type_or_decl; - char *qualifiers_then_data_type; - char saved; - - /* Skip as many leading const's or volatile's as there are. */ - - for (;;) - { - if (!strncmp (p, "volatile ", 9)) - { - p += 9; - continue; - } - if (!strncmp (p, "const ", 6)) - { - p += 6; - continue; - } - break; - } - - /* p now points to the place where we can insert the data type. We have to - add a blank after the data-type of course. */ - - if (p == type_or_decl) - return concat3 (data_type, " ", type_or_decl); - - saved = *p; - *p = '\0'; - qualifiers_then_data_type = concat (type_or_decl, data_type); - *p = saved; - return concat3 (qualifiers_then_data_type, " ", p); -} - -/* Given a tree node which represents some "function type", generate the - source code version of a formal parameter list (of some given style) for - this function type. Return the whole formal parameter list (including - a pair of surrounding parens) as a string. Note that if the style - we are currently aiming for is non-ansi, then we just return a pair - of empty parens here. */ - -static char* -gen_formal_list_for_type (fntype, style) - tree fntype; - formals_style style; -{ - char* formal_list = ""; - tree formal_type; - - if (style != ansi) - return "()"; - - formal_type = TYPE_ARG_TYPES (fntype); - while (formal_type && TREE_VALUE (formal_type) != void_type_node) - { - char* this_type; - - if (*formal_list) - formal_list = concat (formal_list, ", "); - - this_type = gen_type ("", TREE_VALUE (formal_type), ansi); - formal_list = - (strlen (this_type)) - ? concat (formal_list, affix_data_type (this_type)) - : concat (formal_list, data_type); - - formal_type = TREE_CHAIN (formal_type); - } - - /* If we got to here, then we are trying to generate an ANSI style formal - parameters list. - - New style prototyped ANSI formal parameter lists should in theory always - contain some stuff between the opening and closing parens, even if it is - only "void". - - The brutal truth though is that there is lots of old K&R code out there - which contains declarations of "pointer-to-function" parameters and - these almost never have fully specified formal parameter lists associated - with them. That is, the pointer-to-function parameters are declared - with just empty parameter lists. - - In cases such as these, protoize should really insert *something* into - the vacant parameter lists, but what? It has no basis on which to insert - anything in particular. - - Here, we make life easy for protoize by trying to distinguish between - K&R empty parameter lists and new-style prototyped parameter lists - that actually contain "void". In the latter case we (obviously) want - to output the "void" verbatim, and that what we do. In the former case, - we do our best to give protoize something nice to insert. - - This "something nice" should be something that is still legal (when - re-compiled) but something that can clearly indicate to the user that - more typing information (for the parameter list) should be added (by - hand) at some convenient moment. - - The string chosen here is a comment with question marks in it. */ - - if (!*formal_list) - { - if (TYPE_ARG_TYPES (fntype)) - /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */ - formal_list = "void"; - else - formal_list = "/* ??? */"; - } - else - { - /* If there were at least some parameters, and if the formals-types-list - petered out to a NULL (i.e. without being terminated by a - void_type_node) then we need to tack on an ellipsis. */ - if (!formal_type) - formal_list = concat (formal_list, ", ..."); - } - - return concat3 (" (", formal_list, ")"); -} - -/* For the generation of an ANSI prototype for a function definition, we have - to look at the formal parameter list of the function's own "type" to - determine if the function's formal parameter list should end with an - ellipsis. Given a tree node, the following function will return non-zero - if the "function type" parameter list should end with an ellipsis. */ - -static int -deserves_ellipsis (fntype) - tree fntype; -{ - tree formal_type; - - formal_type = TYPE_ARG_TYPES (fntype); - while (formal_type && TREE_VALUE (formal_type) != void_type_node) - formal_type = TREE_CHAIN (formal_type); - - /* If there were at least some parameters, and if the formals-types-list - petered out to a NULL (i.e. without being terminated by a void_type_node) - then we need to tack on an ellipsis. */ - - return (!formal_type && TYPE_ARG_TYPES (fntype)); -} - -/* Generate a parameter list for a function definition (in some given style). - - Note that this routine has to be separate (and different) from the code that - generates the prototype parameter lists for function declarations, because - in the case of a function declaration, all we have to go on is a tree node - representing the function's own "function type". This can tell us the types - of all of the formal parameters for the function, but it cannot tell us the - actual *names* of each of the formal parameters. We need to output those - parameter names for each function definition. - - This routine gets a pointer to a tree node which represents the actual - declaration of the given function, and this DECL node has a list of formal - parameter (variable) declarations attached to it. These formal parameter - (variable) declaration nodes give us the actual names of the formal - parameters for the given function definition. - - This routine returns a string which is the source form for the entire - function formal parameter list. */ - -static char* -gen_formal_list_for_func_def (fndecl, style) - tree fndecl; - formals_style style; -{ - char* formal_list = ""; - tree formal_decl; - - formal_decl = DECL_ARGUMENTS (fndecl); - while (formal_decl) - { - char *this_formal; - - if (*formal_list && ((style == ansi) || (style == k_and_r_names))) - formal_list = concat (formal_list, ", "); - this_formal = gen_decl (formal_decl, 0, style); - if (style == k_and_r_decls) - formal_list = concat3 (formal_list, this_formal, "; "); - else - formal_list = concat (formal_list, this_formal); - formal_decl = TREE_CHAIN (formal_decl); - } - if (style == ansi) - { - if (!DECL_ARGUMENTS (fndecl)) - formal_list = concat (formal_list, "void"); - if (deserves_ellipsis (TREE_TYPE (fndecl))) - formal_list = concat (formal_list, ", ..."); - } - if ((style == ansi) || (style == k_and_r_names)) - formal_list = concat3 (" (", formal_list, ")"); - return formal_list; -} - -/* Generate a string which is the source code form for a given type (t). This - routine is ugly and complex because the C syntax for declarations is ugly - and complex. This routine is straightforward so long as *no* pointer types, - array types, or function types are involved. - - In the simple cases, this routine will return the (string) value which was - passed in as the "ret_val" argument. Usually, this starts out either as an - empty string, or as the name of the declared item (i.e. the formal function - parameter variable). - - This routine will also return with the global variable "data_type" set to - some string value which is the "basic" data-type of the given complete type. - This "data_type" string can be concatenated onto the front of the returned - string after this routine returns to its caller. - - In complicated cases involving pointer types, array types, or function - types, the C declaration syntax requires an "inside out" approach, i.e. if - you have a type which is a "pointer-to-function" type, you need to handle - the "pointer" part first, but it also has to be "innermost" (relative to - the declaration stuff for the "function" type). Thus, is this case, you - must prepend a "(*" and append a ")" to the name of the item (i.e. formal - variable). Then you must append and prepend the other info for the - "function type" part of the overall type. - - To handle the "innermost precedence" rules of complicated C declarators, we - do the following (in this routine). The input parameter called "ret_val" - is treated as a "seed". Each time gen_type is called (perhaps recursively) - some additional strings may be appended or prepended (or both) to the "seed" - string. If yet another (lower) level of the GCC tree exists for the given - type (as in the case of a pointer type, an array type, or a function type) - then the (wrapped) seed is passed to a (recursive) invocation of gen_type() - this recursive invocation may again "wrap" the (new) seed with yet more - declarator stuff, by appending, prepending (or both). By the time the - recursion bottoms out, the "seed value" at that point will have a value - which is (almost) the complete source version of the declarator (except - for the data_type info). Thus, this deepest "seed" value is simply passed - back up through all of the recursive calls until it is given (as the return - value) to the initial caller of the gen_type() routine. All that remains - to do at this point is for the initial caller to prepend the "data_type" - string onto the returned "seed". */ - -static char* -gen_type (ret_val, t, style) - char* ret_val; - tree t; - formals_style style; -{ - tree chain_p; - - if (TYPE_NAME (t) && DECL_NAME (TYPE_NAME (t))) - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - else - { - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); - if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); - - ret_val = concat ("*", ret_val); - - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - ret_val = concat3 ("(", ret_val, ")"); - - ret_val = gen_type (ret_val, TREE_TYPE (t), style); - - return ret_val; - - case ARRAY_TYPE: - if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) - ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style); - else if (int_size_in_bytes (t) == 0) - ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style); - else - { - int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); - char buff[10]; - sprintf (buff, "[%d]", size); - ret_val = gen_type (concat (ret_val, buff), - TREE_TYPE (t), style); - } - break; - - case FUNCTION_TYPE: - ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style); - break; - - case IDENTIFIER_NODE: - data_type = IDENTIFIER_POINTER (t); - break; - - /* The following three cases are complicated by the fact that a - user may do something really stupid, like creating a brand new - "anonymous" type specification in a formal argument list (or as - part of a function return type specification). For example: - - int f (enum { red, green, blue } color); - - In such cases, we have no name that we can put into the prototype - to represent the (anonymous) type. Thus, we have to generate the - whole darn type specification. Yuck! */ - - case RECORD_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_FIELDS (t); - while (chain_p) - { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); - chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); - } - data_type = concat3 ("{ ", data_type, "}"); - } - data_type = concat ("struct ", data_type); - break; - - case UNION_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_FIELDS (t); - while (chain_p) - { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); - chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); - } - data_type = concat3 ("{ ", data_type, "}"); - } - data_type = concat ("union ", data_type); - break; - - case ENUMERAL_TYPE: - if (TYPE_NAME (t)) - data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); - else - { - data_type = ""; - chain_p = TYPE_VALUES (t); - while (chain_p) - { - data_type = concat (data_type, - IDENTIFIER_POINTER (TREE_PURPOSE (chain_p))); - chain_p = TREE_CHAIN (chain_p); - if (chain_p) - data_type = concat (data_type, ", "); - } - data_type = concat3 ("{ ", data_type, " }"); - } - data_type = concat ("enum ", data_type); - break; - - case TYPE_DECL: - data_type = IDENTIFIER_POINTER (DECL_NAME (t)); - break; - - case INTEGER_TYPE: - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - /* Normally, `unsigned' is part of the deal. Not so if it comes - with `const' or `volatile'. */ - if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) - data_type = concat ("unsigned ", data_type); - break; - - case REAL_TYPE: - data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); - break; - - case VOID_TYPE: - data_type = "void"; - break; - - default: - abort (); - } - } - if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); - if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); - return ret_val; -} - -/* Generate a string (source) representation of an entire entity declaration - (using some particular style for function types). - - The given entity may be either a variable or a function. - - If the "is_func_definition" parameter is non-zero, assume that the thing - we are generating a declaration for is a FUNCTION_DECL node which is - associated with a function definition. In this case, we can assume that - an attached list of DECL nodes for function formal arguments is present. */ - -static char* -gen_decl (decl, is_func_definition, style) - tree decl; - int is_func_definition; - formals_style style; -{ - char* ret_val; - char* outer_modifier = ""; - - if (DECL_NAME (decl)) - ret_val = IDENTIFIER_POINTER (DECL_NAME (decl)); - else - ret_val = ""; - - /* If we are just generating a list of names of formal parameters, we can - simply return the formal parameter name (with no typing information - attached to it) now. */ - - if (style == k_and_r_names) - return ret_val; - - /* Note that for the declaration of some entity (either a function or a - data object, like for instance a parameter) if the entity itself was - declared as either const or volatile, then const and volatile properties - are associated with just the declaration of the entity, and *not* with - the `type' of the entity. Thus, for such declared entities, we have to - generate the qualifiers here. */ - - if (TREE_THIS_VOLATILE (decl)) - ret_val = concat ("volatile ", ret_val); - if (TREE_READONLY (decl)) - ret_val = concat ("const ", ret_val); - - data_type = ""; - - /* For FUNCTION_DECL nodes, there are two possible cases here. First, if - this FUNCTION_DECL node was generated from a function "definition", then - we will have a list of DECL_NODE's, one for each of the function's formal - parameters. In this case, we can print out not only the types of each - formal, but also each formal's name. In the second case, this - FUNCTION_DECL node came from an actual function declaration (and *not* - a definition). In this case, we do nothing here because the formal - argument type-list will be output later, when the "type" of the function - is added to the string we are building. Note that the ANSI-style formal - parameter list is considered to be a (suffix) part of the "type" of the - function. */ - - if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition) - { - ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi)); - - /* Since we have already added in the formals list stuff, here we don't - add the whole "type" of the function we are considering (which - would include its parameter-list info), rather, we only add in - the "type" of the "type" of the function, which is really just - the return-type of the function (and does not include the parameter - list info). */ - - ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style); - } - else - ret_val = gen_type (ret_val, TREE_TYPE (decl), style); - - ret_val = affix_data_type (ret_val); - - if (DECL_REGISTER (decl)) - ret_val = concat ("register ", ret_val); - if (TREE_PUBLIC (decl)) - ret_val = concat ("extern ", ret_val); - if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) - ret_val = concat ("static ", ret_val); - - return ret_val; -} - -extern FILE* aux_info_file; - -/* Generate and write a new line of info to the aux-info (.X) file. This - routine is called once for each function declaration, and once for each - function definition (even the implicit ones). */ - -void -gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped) - tree fndecl; - int is_definition; - int is_implicit; - int is_prototyped; -{ - if (flag_gen_aux_info) - { - static int compiled_from_record = 0; - - /* Each output .X file must have a header line. Write one now if we - have not yet done so. */ - - if (! compiled_from_record++) - { - /* The first line tells which directory file names are relative to. - Currently, -aux-info works only for files in the working - directory, so just use a `.' as a placeholder for now. */ - fprintf (aux_info_file, "/* compiled from: . */\n"); - } - - /* Write the actual line of auxiliary info. */ - - fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;", - DECL_SOURCE_FILE (fndecl), - DECL_SOURCE_LINE (fndecl), - (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O', - (is_definition) ? 'F' : 'C', - gen_decl (fndecl, is_definition, ansi)); - - /* If this is an explicit function declaration, we need to also write - out an old-style (i.e. K&R) function header, just in case the user - wants to run unprotoize. */ - - if (is_definition) - { - fprintf (aux_info_file, " /*%s %s*/", - gen_formal_list_for_func_def (fndecl, k_and_r_names), - gen_formal_list_for_func_def (fndecl, k_and_r_decls)); - } - - fprintf (aux_info_file, "\n"); - } -} diff --git a/gnu/usr.bin/gcc2/cc1/c-convert.c b/gnu/usr.bin/gcc2/cc1/c-convert.c deleted file mode 100644 index bfcaa1f19a6..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-convert.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Language-level data type conversion for GNU C. - Copyright (C) 1987, 1988, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-convert.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -/* This file contains the functions for converting C expressions - to different data types. The only entry point is `convert'. - Every language front end must have a `convert' function - but what kind of conversions it does will depend on the language. */ - -#include "config.h" -#include "tree.h" -#include "flags.h" -#include "convert.h" - -/* Change of width--truncation and extension of integers or reals-- - is represented with NOP_EXPR. Proper functioning of many things - assumes that no other conversions can be NOP_EXPRs. - - Conversion between integer and pointer is represented with CONVERT_EXPR. - Converting integer to real uses FLOAT_EXPR - and real to integer uses FIX_TRUNC_EXPR. - - Here is a list of all the functions that assume that widening and - narrowing is always done with a NOP_EXPR: - In convert.c, convert_to_integer. - In c-typeck.c, build_binary_op (boolean ops), and truthvalue_conversion. - In expr.c: expand_expr, for operands of a MULT_EXPR. - In fold-const.c: fold. - In tree.c: get_narrower and get_unwidened. */ - -/* Subroutines of `convert'. */ - - - -/* Create an expression whose value is that of EXPR, - converted to type TYPE. The TREE_TYPE of the value - is always TYPE. This function implements all reasonable - conversions; callers should filter out those that are - not permitted by the language being compiled. */ - -tree -convert (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (expr) - || TREE_CODE (expr) == ERROR_MARK) - return expr; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold (build1 (NOP_EXPR, type, expr)); - if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == VOID_TYPE) - return build1 (CONVERT_EXPR, type, e); -#if 0 - /* This is incorrect. A truncation can't be stripped this way. - Extensions will be stripped by the use of get_unwidened. */ - if (TREE_CODE (expr) == NOP_EXPR) - return convert (type, TREE_OPERAND (expr, 0)); -#endif - if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) - return fold (convert_to_integer (type, e)); - if (code == POINTER_TYPE) - return fold (convert_to_pointer (type, e)); - if (code == REAL_TYPE) - return fold (convert_to_real (type, e)); - if (code == COMPLEX_TYPE) - return fold (convert_to_complex (type, e)); - - error ("conversion to non-scalar type requested"); - return error_mark_node; -} diff --git a/gnu/usr.bin/gcc2/cc1/c-decl.c b/gnu/usr.bin/gcc2/cc1/c-decl.c deleted file mode 100644 index 94ef6b7833e..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-decl.c +++ /dev/null @@ -1,6497 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-decl.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include "config.h" -#include "tree.h" -#include "flags.h" -#include "c-tree.h" -#include "c-lex.h" -#include - -/* In grokdeclarator, distinguish syntactic contexts of declarators. */ -enum decl_context -{ NORMAL, /* Ordinary declaration */ - FUNCDEF, /* Function definition */ - PARM, /* Declaration of parm before function body */ - FIELD, /* Declaration inside struct or union */ - BITFIELD, /* Likewise but with specified width */ - TYPENAME}; /* Typename (inside cast or sizeof) */ - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -/* We let tm.h override the types used here, to handle trivial differences - such as the choice of unsigned int or long unsigned int for size_t. - When machines start needing nontrivial differences in the size type, - it would be best to do something here to figure out automatically - from other information what type to use. */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif - -/* a node which has tree code ERROR_MARK, and whose type is itself. - All erroneous expressions are replaced with this node. All functions - that accept nodes as arguments should avoid generating error messages - if this node is one of the arguments, since it is undesirable to get - multiple error messages from one error in the input. */ - -tree error_mark_node; - -/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */ - -tree short_integer_type_node; -tree integer_type_node; -tree long_integer_type_node; -tree long_long_integer_type_node; - -tree short_unsigned_type_node; -tree unsigned_type_node; -tree long_unsigned_type_node; -tree long_long_unsigned_type_node; - -tree ptrdiff_type_node; - -tree unsigned_char_type_node; -tree signed_char_type_node; -tree char_type_node; -tree wchar_type_node; -tree signed_wchar_type_node; -tree unsigned_wchar_type_node; - -tree float_type_node; -tree double_type_node; -tree long_double_type_node; - -tree complex_integer_type_node; -tree complex_float_type_node; -tree complex_double_type_node; -tree complex_long_double_type_node; - -tree intQI_type_node; -tree intHI_type_node; -tree intSI_type_node; -tree intDI_type_node; - -tree unsigned_intQI_type_node; -tree unsigned_intHI_type_node; -tree unsigned_intSI_type_node; -tree unsigned_intDI_type_node; - -/* a VOID_TYPE node. */ - -tree void_type_node; - -/* Nodes for types `void *' and `const void *'. */ - -tree ptr_type_node, const_ptr_type_node; - -/* Nodes for types `char *' and `const char *'. */ - -tree string_type_node, const_string_type_node; - -/* Type `char[SOMENUMBER]'. - Used when an array of char is needed and the size is irrelevant. */ - -tree char_array_type_node; - -/* Type `int[SOMENUMBER]' or something like it. - Used when an array of int needed and the size is irrelevant. */ - -tree int_array_type_node; - -/* Type `wchar_t[SOMENUMBER]' or something like it. - Used when a wide string literal is created. */ - -tree wchar_array_type_node; - -/* type `int ()' -- used for implicit declaration of functions. */ - -tree default_function_type; - -/* function types `double (double)' and `double (double, double)', etc. */ - -tree double_ftype_double, double_ftype_double_double; -tree int_ftype_int, long_ftype_long; - -/* Function type `void (void *, void *, int)' and similar ones */ - -tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int; - -/* Function type `char *(char *, char *)' and similar ones */ -tree string_ftype_ptr_ptr, int_ftype_string_string; - -/* Function type `int (const void *, const void *, size_t)' */ -tree int_ftype_cptr_cptr_sizet; - -/* Two expressions that are constants with value zero. - The first is of type `int', the second of type `void *'. */ - -tree integer_zero_node; -tree null_pointer_node; - -/* A node for the integer constant 1. */ - -tree integer_one_node; - -/* Nonzero if we have seen an invalid cross reference - to a struct, union, or enum, but not yet printed the message. */ - -tree pending_invalid_xref; -/* File and line to appear in the eventual error message. */ -char *pending_invalid_xref_file; -int pending_invalid_xref_line; - -/* While defining an enum type, this is 1 plus the last enumerator - constant value. */ - -static tree enum_next_value; - -/* Nonzero means that there was overflow computing enum_next_value. */ - -static int enum_overflow; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ - -static tree last_function_parms; - -/* Parsing a function declarator leaves here a chain of structure - and enum types declared in the parmlist. */ - -static tree last_function_parm_tags; - -/* After parsing the declarator that starts a function definition, - `start_function' puts here the list of parameter names or chain of decls. - `store_parm_decls' finds it here. */ - -static tree current_function_parms; - -/* Similar, for last_function_parm_tags. */ -static tree current_function_parm_tags; - -/* Similar, for the file and line that the prototype came from if this is - an old-style definition. */ -static char *current_function_prototype_file; -static int current_function_prototype_line; - -/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function - that have names. Here so we can clear out their names' definitions - at the end of the function. */ - -static tree named_labels; - -/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ - -static tree shadowed_labels; - -/* Nonzero when store_parm_decls is called indicates a varargs function. - Value not meaningful after store_parm_decls. */ - -static int c_function_varargs; - -/* The FUNCTION_DECL for the function currently being compiled, - or 0 if between functions. */ -tree current_function_decl; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement that specifies a return value is seen. */ - -int current_function_returns_value; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement with no argument is seen. */ - -int current_function_returns_null; - -/* Set to nonzero by `grokdeclarator' for a function - whose return type is defaulted, if warnings for this are desired. */ - -static int warn_about_return_type; - -/* Nonzero when starting a function declared `extern inline'. */ - -static int current_extern_inline; - -/* For each binding contour we allocate a binding_level structure - * which records the names defined in that contour. - * Contours include: - * 0) the global one - * 1) one for each function definition, - * where internal declarations of the parameters appear. - * 2) one for each compound statement, - * to record its declarations. - * - * The current meaning of a name can be found by searching the levels from - * the current one out to the global one. - */ - -/* Note that the information in the `names' component of the global contour - is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ - -struct binding_level - { - /* A chain of _DECL nodes for all variables, constants, functions, - and typedef types. These are in the reverse of the order supplied. - */ - tree names; - - /* A list of structure, union and enum definitions, - * for looking up tag names. - * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, - * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, - * or ENUMERAL_TYPE node. - */ - tree tags; - - /* For each level, a list of shadowed outer-level local definitions - to be restored when this level is popped. - Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and - whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ - tree shadowed; - - /* For each level (except not the global one), - a chain of BLOCK nodes for all the levels - that were entered and exited one level down. */ - tree blocks; - - /* The BLOCK node for this level, if one has been preallocated. - If 0, the BLOCK is allocated (if needed) when the level is popped. */ - tree this_block; - - /* The binding level which this one is contained in (inherits from). */ - struct binding_level *level_chain; - - /* Nonzero for the level that holds the parameters of a function. */ - char parm_flag; - - /* Nonzero if this level "doesn't exist" for tags. */ - char tag_transparent; - - /* Nonzero if sublevels of this level "don't exist" for tags. - This is set in the parm level of a function definition - while reading the function body, so that the outermost block - of the function body will be tag-transparent. */ - char subblocks_tag_transparent; - - /* Nonzero means make a BLOCK for this level regardless of all else. */ - char keep; - - /* Nonzero means make a BLOCK if this level has any subblocks. */ - char keep_if_subblocks; - - /* Number of decls in `names' that have incomplete - structure or union types. */ - int n_incomplete; - - /* A list of decls giving the (reversed) specified order of parms, - not including any forward-decls in the parmlist. - This is so we can put the parms in proper order for assign_parms. */ - tree parm_order; - }; - -#define NULL_BINDING_LEVEL (struct binding_level *) NULL - -/* The binding level currently in effect. */ - -static struct binding_level *current_binding_level; - -/* A chain of binding_level structures awaiting reuse. */ - -static struct binding_level *free_binding_level; - -/* The outermost binding level, for names of file scope. - This is created when the compiler is started and exists - through the entire run. */ - -static struct binding_level *global_binding_level; - -/* Binding level structures are initialized by copying this one. */ - -static struct binding_level clear_binding_level - = {NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0}; - -/* Nonzero means unconditionally make a BLOCK for the next level pushed. */ - -static int keep_next_level_flag; - -/* Nonzero means make a BLOCK for the next level pushed - if it has subblocks. */ - -static int keep_next_if_subblocks; - -/* The chain of outer levels of label scopes. - This uses the same data structure used for binding levels, - but it works differently: each link in the chain records - saved values of named_labels and shadowed_labels for - a label binding level outside the current one. */ - -static struct binding_level *label_level_chain; - -/* Forward declarations. */ - -static tree grokparms (), grokdeclarator (); -tree pushdecl (); -tree builtin_function (); -void shadow_tag_warned (); - -static tree lookup_tag (); -static tree lookup_tag_reverse (); -tree lookup_name_current_level (); -static char *redeclaration_error_message (); -static void layout_array_type (); - -/* C-specific option variables. */ - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -int flag_cond_mismatch; - -/* Nonzero means give `double' the same size as `float'. */ - -int flag_short_double; - -/* Nonzero means don't recognize the keyword `asm'. */ - -int flag_no_asm; - -/* Nonzero means don't recognize any builtin functions. */ - -int flag_no_builtin; - -/* Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. */ - -int flag_no_nonansi_builtin; - -/* Nonzero means do some things the same way PCC does. */ - -int flag_traditional; - -/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */ - -int flag_signed_bitfields = 1; -int explicit_flag_signed_bitfields = 0; - -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident = 0; - -/* Nonzero means warn about implicit declarations. */ - -int warn_implicit; - -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ - -int warn_write_strings; - -/* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - -int warn_cast_qual; - -/* Warn about traditional constructs whose meanings changed in ANSI C. */ - -int warn_traditional; - -/* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - -int warn_pointer_arith; - -/* Nonzero means warn for non-prototype function decls - or non-prototyped defs without previous prototype. */ - -int warn_strict_prototypes; - -/* Nonzero means warn for any global function def - without separate previous prototype decl. */ - -int warn_missing_prototypes; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -int warn_redundant_decls = 0; - -/* Nonzero means warn about extern declarations of objects not at - file-scope level and about *all* declarations of functions (whether - extern or static) not at file-scope level. Note that we exclude - implicit function declarations. To get warnings about those, use - -Wimplicit. */ - -int warn_nested_externs = 0; - -/* Warn about *printf or *scanf format/argument anomalies. */ - -int warn_format; - -/* Warn about a subscript that has type char. */ - -int warn_char_subscripts = 0; - -/* Warn if a type conversion is done that might have confusing results. */ - -int warn_conversion; - -/* Warn if adding () is suggested. */ - -int warn_parentheses; - -/* Warn if initializer is not completely bracketed. */ - -int warn_missing_braces; - -/* Nonzero means `$' can be in an identifier. - See cccp.c for reasons why this breaks some obscure ANSI C programs. */ - -#ifndef DOLLARS_IN_IDENTIFIERS -#define DOLLARS_IN_IDENTIFIERS 1 -#endif -int dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; - -/* Decode the string P as a language-specific option for C. - Return 1 if it is recognized (and handle it); - return 0 if not recognized. */ - -int -c_decode_option (p) - char *p; -{ - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - { - flag_traditional = 1; - flag_writable_strings = 1; -#if DOLLARS_IN_IDENTIFIERS > 0 - dollars_in_ident = 1; -#endif - } - else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional")) - { - flag_traditional = 0; - flag_writable_strings = 0; - dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 1; - } - else if (!strcmp (p, "-fsigned-char")) - flag_signed_char = 1; - else if (!strcmp (p, "-funsigned-char")) - flag_signed_char = 0; - else if (!strcmp (p, "-fno-signed-char")) - flag_signed_char = 0; - else if (!strcmp (p, "-fno-unsigned-char")) - flag_signed_char = 1; - else if (!strcmp (p, "-fsigned-bitfields") - || !strcmp (p, "-fno-unsigned-bitfields")) - { - flag_signed_bitfields = 1; - explicit_flag_signed_bitfields = 1; - } - else if (!strcmp (p, "-funsigned-bitfields") - || !strcmp (p, "-fno-signed-bitfields")) - { - flag_signed_bitfields = 0; - explicit_flag_signed_bitfields = 1; - } - else if (!strcmp (p, "-fshort-enums")) - flag_short_enums = 1; - else if (!strcmp (p, "-fno-short-enums")) - flag_short_enums = 0; - else if (!strcmp (p, "-fcond-mismatch")) - flag_cond_mismatch = 1; - else if (!strcmp (p, "-fno-cond-mismatch")) - flag_cond_mismatch = 0; - else if (!strcmp (p, "-fshort-double")) - flag_short_double = 1; - else if (!strcmp (p, "-fno-short-double")) - flag_short_double = 0; - else if (!strcmp (p, "-fasm")) - flag_no_asm = 0; - else if (!strcmp (p, "-fno-asm")) - flag_no_asm = 1; - else if (!strcmp (p, "-fbuiltin")) - flag_no_builtin = 0; - else if (!strcmp (p, "-fno-builtin")) - flag_no_builtin = 1; - else if (!strcmp (p, "-fno-ident")) - flag_no_ident = 1; - else if (!strcmp (p, "-fident")) - flag_no_ident = 0; - else if (!strcmp (p, "-ansi")) - flag_no_asm = 1, flag_no_nonansi_builtin = 1, dollars_in_ident = 0; - else if (!strcmp (p, "-Wimplicit")) - warn_implicit = 1; - else if (!strcmp (p, "-Wno-implicit")) - warn_implicit = 0; - else if (!strcmp (p, "-Wwrite-strings")) - warn_write_strings = 1; - else if (!strcmp (p, "-Wno-write-strings")) - warn_write_strings = 0; - else if (!strcmp (p, "-Wcast-qual")) - warn_cast_qual = 1; - else if (!strcmp (p, "-Wno-cast-qual")) - warn_cast_qual = 0; - else if (!strcmp (p, "-Wpointer-arith")) - warn_pointer_arith = 1; - else if (!strcmp (p, "-Wno-pointer-arith")) - warn_pointer_arith = 0; - else if (!strcmp (p, "-Wstrict-prototypes")) - warn_strict_prototypes = 1; - else if (!strcmp (p, "-Wno-strict-prototypes")) - warn_strict_prototypes = 0; - else if (!strcmp (p, "-Wmissing-prototypes")) - warn_missing_prototypes = 1; - else if (!strcmp (p, "-Wno-missing-prototypes")) - warn_missing_prototypes = 0; - else if (!strcmp (p, "-Wredundant-decls")) - warn_redundant_decls = 1; - else if (!strcmp (p, "-Wno-redundant-decls")) - warn_redundant_decls = 0; - else if (!strcmp (p, "-Wnested-externs")) - warn_nested_externs = 1; - else if (!strcmp (p, "-Wno-nested-externs")) - warn_nested_externs = 0; - else if (!strcmp (p, "-Wtraditional")) - warn_traditional = 1; - else if (!strcmp (p, "-Wno-traditional")) - warn_traditional = 0; - else if (!strcmp (p, "-Wformat")) - warn_format = 1; - else if (!strcmp (p, "-Wno-format")) - warn_format = 0; - else if (!strcmp (p, "-Wchar-subscripts")) - warn_char_subscripts = 1; - else if (!strcmp (p, "-Wno-char-subscripts")) - warn_char_subscripts = 0; - else if (!strcmp (p, "-Wconversion")) - warn_conversion = 1; - else if (!strcmp (p, "-Wno-conversion")) - warn_conversion = 0; - else if (!strcmp (p, "-Wparentheses")) - warn_parentheses = 1; - else if (!strcmp (p, "-Wno-parentheses")) - warn_parentheses = 0; - else if (!strcmp (p, "-Wreturn-type")) - warn_return_type = 1; - else if (!strcmp (p, "-Wno-return-type")) - warn_return_type = 0; - else if (!strcmp (p, "-Wcomment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-comment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wcomments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-comments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wtrigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wimport")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wno-import")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "-Wmissing-braces")) - warn_missing_braces = 1; - else if (!strcmp (p, "-Wno-missing-braces")) - warn_missing_braces = 0; - else if (!strcmp (p, "-Wall")) - { - extra_warnings = 1; - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = 2; - warn_implicit = 1; - warn_return_type = 1; - warn_unused = 1; - warn_switch = 1; - warn_format = 1; - warn_char_subscripts = 1; - warn_parentheses = 1; - warn_missing_braces = 1; - } - else - return 0; - - return 1; -} - -/* Hooks for print_node. */ - -void -print_lang_decl () -{ -} - -void -print_lang_type () -{ -} - -void -print_lang_identifier (file, node, indent) - FILE *file; - tree node; - int indent; -{ - print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4); - print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4); - print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4); - print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); - print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4); - print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4); -} - -/* Hook called at end of compilation to assume 1 elt - for a top-level array decl that wasn't complete before. */ - -void -finish_incomplete_decl (decl) - tree decl; -{ - if (TREE_CODE (decl) == VAR_DECL && TREE_TYPE (decl) != error_mark_node) - { - tree type = TREE_TYPE (decl); - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == 0 - && TREE_CODE (decl) != TYPE_DECL) - { - complete_array_type (type, NULL_TREE, 1); - - layout_decl (decl, 0); - } - } -} - -/* Create a new `struct binding_level'. */ - -static -struct binding_level * -make_binding_level () -{ - /* NOSTRICT */ - return (struct binding_level *) xmalloc (sizeof (struct binding_level)); -} - -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p () -{ - return current_binding_level == global_binding_level; -} - -void -keep_next_level () -{ - keep_next_level_flag = 1; -} - -/* Nonzero if the current level needs to have a BLOCK made. */ - -int -kept_level_p () -{ - return ((current_binding_level->keep_if_subblocks - && current_binding_level->blocks != 0) - || current_binding_level->keep - || current_binding_level->names != 0 - || (current_binding_level->tags != 0 - && !current_binding_level->tag_transparent)); -} - -/* Identify this binding level as a level of parameters. - DEFINITION_FLAG is 1 for a definition, 0 for a declaration. - But it turns out there is no way to pass the right value for - DEFINITION_FLAG, so we ignore it. */ - -void -declare_parm_level (definition_flag) - int definition_flag; -{ - current_binding_level->parm_flag = 1; -} - -/* Nonzero if currently making parm declarations. */ - -int -in_parm_level_p () -{ - return current_binding_level->parm_flag; -} - -/* Enter a new binding level. - If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, - not for that of tags. */ - -void -pushlevel (tag_transparent) - int tag_transparent; -{ - register struct binding_level *newlevel = NULL_BINDING_LEVEL; - - /* If this is the top level of a function, - just make sure that NAMED_LABELS is 0. */ - - if (current_binding_level == global_binding_level) - { - named_labels = 0; - } - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - /* Add this level to the front of the chain (stack) of levels that - are active. */ - - *newlevel = clear_binding_level; - newlevel->tag_transparent - = (tag_transparent - || (current_binding_level - ? current_binding_level->subblocks_tag_transparent - : 0)); - newlevel->level_chain = current_binding_level; - current_binding_level = newlevel; - newlevel->keep = keep_next_level_flag; - keep_next_level_flag = 0; - newlevel->keep_if_subblocks = keep_next_if_subblocks; - keep_next_if_subblocks = 0; -} - -/* Exit a binding level. - Pop the level off, and restore the state of the identifier-decl mappings - that were in effect when this level was entered. - - If KEEP is nonzero, this level had explicit declarations, so - and create a "block" (a BLOCK node) for the level - to record its declarations and subblocks for symbol table output. - - If FUNCTIONBODY is nonzero, this level is the body of a function, - so create a block as if KEEP were set and also clear out all - label names. - - If REVERSE is nonzero, reverse the order of decls before putting - them into the BLOCK. */ - -tree -poplevel (keep, reverse, functionbody) - int keep; - int reverse; - int functionbody; -{ - register tree link; - /* The chain of decls was accumulated in reverse order. - Put it into forward order, just for cleanliness. */ - tree decls; - tree tags = current_binding_level->tags; - tree subblocks = current_binding_level->blocks; - tree block = 0; - tree decl; - int block_previously_created; - - keep |= current_binding_level->keep; - - /* This warning is turned off because it causes warnings for - declarations like `extern struct foo *x'. */ -#if 0 - /* Warn about incomplete structure types in this level. */ - for (link = tags; link; link = TREE_CHAIN (link)) - if (TYPE_SIZE (TREE_VALUE (link)) == 0) - { - tree type = TREE_VALUE (link); - char *errmsg; - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - errmsg = "`struct %s' incomplete in scope ending here"; - break; - case UNION_TYPE: - errmsg = "`union %s' incomplete in scope ending here"; - break; - case ENUMERAL_TYPE: - errmsg = "`enum %s' incomplete in scope ending here"; - break; - } - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - } -#endif /* 0 */ - - /* Get the decls in the order they were written. - Usually current_binding_level->names is in reverse order. - But parameter decls were previously put in forward order. */ - - if (reverse) - current_binding_level->names - = decls = nreverse (current_binding_level->names); - else - decls = current_binding_level->names; - - /* Output any nested inline functions within this block - if they weren't already output. */ - - for (decl = decls; decl; decl = TREE_CHAIN (decl)) - if (TREE_CODE (decl) == FUNCTION_DECL - && ! TREE_ASM_WRITTEN (decl) - && DECL_INITIAL (decl) != 0 - && TREE_ADDRESSABLE (decl)) - { - /* If this decl was copied from a file-scope decl - on account of a block-scope extern decl, - propagate TREE_ADDRESSABLE to the file-scope decl. */ - if (DECL_ABSTRACT_ORIGIN (decl) != 0) - TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else - output_inline_function (decl); - } - - /* If there were any declarations or structure tags in that level, - or if this level is a function body, - create a BLOCK to record them for the life of this function. */ - - block = 0; - block_previously_created = (current_binding_level->this_block != 0); - if (block_previously_created) - block = current_binding_level->this_block; - else if (keep || functionbody - || (current_binding_level->keep_if_subblocks && subblocks != 0)) - block = make_node (BLOCK); - if (block != 0) - { - BLOCK_VARS (block) = decls; - BLOCK_TYPE_TAGS (block) = tags; - BLOCK_SUBBLOCKS (block) = subblocks; - remember_end_note (block); - } - - /* In each subblock, record that this is its superior. */ - - for (link = subblocks; link; link = TREE_CHAIN (link)) - BLOCK_SUPERCONTEXT (link) = block; - - /* Clear out the meanings of the local variables of this level. */ - - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != 0) - { - /* If the ident. was used or addressed via a local extern decl, - don't forget that fact. */ - if (DECL_EXTERNAL (link)) - { - if (TREE_USED (link)) - TREE_USED (DECL_NAME (link)) = 1; - if (TREE_ADDRESSABLE (link)) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; - } - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0; - } - } - - /* Restore all name-meanings of the outer levels - that were shadowed by this level. */ - - for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - - /* If the level being exited is the top level of a function, - check over all the labels, and clear out the current - (function local) meanings of their names. */ - - if (functionbody) - { - /* If this is the top level block of a function, - the vars are the function's parameters. - Don't leave them in the BLOCK because they are - found in the FUNCTION_DECL instead. */ - - BLOCK_VARS (block) = 0; - - /* Clear out the definitions of all label names, - since their scopes end here, - and add them to BLOCK_VARS. */ - - for (link = named_labels; link; link = TREE_CHAIN (link)) - { - register tree label = TREE_VALUE (link); - - if (DECL_INITIAL (label) == 0) - { - error_with_decl (label, "label `%s' used but not defined"); - /* Avoid crashing later. */ - define_label (input_filename, lineno, - DECL_NAME (label)); - } - else if (warn_unused && !TREE_USED (label)) - warning_with_decl (label, "label `%s' defined but not used"); - IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0; - - /* Put the labels into the "variables" of the - top-level block, so debugger can see them. */ - TREE_CHAIN (label) = BLOCK_VARS (block); - BLOCK_VARS (block) = label; - } - } - - /* Pop the current level, and free the structure for reuse. */ - - { - register struct binding_level *level = current_binding_level; - current_binding_level = current_binding_level->level_chain; - - level->level_chain = free_binding_level; - free_binding_level = level; - } - - /* Dispose of the block that we just made inside some higher level. */ - if (functionbody) - DECL_INITIAL (current_function_decl) = block; - else if (block) - { - if (!block_previously_created) - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); - } - /* If we did not make a block for the level just exited, - any blocks made for inner levels - (since they cannot be recorded as subblocks in that level) - must be carried forward so they will later become subblocks - of something else. */ - else if (subblocks) - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this - binding contour so that they point to the appropriate construct, i.e. - either to the current FUNCTION_DECL node, or else to the BLOCK node - we just constructed. - - Note that for tagged types whose scope is just the formal parameter - list for some function type specification, we can't properly set - their TYPE_CONTEXTs here, because we don't have a pointer to the - appropriate FUNCTION_TYPE node readily available to us. For those - cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set - in `grokdeclarator' as soon as we have created the FUNCTION_TYPE - node which will represent the "scope" for these "parameter list local" - tagged types. - */ - - if (functionbody) - for (link = tags; link; link = TREE_CHAIN (link)) - TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl; - else if (block) - for (link = tags; link; link = TREE_CHAIN (link)) - TYPE_CONTEXT (TREE_VALUE (link)) = block; - - if (block) - TREE_USED (block) = 1; - return block; -} - -/* Delete the node BLOCK from the current binding level. - This is used for the block inside a stmt expr ({...}) - so that the block can be reinserted where appropriate. */ - -void -delete_block (block) - tree block; -{ - tree t; - if (current_binding_level->blocks == block) - current_binding_level->blocks = TREE_CHAIN (block); - for (t = current_binding_level->blocks; t;) - { - if (TREE_CHAIN (t) == block) - TREE_CHAIN (t) = TREE_CHAIN (block); - else - t = TREE_CHAIN (t); - } - TREE_CHAIN (block) = NULL; - /* Clear TREE_USED which is always set by poplevel. - The flag is set again if insert_block is called. */ - TREE_USED (block) = 0; -} - -/* Insert BLOCK at the end of the list of subblocks of the - current binding level. This is used when a BIND_EXPR is expanded, - to handle the BLOCK node inside teh BIND_EXPR. */ - -void -insert_block (block) - tree block; -{ - TREE_USED (block) = 1; - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -/* Set the BLOCK node for the innermost scope - (the one we are currently in). */ - -void -set_block (block) - register tree block; -{ - current_binding_level->this_block = block; -} - -void -push_label_level () -{ - register struct binding_level *newlevel; - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - /* Add this level to the front of the chain (stack) of label levels. */ - - newlevel->level_chain = label_level_chain; - label_level_chain = newlevel; - - newlevel->names = named_labels; - newlevel->shadowed = shadowed_labels; - named_labels = 0; - shadowed_labels = 0; -} - -void -pop_label_level () -{ - register struct binding_level *level = label_level_chain; - tree link, prev; - - /* Clear out the definitions of the declared labels in this level. - Leave in the list any ordinary, non-declared labels. */ - for (link = named_labels, prev = 0; link;) - { - if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link))) - { - if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0) - { - error_with_decl (TREE_VALUE (link), - "label `%s' used but not defined"); - /* Avoid crashing later. */ - define_label (input_filename, lineno, - DECL_NAME (TREE_VALUE (link))); - } - else if (warn_unused && !TREE_USED (TREE_VALUE (link))) - warning_with_decl (TREE_VALUE (link), - "label `%s' defined but not used"); - IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0; - - /* Delete this element from the list. */ - link = TREE_CHAIN (link); - if (prev) - TREE_CHAIN (prev) = link; - else - named_labels = link; - } - else - { - prev = link; - link = TREE_CHAIN (link); - } - } - - /* Bring back all the labels that were shadowed. */ - for (link = shadowed_labels; link; link = TREE_CHAIN (link)) - if (DECL_NAME (TREE_VALUE (link)) != 0) - IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) - = TREE_VALUE (link); - - named_labels = chainon (named_labels, level->names); - shadowed_labels = level->shadowed; - - /* Pop the current level, and free the structure for reuse. */ - label_level_chain = label_level_chain->level_chain; - level->level_chain = free_binding_level; - free_binding_level = level; -} - -/* Push a definition or a declaration of struct, union or enum tag "name". - "type" should be the type node. - We assume that the tag "name" is not already defined. - - Note that the definition may really be just a forward reference. - In that case, the TYPE_SIZE will be zero. */ - -void -pushtag (name, type) - tree name, type; -{ - register struct binding_level *b; - - /* Find the proper binding level for this type tag. */ - - for (b = current_binding_level; b->tag_transparent; b = b->level_chain) - continue; - - if (name) - { - /* Record the identifier as the type's name if it has none. */ - - if (TYPE_NAME (type) == 0) - TYPE_NAME (type) = name; - } - - if (b == global_binding_level) - b->tags = perm_tree_cons (name, type, b->tags); - else - b->tags = saveable_tree_cons (name, type, b->tags); - - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the - tagged type we just added to the current binding level. This fake - NULL-named TYPE_DECL node helps dwarfout.c to know when it needs - to output a representation of a tagged type, and it also gives - us a convenient place to record the "scope start" address for the - tagged type. */ - - TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type)); -} - -/* Handle when a new declaration NEWDECL - has the same name as an old one OLDDECL - in the same binding contour. - Prints an error message if appropriate. - - If safely possible, alter OLDDECL to look like NEWDECL, and return 1. - Otherwise, return 0. */ - -static int -duplicate_decls (newdecl, olddecl) - register tree newdecl, olddecl; -{ - int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); - int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_INITIAL (newdecl) != 0); - tree oldtype = TREE_TYPE (olddecl); - tree newtype = TREE_TYPE (newdecl); - - if (TREE_CODE (newtype) == ERROR_MARK - || TREE_CODE (oldtype) == ERROR_MARK) - types_match = 0; - - /* New decl is completely inconsistent with the old one => - tell caller to replace the old one. - This is always an error except in the case of shadowing a builtin. */ - if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) - { - if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl)) - { - /* If you declare a built-in function name as static, the - built-in definition is overridden, - but optionally warn this was a bad choice of name. */ - if (!TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - warning_with_decl (newdecl, "shadowing built-in function `%s'"); - } - /* Likewise, if the built-in is not ansi, then programs can - override it even globally without an error. */ - else if (DECL_BUILT_IN_NONANSI (olddecl)) - warning_with_decl (newdecl, - "built-in function `%s' declared as non-function"); - else - error_with_decl (newdecl, - "built-in function `%s' declared as non-function"); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN_NONANSI (olddecl)) - { - /* If overriding decl is static, - optionally warn this was a bad choice of name. */ - if (!TREE_PUBLIC (newdecl)) - { - if (warn_shadow) - warning_with_decl (newdecl, "shadowing library function `%s'"); - } - /* Otherwise, always warn. */ - else - warning_with_decl (newdecl, - "library function `%s' declared as non-function"); - } - else - { - error_with_decl (newdecl, "`%s' redeclared as different kind of symbol"); - error_with_decl (olddecl, "previous declaration of `%s'"); - } - - return 0; - } - - /* For real parm decl following a forward decl, - return 1 so old decl will be reused. */ - if (types_match && TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl)) - return 1; - - /* The new declaration is the same kind of object as the old one. - The declarations may partially match. Print warnings if they don't - match enough. Ultimately, copy most of the information from the new - decl to the old one, and keep using the old one. */ - - if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL - && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl - && DECL_INITIAL (olddecl) == 0) - /* If -traditional, avoid error for redeclaring fcn - after implicit decl. */ - ; - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl)) - { - /* A function declaration for a built-in function. */ - if (!TREE_PUBLIC (newdecl)) - { - /* If you declare a built-in function name as static, the - built-in definition is overridden, - but optionally warn this was a bad choice of name. */ - if (warn_shadow) - warning_with_decl (newdecl, "shadowing built-in function `%s'"); - /* Discard the old built-in function. */ - return 0; - } - else if (!types_match) - { - /* Accept the return type of the new declaration if same modes. */ - tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl)); - tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl)); - if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype)) - { - /* Function types may be shared, so we can't just modify - the return type of olddecl's function type. */ - tree newtype - = build_function_type (newreturntype, - TYPE_ARG_TYPES (TREE_TYPE (olddecl))); - - types_match = comptypes (TREE_TYPE (newdecl), newtype); - if (types_match) - TREE_TYPE (olddecl) = newtype; - } - /* Accept harmless mismatch in first argument type also. - This is for ffs. */ - if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0 - && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0 - && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))) != 0 - && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl))) != 0 - && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl)))) - == - TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl)))))) - { - /* Function types may be shared, so we can't just modify - the return type of olddecl's function type. */ - tree newtype - = build_function_type (TREE_TYPE (TREE_TYPE (olddecl)), - tree_cons (NULL_TREE, - TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))), - TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (olddecl))))); - - types_match = comptypes (TREE_TYPE (newdecl), newtype); - if (types_match) - TREE_TYPE (olddecl) = newtype; - } - } - if (!types_match) - { - /* If types don't match for a built-in, throw away the built-in. */ - warning_with_decl (newdecl, "conflicting types for built-in function `%s'"); - return 0; - } - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_SOURCE_LINE (olddecl) == 0) - { - /* A function declaration for a predeclared function - that isn't actually built in. */ - if (!TREE_PUBLIC (newdecl)) - { - /* If you declare it as static, the - default definition is overridden. */ - return 0; - } - else if (!types_match) - { - /* If the types don't match, preserve volatility indication. - Later on, we will discard everything else about the - default declaration. */ - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - } - } - /* Permit char *foo () to match void *foo (...) if not pedantic, - if one of them came from a system header file. */ - else if (!types_match - && TREE_CODE (olddecl) == FUNCTION_DECL - && TREE_CODE (newdecl) == FUNCTION_DECL - && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE - && (DECL_IN_SYSTEM_HEADER (olddecl) - || DECL_IN_SYSTEM_HEADER (newdecl)) - && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node - && TYPE_ARG_TYPES (oldtype) == 0 - && self_promoting_args_p (TYPE_ARG_TYPES (newtype)) - && TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node) - || - (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node - && TYPE_ARG_TYPES (newtype) == 0 - && self_promoting_args_p (TYPE_ARG_TYPES (oldtype)) - && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node))) - { - if (pedantic) - pedwarn_with_decl (newdecl, "conflicting types for `%s'"); - /* Make sure we keep void * as ret type, not char *. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node) - TREE_TYPE (newdecl) = newtype = oldtype; - } - else if (!types_match - /* Permit char *foo (int, ...); followed by char *foo (); - if not pedantic. */ - && ! (TREE_CODE (olddecl) == FUNCTION_DECL - && ! pedantic - /* Return types must still match. */ - && comptypes (TREE_TYPE (oldtype), - TREE_TYPE (newtype)) - && TYPE_ARG_TYPES (newtype) == 0)) - { - error_with_decl (newdecl, "conflicting types for `%s'"); - /* Check for function type mismatch - involving an empty arglist vs a nonempty one. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && comptypes (TREE_TYPE (oldtype), - TREE_TYPE (newtype)) - && ((TYPE_ARG_TYPES (oldtype) == 0 - && DECL_INITIAL (olddecl) == 0) - || - (TYPE_ARG_TYPES (newtype) == 0 - && DECL_INITIAL (newdecl) == 0))) - { - /* Classify the problem further. */ - register tree t = TYPE_ARG_TYPES (oldtype); - if (t == 0) - t = TYPE_ARG_TYPES (newtype); - for (; t; t = TREE_CHAIN (t)) - { - register tree type = TREE_VALUE (t); - - if (TREE_CHAIN (t) == 0 - && TYPE_MAIN_VARIANT (type) != void_type_node) - { - error ("A parameter list with an ellipsis can't match"); - error ("an empty parameter name list declaration."); - break; - } - - if (TYPE_MAIN_VARIANT (type) == float_type_node - || C_PROMOTING_INTEGER_TYPE_P (type)) - { - error ("An argument type that has a default promotion"); - error ("can't match an empty parameter name list declaration."); - break; - } - } - } - error_with_decl (olddecl, "previous declaration of `%s'"); - } - else - { - char *errmsg = redeclaration_error_message (newdecl, olddecl); - if (errmsg) - { - error_with_decl (newdecl, errmsg); - error_with_decl (olddecl, - ((DECL_INITIAL (olddecl) - && current_binding_level == global_binding_level) - ? "`%s' previously defined here" - : "`%s' previously declared here")); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_INITIAL (olddecl) != 0 - && TYPE_ARG_TYPES (oldtype) == 0 - && TYPE_ARG_TYPES (newtype) != 0) - { - register tree type, parm; - register int nargs; - /* Prototype decl follows defn w/o prototype. */ - - for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype), - type = TYPE_ARG_TYPES (newtype), - nargs = 1; - (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node - || TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node); - parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++) - { - if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node - || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) - { - errmsg = "prototype for `%s' follows and number of arguments"; - break; - } - /* Type for passing arg must be consistent - with that declared for the arg. */ - if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)) - /* If -traditional, allow `unsigned int' instead of `int' - in the prototype. */ - && (! (flag_traditional - && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node - && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))) - { - errmsg = "prototype for `%s' follows and argument %d"; - break; - } - } - if (errmsg) - { - error_with_decl (newdecl, errmsg, nargs); - error_with_decl (olddecl, - "doesn't match non-prototype definition here"); - } - else - { - warning_with_decl (newdecl, "prototype for `%s' follows"); - warning_with_decl (olddecl, "non-prototype definition here"); - } - } - /* Warn about mismatches in various flags. */ - else - { - /* Warn if function is now inline - but was previously declared not inline and has been called. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl) - && TREE_USED (olddecl)) - warning_with_decl (newdecl, - "`%s' declared inline after being called"); - if (TREE_CODE (olddecl) == FUNCTION_DECL - && ! DECL_INLINE (olddecl) && DECL_INLINE (newdecl) - && DECL_INITIAL (olddecl) != 0) - warning_with_decl (newdecl, - "`%s' declared inline after its definition"); - /* It is nice to warn when a function is declared - global first and then static. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && TREE_PUBLIC (olddecl) - && !TREE_PUBLIC (newdecl)) - warning_with_decl (newdecl, "static declaration for `%s' follows non-static"); - - /* These bits are logically part of the type, for variables. - But not for functions - (where qualifiers are not valid ANSI anyway). */ - if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL - && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) - || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))) - pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl"); - } - } - - /* Optionally warn about more than one declaration for the same name. */ - if (warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0 - /* Dont warn about a function declaration - followed by a definition. */ - && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0 - && DECL_INITIAL (olddecl) == 0)) - { - warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope"); - warning_with_decl (olddecl, "previous declaration of `%s'"); - } - - /* Copy all the DECL_... slots specified in the new decl - except for any that we copy here from the old type. - - Past this point, we don't change OLDTYPE and NEWTYPE - even if we change the types of NEWDECL and OLDDECL. */ - - if (types_match) - { - /* Merge the data types specified in the two decls. */ - if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl)) - TREE_TYPE (newdecl) - = TREE_TYPE (olddecl) - = common_type (newtype, oldtype); - - /* Lay the type out, unless already done. */ - if (oldtype != TREE_TYPE (newdecl)) - { - if (TREE_TYPE (newdecl) != error_mark_node) - layout_type (TREE_TYPE (newdecl)); - if (TREE_CODE (newdecl) != FUNCTION_DECL - && TREE_CODE (newdecl) != TYPE_DECL - && TREE_CODE (newdecl) != CONST_DECL) - layout_decl (newdecl, 0); - } - else - { - /* Since the type is OLDDECL's, make OLDDECL's size go with. */ - DECL_SIZE (newdecl) = DECL_SIZE (olddecl); - if (TREE_CODE (olddecl) != FUNCTION_DECL) - if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); - } - - /* Keep the old rtl since we can safely use it. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); - - /* Merge the type qualifiers. */ - if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl) - && !TREE_THIS_VOLATILE (newdecl)) - TREE_THIS_VOLATILE (olddecl) = 0; - if (TREE_READONLY (newdecl)) - TREE_READONLY (olddecl) = 1; - if (TREE_THIS_VOLATILE (newdecl)) - { - TREE_THIS_VOLATILE (olddecl) = 1; - if (TREE_CODE (newdecl) == VAR_DECL) - make_var_volatile (newdecl); - } - - /* Keep source location of definition rather than declaration. */ - if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) - { - DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); - DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); - } - - /* Merge the unused-warning information. */ - if (DECL_IN_SYSTEM_HEADER (olddecl)) - DECL_IN_SYSTEM_HEADER (newdecl) = 1; - else if (DECL_IN_SYSTEM_HEADER (newdecl)) - DECL_IN_SYSTEM_HEADER (olddecl) = 1; - - /* Merge the initialization information. */ - if (DECL_INITIAL (newdecl) == 0) - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - } - /* If cannot merge, then use the new type and qualifiers, - and don't preserve the old rtl. */ - else - { - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - TREE_READONLY (olddecl) = TREE_READONLY (newdecl); - TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); - TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl); - } - - /* Merge the storage class information. */ - /* For functions, static overrides non-static. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - if (! TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_NAME (olddecl)) = 0; - } - if (DECL_EXTERNAL (newdecl)) - { - TREE_STATIC (newdecl) = TREE_STATIC (olddecl); - DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl); - /* An extern decl does not override previous storage class. */ - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); - } - else - { - TREE_STATIC (olddecl) = TREE_STATIC (newdecl); - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - } - - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) - DECL_INLINE (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); - - /* Get rid of any built-in function if new arg types don't match it - or if we have a function definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl) - && (!types_match || new_is_definition)) - { - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - DECL_BUILT_IN (olddecl) = 0; - } - - /* If redeclaring a builtin function, and not a definition, - it stays built in. - Also preserve various other info from the definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition) - { - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN (newdecl) = 1; - DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl)); - } - else - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); - - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - } - - /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve OLDdECL's DECL_UID. */ - { - register unsigned olddecl_uid = DECL_UID (olddecl); - - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common)); - DECL_UID (olddecl) = olddecl_uid; - } - - return 1; -} - -/* Record a decl-node X as belonging to the current lexical scope. - Check for errors (such as an incompatible declaration for the same - name already seen in the same scope). - - Returns either X or an old decl for the same name. - If an old decl is returned, it may have been smashed - to agree with what X says. */ - -tree -pushdecl (x) - tree x; -{ - register tree t; - register tree name = DECL_NAME (x); - register struct binding_level *b = current_binding_level; - - DECL_CONTEXT (x) = current_function_decl; - /* A local extern declaration for a function doesn't constitute nesting. - A local auto declaration does, since it's a forward decl - for a nested function coming later. */ - if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0 - && DECL_EXTERNAL (x)) - DECL_CONTEXT (x) = 0; - - if (warn_nested_externs && DECL_EXTERNAL (x) && b != global_binding_level - && x != IDENTIFIER_IMPLICIT_DECL (name)) - warning ("nested extern declaration of `%s'", IDENTIFIER_POINTER (name)); - - if (name) - { - char *file; - int line; - - t = lookup_name_current_level (name); - if (t != 0 && t == error_mark_node) - /* error_mark_node is 0 for a while during initialization! */ - { - t = 0; - error_with_decl (x, "`%s' used prior to declaration"); - } - - if (t != 0) - { - file = DECL_SOURCE_FILE (t); - line = DECL_SOURCE_LINE (t); - } - - if (t != 0 && duplicate_decls (x, t)) - { - if (TREE_CODE (t) == PARM_DECL) - { - /* Don't allow more than one "real" duplicate - of a forward parm decl. */ - TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x); - return t; - } - /* If this decl is `static' and an implicit decl was seen previously, - warn. But don't complain if -traditional, - since traditional compilers don't complain. */ - if (!flag_traditional && TREE_PUBLIC (name) - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x) - /* We used to warn also for explicit extern followed by static, - but sometimes you need to do it that way. */ - && IDENTIFIER_IMPLICIT_DECL (name) != 0) - { - pedwarn ("`%s' was declared implicitly `extern' and later `static'", - IDENTIFIER_POINTER (name)); - pedwarn_with_file_and_line (file, line, - "previous declaration of `%s'", - IDENTIFIER_POINTER (name)); - } - - return t; - } - - /* If we are processing a typedef statement, generate a whole new - ..._TYPE node (which will be just an variant of the existing - ..._TYPE node with identical properties) and then install the - TYPE_DECL node generated to represent the typedef name as the - TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each - and every ..._TYPE node the compiler creates will be uniquely - associated with AT MOST one node representing a typedef name. - This way, even though the compiler substitutes corresponding - ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very - early on, later parts of the compiler can always do the reverse - translation and get back the corresponding typedef name. For - example, given: - - typedef struct S MY_TYPE; - MY_TYPE object; - - Later parts of the compiler might only know that `object' was of - type `struct S' if if were not for code just below. With this - code however, later parts of the compiler see something like: - - struct S' == struct S - typedef struct S' MY_TYPE; - struct S' object; - - And they can then deduce (from the node for type struct S') that - the original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, - and also for generating precise symbolic debugging information - which takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if - the TYPE_DECL node that we are now processing really represents a - standard built-in type. - - Since all standard types are effectively declared at line zero - in the source file, we can easily check to see if we are working - on a standard type by checking the current value of lineno. */ - - if (TREE_CODE (x) == TYPE_DECL) - { - if (DECL_SOURCE_LINE (x) == 0) - { - if (TYPE_NAME (TREE_TYPE (x)) == 0) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else if (TREE_TYPE (x) != error_mark_node) - { - tree tt = TREE_TYPE (x); - - tt = build_type_copy (tt); - TYPE_NAME (tt) = x; - TREE_TYPE (x) = tt; - } - } - - /* Multiple external decls of the same identifier ought to match. - Check against both global declarations and out of scope (limbo) block - level declarations. - - We get warnings about inline functions where they are defined. - Avoid duplicate warnings where they are used. */ - if (TREE_PUBLIC (x) && ! DECL_INLINE (x)) - { - tree decl; - - if (IDENTIFIER_GLOBAL_VALUE (name) != 0 - && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) - || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name)))) - decl = IDENTIFIER_GLOBAL_VALUE (name); - else if (IDENTIFIER_LIMBO_VALUE (name) != 0) - /* Decls in limbo are always extern, so no need to check that. */ - decl = IDENTIFIER_LIMBO_VALUE (name); - else - decl = 0; - - if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl)) - /* If old decl is built-in, we already warned if we should. */ - && !DECL_BUILT_IN (decl)) - { - pedwarn_with_decl (x, - "type mismatch with previous external decl"); - pedwarn_with_decl (decl, "previous external decl of `%s'"); - } - } - - /* If a function has had an implicit declaration, and then is defined, - make sure they are compatible. */ - - if (IDENTIFIER_IMPLICIT_DECL (name) != 0 - && IDENTIFIER_GLOBAL_VALUE (name) == 0 - && TREE_CODE (x) == FUNCTION_DECL - && ! comptypes (TREE_TYPE (x), - TREE_TYPE (IDENTIFIER_IMPLICIT_DECL (name)))) - { - warning_with_decl (x, "type mismatch with previous implicit declaration"); - warning_with_decl (IDENTIFIER_IMPLICIT_DECL (name), - "previous implicit declaration of `%s'"); - } - - /* In PCC-compatibility mode, extern decls of vars with no current decl - take effect at top level no matter where they are. */ - if (flag_traditional && DECL_EXTERNAL (x) - && lookup_name (name) == 0) - { - tree type = TREE_TYPE (x); - - /* But don't do this if the type contains temporary nodes. */ - while (type) - { - if (type == error_mark_node) - break; - if (! TREE_PERMANENT (type)) - { - warning_with_decl (x, "type of external `%s' is not global"); - /* By exiting the loop early, we leave TYPE nonzero, - and thus prevent globalization of the decl. */ - break; - } - else if (TREE_CODE (type) == FUNCTION_TYPE - && TYPE_ARG_TYPES (type) != 0) - /* The types might not be truly local, - but the list of arg types certainly is temporary. - Since prototypes are nontraditional, - ok not to do the traditional thing. */ - break; - type = TREE_TYPE (type); - } - - if (type == 0) - b = global_binding_level; - } - - /* This name is new in its binding level. - Install the new declaration and return it. */ - if (b == global_binding_level) - { - /* Install a global value. */ - - /* If the first global decl has external linkage, - warn if we later see static one. */ - if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x)) - TREE_PUBLIC (name) = 1; - - IDENTIFIER_GLOBAL_VALUE (name) = x; - - /* We no longer care about any previous block level declarations. */ - IDENTIFIER_LIMBO_VALUE (name) = 0; - - /* Don't forget if the function was used via an implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_USED (x) = 1, TREE_USED (name) = 1; - - /* Don't forget if its address was taken in that way. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_ADDRESSABLE (x) = 1; - - /* Warn about mismatches against previous implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) != 0 - /* If this real decl matches the implicit, don't complain. */ - && ! (TREE_CODE (x) == FUNCTION_DECL - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (x))) - == integer_type_node))) - pedwarn ("`%s' was previously implicitly declared to return `int'", - IDENTIFIER_POINTER (name)); - - /* If this decl is `static' and an `extern' was seen previously, - that is erroneous. */ - if (TREE_PUBLIC (name) - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x)) - { - /* Okay to redeclare an ANSI built-in as static. */ - if (t != 0 && DECL_BUILT_IN (t)) - ; - /* Okay to declare a non-ANSI built-in as anything. */ - else if (t != 0 && DECL_BUILT_IN_NONANSI (t)) - ; - else if (IDENTIFIER_IMPLICIT_DECL (name)) - pedwarn ("`%s' was declared implicitly `extern' and later `static'", - IDENTIFIER_POINTER (name)); - else - pedwarn ("`%s' was declared `extern' and later `static'", - IDENTIFIER_POINTER (name)); - } - } - else - { - /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); - tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name); - IDENTIFIER_LOCAL_VALUE (name) = x; - - /* If this is an extern function declaration, see if we - have a global definition or declaration for the function. */ - if (oldlocal == 0 - && DECL_EXTERNAL (x) && !DECL_INLINE (x) - && oldglobal != 0 - && TREE_CODE (x) == FUNCTION_DECL - && TREE_CODE (oldglobal) == FUNCTION_DECL) - { - /* We have one. Their types must agree. */ - if (! comptypes (TREE_TYPE (x), - TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)))) - pedwarn_with_decl (x, "extern declaration of `%s' doesn't match global one"); - else - { - /* Inner extern decl is inline if global one is. - Copy enough to really inline it. */ - if (DECL_INLINE (oldglobal)) - { - DECL_INLINE (x) = DECL_INLINE (oldglobal); - DECL_INITIAL (x) = (current_function_decl == oldglobal - ? 0 : DECL_INITIAL (oldglobal)); - DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal); - DECL_FRAME_SIZE (x) = DECL_FRAME_SIZE (oldglobal); - DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal); - DECL_RESULT (x) = DECL_RESULT (oldglobal); - TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal); - DECL_ABSTRACT_ORIGIN (x) = oldglobal; - } - /* Inner extern decl is built-in if global one is. */ - if (DECL_BUILT_IN (oldglobal)) - { - DECL_BUILT_IN (x) = DECL_BUILT_IN (oldglobal); - DECL_SET_FUNCTION_CODE (x, DECL_FUNCTION_CODE (oldglobal)); - } - /* Keep the arg types from a file-scope fcn defn. */ - if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0 - && DECL_INITIAL (oldglobal) - && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0) - TREE_TYPE (x) = TREE_TYPE (oldglobal); - } - } - -#if 0 /* This case is probably sometimes the right thing to do. */ - /* If we have a local external declaration, - then any file-scope declaration should not - have been static. */ - if (oldlocal == 0 && oldglobal != 0 - && !TREE_PUBLIC (oldglobal) - && DECL_EXTERNAL (x) && TREE_PUBLIC (x)) - warning ("`%s' locally external but globally static", - IDENTIFIER_POINTER (name)); -#endif - - /* If we have a local external declaration, - and no file-scope declaration has yet been seen, - then if we later have a file-scope decl it must not be static. */ - if (oldlocal == 0 - && oldglobal == 0 - && DECL_EXTERNAL (x) - && TREE_PUBLIC (x)) - { - TREE_PUBLIC (name) = 1; - - /* Save this decl, so that we can do type checking against - other decls after it falls out of scope. - - Only save it once. This prevents temporary decls created in - expand_inline_function from being used here, since this - will have been set when the inline function was parsed. - It also helps give slightly better warnings. */ - if (IDENTIFIER_LIMBO_VALUE (name) == 0) - IDENTIFIER_LIMBO_VALUE (name) = x; - } - - /* Warn if shadowing an argument at the top level of the body. */ - if (oldlocal != 0 && !DECL_EXTERNAL (x) - /* This warning doesn't apply to the parms of a nested fcn. */ - && ! current_binding_level->parm_flag - /* Check that this is one level down from the parms. */ - && current_binding_level->level_chain->parm_flag - /* Check that the decl being shadowed - comes from the parm level, one level up. */ - && chain_member (oldlocal, current_binding_level->level_chain->names)) - { - if (TREE_CODE (oldlocal) == PARM_DECL) - pedwarn ("declaration of `%s' shadows a parameter", - IDENTIFIER_POINTER (name)); - else - pedwarn ("declaration of `%s' shadows a symbol from the parameter list", - IDENTIFIER_POINTER (name)); - } - - /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && DECL_SOURCE_LINE (x) != 0 - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) - { - char *warnstring = 0; - - if (TREE_CODE (x) == PARM_DECL - && current_binding_level->level_chain->parm_flag) - /* Don't warn about the parm names in function declarator - within a function declarator. - It would be nice to avoid warning in any function - declarator in a declaration, as opposed to a definition, - but there is no way to tell it's not a definition. */ - ; - else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) - warnstring = "declaration of `%s' shadows a parameter"; - else if (oldlocal != 0) - warnstring = "declaration of `%s' shadows previous local"; - else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 - && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) - warnstring = "declaration of `%s' shadows global declaration"; - - if (warnstring) - warning (warnstring, IDENTIFIER_POINTER (name)); - } - - /* If storing a local value, there may already be one (inherited). - If so, record it for restoration when this binding level ends. */ - if (oldlocal != 0) - b->shadowed = tree_cons (name, oldlocal, b->shadowed); - } - - /* Keep count of variables in this level with incomplete type. */ - if (TYPE_SIZE (TREE_TYPE (x)) == 0) - ++b->n_incomplete; - } - - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = b->names; - b->names = x; - - return x; -} - -/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ - -tree -pushdecl_top_level (x) - tree x; -{ - register tree t; - register struct binding_level *b = current_binding_level; - - current_binding_level = global_binding_level; - t = pushdecl (x); - current_binding_level = b; - return t; -} - -/* Generate an implicit declaration for identifier FUNCTIONID - as a function of type int (). Print a warning if appropriate. */ - -tree -implicitly_declare (functionid) - tree functionid; -{ - register tree decl; - int traditional_warning = 0; - /* Only one "implicit declaration" warning per identifier. */ - int implicit_warning; - - /* Save the decl permanently so we can warn if definition follows. */ - push_obstacks_nochange (); - end_temporary_allocation (); - - /* We used to reuse an old implicit decl here, - but this loses with inline functions because it can clobber - the saved decl chains. */ -/* if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0) - decl = IDENTIFIER_IMPLICIT_DECL (functionid); - else */ - decl = build_decl (FUNCTION_DECL, functionid, default_function_type); - - /* Warn of implicit decl following explicit local extern decl. - This is probably a program designed for traditional C. */ - if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0) - traditional_warning = 1; - - /* Warn once of an implicit declaration. */ - implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0); - - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* Record that we have an implicit decl and this is it. */ - IDENTIFIER_IMPLICIT_DECL (functionid) = decl; - - /* ANSI standard says implicit declarations are in the innermost block. - So we record the decl in the standard fashion. - If flag_traditional is set, pushdecl does it top-level. */ - pushdecl (decl); - - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - - rest_of_decl_compilation (decl, NULL_PTR, 0, 0); - - if (warn_implicit && implicit_warning) - warning ("implicit declaration of function `%s'", - IDENTIFIER_POINTER (functionid)); - else if (warn_traditional && traditional_warning) - warning ("function `%s' was previously declared within a block", - IDENTIFIER_POINTER (functionid)); - - /* Write a record describing this implicit function declaration to the - prototypes file (if requested). */ - - gen_aux_info_record (decl, 0, 1, 0); - - pop_obstacks (); - - return decl; -} - -/* Return zero if the declaration NEWDECL is valid - when the declaration OLDDECL (assumed to be for the same name) - has already been seen. - Otherwise return an error message format string with a %s - where the identifier should go. */ - -static char * -redeclaration_error_message (newdecl, olddecl) - tree newdecl, olddecl; -{ - if (TREE_CODE (newdecl) == TYPE_DECL) - { - if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl)) - return 0; - return "redefinition of `%s'"; - } - else if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* Declarations of functions can insist on internal linkage - but they can't be inconsistent with internal linkage, - so there can be no error on that account. - However defining the same name twice is no good. */ - if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0 - /* However, defining once as extern inline and a second - time in another way is ok. */ - && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) - && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) - return "redefinition of `%s'"; - return 0; - } - else if (current_binding_level == global_binding_level) - { - /* Objects declared at top level: */ - /* If at least one is a reference, it's ok. */ - if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) - return 0; - /* Reject two definitions. */ - if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0) - return "redefinition of `%s'"; - /* Now we have two tentative defs, or one tentative and one real def. */ - /* Insist that the linkage match. */ - if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl)) - return "conflicting declarations of `%s'"; - return 0; - } - else if (current_binding_level->parm_flag - && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) - return 0; - else - { - /* Objects declared with block scope: */ - /* Reject two definitions, and reject a definition - together with an external reference. */ - if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))) - return "redeclaration of `%s'"; - return 0; - } -} - -/* Get the LABEL_DECL corresponding to identifier ID as a label. - Create one if none exists so far for the current function. - This function is called for both label definitions and label references. */ - -tree -lookup_label (id) - tree id; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (id); - - if (current_function_decl == 0) - { - error ("label %s referenced outside of any function", - IDENTIFIER_POINTER (id)); - return 0; - } - - /* Use a label already defined or ref'd with this name. */ - if (decl != 0) - { - /* But not if it is inherited and wasn't declared to be inheritable. */ - if (DECL_CONTEXT (decl) != current_function_decl - && ! C_DECLARED_LABEL_FLAG (decl)) - return shadow_label (id); - return decl; - } - - decl = build_decl (LABEL_DECL, id, void_type_node); - - /* Make sure every label has an rtx. */ - label_rtx (decl); - - /* A label not explicitly declared must be local to where it's ref'd. */ - DECL_CONTEXT (decl) = current_function_decl; - - DECL_MODE (decl) = VOIDmode; - - /* Say where one reference is to the label, - for the sake of the error if it is not defined. */ - DECL_SOURCE_LINE (decl) = lineno; - DECL_SOURCE_FILE (decl) = input_filename; - - IDENTIFIER_LABEL_VALUE (id) = decl; - - named_labels = tree_cons (NULL_TREE, decl, named_labels); - - return decl; -} - -/* Make a label named NAME in the current function, - shadowing silently any that may be inherited from containing functions - or containing scopes. - - Note that valid use, if the label being shadowed - comes from another scope in the same function, - requires calling declare_nonlocal_label right away. */ - -tree -shadow_label (name) - tree name; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (name); - - if (decl != 0) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - IDENTIFIER_LABEL_VALUE (name) = decl = 0; - } - - return lookup_label (name); -} - -/* Define a label, specifying the location in the source file. - Return the LABEL_DECL node for the label, if the definition is valid. - Otherwise return 0. */ - -tree -define_label (filename, line, name) - char *filename; - int line; - tree name; -{ - tree decl = lookup_label (name); - - /* If label with this name is known from an outer context, shadow it. */ - if (decl != 0 && DECL_CONTEXT (decl) != current_function_decl) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - IDENTIFIER_LABEL_VALUE (name) = 0; - decl = lookup_label (name); - } - - if (DECL_INITIAL (decl) != 0) - { - error ("duplicate label `%s'", IDENTIFIER_POINTER (name)); - return 0; - } - else - { - /* Mark label as having been defined. */ - DECL_INITIAL (decl) = error_mark_node; - /* Say where in the source. */ - DECL_SOURCE_FILE (decl) = filename; - DECL_SOURCE_LINE (decl) = line; - return decl; - } -} - -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls () -{ - return current_binding_level->names; -} - -/* Return the list of type-tags (for structs, etc) of the current level. */ - -tree -gettags () -{ - return current_binding_level->tags; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static void -storedecls (decls) - tree decls; -{ - current_binding_level->names = decls; -} - -/* Similarly, store the list of tags of the current level. */ - -static void -storetags (tags) - tree tags; -{ - current_binding_level->tags = tags; -} - -/* Given NAME, an IDENTIFIER_NODE, - return the structure (or union or enum) definition for that name. - Searches binding levels from BINDING_LEVEL up to the global level. - If THISLEVEL_ONLY is nonzero, searches only the specified context - (but skips any tag-transparent contexts to find one that is - meaningful for tags). - CODE says which kind of type the caller wants; - it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. - If the wrong kind of type is found, an error is reported. */ - -static tree -lookup_tag (code, name, binding_level, thislevel_only) - enum tree_code code; - struct binding_level *binding_level; - tree name; - int thislevel_only; -{ - register struct binding_level *level; - - for (level = binding_level; level; level = level->level_chain) - { - register tree tail; - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_PURPOSE (tail) == name) - { - if (TREE_CODE (TREE_VALUE (tail)) != code) - { - /* Definition isn't the kind we were looking for. */ - pending_invalid_xref = name; - pending_invalid_xref_file = input_filename; - pending_invalid_xref_line = lineno; - } - return TREE_VALUE (tail); - } - } - if (thislevel_only && ! level->tag_transparent) - return NULL_TREE; - } - return NULL_TREE; -} - -/* Print an error message now - for a recent invalid struct, union or enum cross reference. - We don't print them immediately because they are not invalid - when used in the `struct foo;' construct for shadowing. */ - -void -pending_xref_error () -{ - if (pending_invalid_xref != 0) - error_with_file_and_line (pending_invalid_xref_file, - pending_invalid_xref_line, - "`%s' defined as wrong kind of tag", - IDENTIFIER_POINTER (pending_invalid_xref)); - pending_invalid_xref = 0; -} - -/* Given a type, find the tag that was defined for it and return the tag name. - Otherwise return 0. */ - -static tree -lookup_tag_reverse (type) - tree type; -{ - register struct binding_level *level; - - for (level = current_binding_level; level; level = level->level_chain) - { - register tree tail; - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_VALUE (tail) == type) - return TREE_PURPOSE (tail); - } - } - return NULL_TREE; -} - -/* Look up NAME in the current binding level and its superiors - in the namespace of variables, functions and typedefs. - Return a ..._DECL node of some kind representing its definition, - or return 0 if it is undefined. */ - -tree -lookup_name (name) - tree name; -{ - register tree val; - if (current_binding_level != global_binding_level - && IDENTIFIER_LOCAL_VALUE (name)) - val = IDENTIFIER_LOCAL_VALUE (name); - else - val = IDENTIFIER_GLOBAL_VALUE (name); - return val; -} - -/* Similar to `lookup_name' but look only at current binding level. */ - -tree -lookup_name_current_level (name) - tree name; -{ - register tree t; - - if (current_binding_level == global_binding_level) - return IDENTIFIER_GLOBAL_VALUE (name); - - if (IDENTIFIER_LOCAL_VALUE (name) == 0) - return 0; - - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) - if (DECL_NAME (t) == name) - break; - - return t; -} - -/* Create the predefined scalar types of C, - and some nodes representing standard constants (0, 1, (void *)0). - Initialize the global binding level. - Make definitions for built-in primitive functions. */ - -void -init_decl_processing () -{ - register tree endlink; - /* Either char* or void*. */ - tree traditional_ptr_type_node; - /* Data types of memcpy and strlen. */ - tree memcpy_ftype, strlen_ftype; - tree void_ftype_any; - int wchar_type_size; - tree temp; - tree array_domain_type; - - current_function_decl = NULL; - named_labels = NULL; - current_binding_level = NULL_BINDING_LEVEL; - free_binding_level = NULL_BINDING_LEVEL; - pushlevel (0); /* make the binding_level structure for global names */ - global_binding_level = current_binding_level; - - /* Define `int' and `char' first so that dbx will output them first. */ - - integer_type_node = make_signed_type (INT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_INT], - integer_type_node)); - - /* Define `char', which is like either `signed char' or `unsigned char' - but not the same as either. */ - - char_type_node - = (flag_signed_char - ? make_signed_type (CHAR_TYPE_SIZE) - : make_unsigned_type (CHAR_TYPE_SIZE)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), - char_type_node)); - - long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"), - long_integer_type_node)); - - unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"), - unsigned_type_node)); - - long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"), - long_unsigned_type_node)); - - /* `unsigned long' is the standard type for sizeof. - Traditionally, use a signed type. - Note that stddef.h uses `unsigned long', - and this must agree, even of long and int are the same size. */ - if (flag_traditional) - sizetype = long_integer_type_node; - else - sizetype - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); - - ptrdiff_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); - - TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype; - - error_mark_node = make_node (ERROR_MARK); - TREE_TYPE (error_mark_node) = error_mark_node; - - short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"), - short_integer_type_node)); - - long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"), - long_long_integer_type_node)); - - short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"), - short_unsigned_type_node)); - - long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"), - long_long_unsigned_type_node)); - - /* Define both `signed char' and `unsigned char'. */ - signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"), - signed_char_type_node)); - - unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"), - unsigned_char_type_node)); - - intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node)); - - intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node)); - - intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); - - intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); - - unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); - - unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node)); - - unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); - - unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); - - float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT], - float_type_node)); - layout_type (float_type_node); - - double_type_node = make_node (REAL_TYPE); - if (flag_short_double) - TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE; - else - TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; - pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_DOUBLE], - double_type_node)); - layout_type (double_type_node); - - long_double_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; - pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"), - long_double_type_node)); - layout_type (long_double_type_node); - - complex_integer_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), - complex_integer_type_node)); - TREE_TYPE (complex_integer_type_node) = integer_type_node; - layout_type (complex_integer_type_node); - - complex_float_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), - complex_float_type_node)); - TREE_TYPE (complex_float_type_node) = float_type_node; - layout_type (complex_float_type_node); - - complex_double_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), - complex_double_type_node)); - TREE_TYPE (complex_double_type_node) = double_type_node; - layout_type (complex_double_type_node); - - complex_long_double_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), - complex_long_double_type_node)); - TREE_TYPE (complex_long_double_type_node) = long_double_type_node; - layout_type (complex_long_double_type_node); - - wchar_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); - wchar_type_size = TYPE_PRECISION (wchar_type_node); - signed_wchar_type_node = type_for_size (wchar_type_size, 0); - unsigned_wchar_type_node = type_for_size (wchar_type_size, 1); - - integer_zero_node = build_int_2 (0, 0); - TREE_TYPE (integer_zero_node) = integer_type_node; - integer_one_node = build_int_2 (1, 0); - TREE_TYPE (integer_one_node) = integer_type_node; - - size_zero_node = build_int_2 (0, 0); - TREE_TYPE (size_zero_node) = sizetype; - size_one_node = build_int_2 (1, 0); - TREE_TYPE (size_one_node) = sizetype; - - void_type_node = make_node (VOID_TYPE); - pushdecl (build_decl (TYPE_DECL, - ridpointers[(int) RID_VOID], void_type_node)); - layout_type (void_type_node); /* Uses integer_zero_node */ - /* We are not going to have real types in C with less than byte alignment, - so we might as well not have any types that claim to have it. */ - TYPE_ALIGN (void_type_node) = BITS_PER_UNIT; - - null_pointer_node = build_int_2 (0, 0); - TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); - layout_type (TREE_TYPE (null_pointer_node)); - - string_type_node = build_pointer_type (char_type_node); - const_string_type_node - = build_pointer_type (build_type_variant (char_type_node, 1, 0)); - - /* Make a type to be the domain of a few array types - whose domains don't really matter. - 200 is small enough that it always fits in size_t - and large enough that it can hold most function names for the - initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ - array_domain_type = build_index_type (build_int_2 (200, 0)); - - /* make a type for arrays of characters. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node - = build_array_type (char_type_node, array_domain_type); - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, array_domain_type); - /* This is for wide string constants. */ - wchar_array_type_node - = build_array_type (wchar_type_node, array_domain_type); - - default_function_type - = build_function_type (integer_type_node, NULL_TREE); - - ptr_type_node = build_pointer_type (void_type_node); - const_ptr_type_node - = build_pointer_type (build_type_variant (void_type_node, 1, 0)); - - endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE); - - void_ftype_any - = build_function_type (void_type_node, NULL_TREE); - - double_ftype_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, double_type_node, endlink)); - - double_ftype_double_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, double_type_node, - tree_cons (NULL_TREE, - double_type_node, endlink))); - - int_ftype_int - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, endlink)); - - long_ftype_long - = build_function_type (long_integer_type_node, - tree_cons (NULL_TREE, - long_integer_type_node, endlink)); - - void_ftype_ptr_ptr_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)))); - - int_ftype_cptr_cptr_sizet - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)))); - - void_ftype_ptr_int_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)))); - - string_ftype_ptr_ptr /* strcpy prototype */ - = build_function_type (string_type_node, - tree_cons (NULL_TREE, string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - int_ftype_string_string /* strcmp prototype */ - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - strlen_ftype /* strlen prototype */ - = build_function_type (flag_traditional ? integer_type_node : sizetype, - tree_cons (NULL_TREE, const_string_type_node, - endlink)); - - traditional_ptr_type_node - = (flag_traditional ? string_type_node : ptr_type_node); - - memcpy_ftype /* memcpy prototype */ - = build_function_type (traditional_ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)))); - - builtin_function ("__builtin_constant_p", int_ftype_int, - BUILT_IN_CONSTANT_P, NULL_PTR); - - builtin_function ("__builtin_return_address", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - unsigned_type_node, - endlink)), - BUILT_IN_RETURN_ADDRESS, NULL_PTR); - - builtin_function ("__builtin_frame_address", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - unsigned_type_node, - endlink)), - BUILT_IN_FRAME_ADDRESS, NULL_PTR); - - builtin_function ("__builtin_alloca", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)), - BUILT_IN_ALLOCA, "alloca"); - builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); - /* Define alloca, ffs as builtins. - Declare _exit just to mark it as volatile. */ - if (! flag_no_builtin && !flag_no_nonansi_builtin) - { - temp = builtin_function ("alloca", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)), - BUILT_IN_ALLOCA, NULL_PTR); - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("_exit", void_ftype_any, NOT_BUILT_IN, - NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - } - - builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("__builtin_fabs", double_ftype_double, BUILT_IN_FABS, - NULL_PTR); - builtin_function ("__builtin_labs", long_ftype_long, BUILT_IN_LABS, - NULL_PTR); - builtin_function ("__builtin_saveregs", - build_function_type (ptr_type_node, NULL_TREE), - BUILT_IN_SAVEREGS, NULL_PTR); -/* EXPAND_BUILTIN_VARARGS is obsolete. */ -#if 0 - builtin_function ("__builtin_varargs", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)), - BUILT_IN_VARARGS, NULL_PTR); -#endif - builtin_function ("__builtin_classify_type", default_function_type, - BUILT_IN_CLASSIFY_TYPE, NULL_PTR); - builtin_function ("__builtin_next_arg", - build_function_type (ptr_type_node, endlink), - BUILT_IN_NEXT_ARG, NULL_PTR); - builtin_function ("__builtin_args_info", - build_function_type (integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)), - BUILT_IN_ARGS_INFO, NULL_PTR); - - /* Untyped call and return. */ - builtin_function ("__builtin_apply_args", - build_function_type (ptr_type_node, NULL_TREE), - BUILT_IN_APPLY_ARGS, NULL_PTR); - - temp = tree_cons (NULL_TREE, - build_pointer_type (build_function_type (void_type_node, - NULL_TREE)), - tree_cons (NULL_TREE, - ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink))); - builtin_function ("__builtin_apply", - build_function_type (ptr_type_node, temp), - BUILT_IN_APPLY, NULL_PTR); - builtin_function ("__builtin_return", - build_function_type (void_type_node, - tree_cons (NULL_TREE, - ptr_type_node, - endlink)), - BUILT_IN_RETURN, NULL_PTR); - - /* Currently under experimentation. */ - builtin_function ("__builtin_memcpy", memcpy_ftype, - BUILT_IN_MEMCPY, "memcpy"); - builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet, - BUILT_IN_MEMCMP, "memcmp"); - builtin_function ("__builtin_strcmp", int_ftype_string_string, - BUILT_IN_STRCMP, "strcmp"); - builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr, - BUILT_IN_STRCPY, "strcpy"); - builtin_function ("__builtin_strlen", strlen_ftype, - BUILT_IN_STRLEN, "strlen"); - builtin_function ("__builtin_fsqrt", double_ftype_double, - BUILT_IN_FSQRT, "sqrt"); - builtin_function ("__builtin_sin", double_ftype_double, - BUILT_IN_SIN, "sin"); - builtin_function ("__builtin_cos", double_ftype_double, - BUILT_IN_COS, "cos"); - - /* In an ANSI C program, it is okay to supply built-in meanings - for these functions, since applications cannot validly use them - with any other meaning. - However, honor the -fno-builtin option. */ - if (!flag_no_builtin) - { - builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR); - builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR); - builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR); - builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP, - NULL_PTR); - builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, - NULL_PTR); - builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, - NULL_PTR); - builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN, NULL_PTR); - builtin_function ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); - builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); - - /* Declare these functions volatile - to avoid spurious "control drops through" warnings. */ - /* Don't specify the argument types, to avoid errors - from certain code which isn't valid in ANSI but which exists. */ - temp = builtin_function ("abort", void_ftype_any, NOT_BUILT_IN, - NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - temp = builtin_function ("exit", void_ftype_any, NOT_BUILT_IN, NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - } - -#if 0 - /* Support for these has not been written in either expand_builtin - or build_function_call. */ - builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, NULL_PTR); - builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR); - builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, - NULL_PTR); - builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, - NULL_PTR); - builtin_function ("__builtin_fmod", double_ftype_double_double, - BUILT_IN_FMOD, NULL_PTR); - builtin_function ("__builtin_frem", double_ftype_double_double, - BUILT_IN_FREM, NULL_PTR); - builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, - BUILT_IN_MEMSET, NULL_PTR); - builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, - NULL_PTR); - builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, - NULL_PTR); -#endif - - /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ - declare_function_name (); - - start_identifier_warnings (); - - init_format_info_table (); - - init_iterators (); - - incomplete_decl_finalize_hook = finish_incomplete_decl; -} - -/* Return a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. - FUNCTION_CODE tells later passes how to compile calls to this function. - See tree.h for its possible values. - - If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, - the name to be called if we can't opencode the function. */ - -tree -builtin_function (name, type, function_code, library_name) - char *name; - tree type; - enum built_in_function function_code; - char *library_name; -{ - tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - /* If -traditional, permit redefining a builtin function any way you like. - (Though really, if the program redefines these functions, - it probably won't work right unless compiled with -fno-builtin.) */ - if (flag_traditional && name[0] != '_') - DECL_BUILT_IN_NONANSI (decl) = 1; - if (library_name) - DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); - make_decl_rtl (decl, NULL_PTR, 1); - pushdecl (decl); - if (function_code != NOT_BUILT_IN) - { - DECL_BUILT_IN (decl) = 1; - DECL_SET_FUNCTION_CODE (decl, function_code); - } - /* Warn if a function in the namespace for users - is used without an occasion to consider it declared. */ - if (name[0] != '_' || name[1] != '_') - C_DECL_ANTICIPATED (decl) = 1; - - return decl; -} - -/* Called when a declaration is seen that contains no names to declare. - If its type is a reference to a structure, union or enum inherited - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. */ - -void -shadow_tag (declspecs) - tree declspecs; -{ - shadow_tag_warned (declspecs, 0); -} - -void -shadow_tag_warned (declspecs, warned) - tree declspecs; - int warned; - /* 1 => we have done a pedwarn. 2 => we have done a warning, but - no pedwarn. */ -{ - int found_tag = 0; - register tree link; - - pending_invalid_xref = 0; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - register tree value = TREE_VALUE (link); - register enum tree_code code = TREE_CODE (value); - - if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE) - /* Used to test also that TYPE_SIZE (value) != 0. - That caused warning for `struct foo;' at top level in the file. */ - { - register tree name = lookup_tag_reverse (value); - register tree t; - - found_tag++; - - if (name == 0) - { - if (warned != 1 && code != ENUMERAL_TYPE) - /* Empty unnamed enum OK */ - { - pedwarn ("unnamed struct/union that defines no instances"); - warned = 1; - } - } - else - { - t = lookup_tag (code, name, current_binding_level, 1); - - if (t == 0) - { - t = make_node (code); - pushtag (name, t); - } - } - } - else - { - if (!warned) - { - warning ("useless keyword or type name in empty declaration"); - warned = 2; - } - } - } - - if (found_tag > 1) - error ("two types specified in one empty declaration"); - - if (warned != 1) - { - if (found_tag == 0) - pedwarn ("empty declaration"); - } -} - -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ - -tree -groktypename (typename) - tree typename; -{ - if (TREE_CODE (typename) != TREE_LIST) - return typename; - return grokdeclarator (TREE_VALUE (typename), - TREE_PURPOSE (typename), - TYPENAME, 0); -} - -/* Return a PARM_DECL node for a given pair of specs and declarator. */ - -tree -groktypename_in_parm_context (typename) - tree typename; -{ - if (TREE_CODE (typename) != TREE_LIST) - return typename; - return grokdeclarator (TREE_VALUE (typename), - TREE_PURPOSE (typename), - PARM, 0); -} - -/* Decode a declarator in an ordinary declaration or data definition. - This is called as soon as the type information and variable name - have been parsed, before parsing the initializer if any. - Here we create the ..._DECL node, fill in its type, - and put it on the list of decls for the current context. - The ..._DECL node is returned as the value. - - Exception: for arrays where the length is not specified, - the type is left null, to be filled in by `finish_decl'. - - Function definitions do not come here; they go to start_function - instead. However, external and forward declarations of functions - do go through here. Structure field declarations are done by - grokfield and not through here. */ - -/* Set this to zero to debug not using the temporary obstack - to parse initializers. */ -int debug_temp_inits = 1; - -tree -start_decl (declarator, declspecs, initialized) - tree declarator, declspecs; - int initialized; -{ - register tree decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized); - register tree tem; - int init_written = initialized; - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `finish_decl' to ignore the initializer once it is parsed. */ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - error ("typedef `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - break; - - case FUNCTION_DECL: - error ("function `%s' is initialized like a variable", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - break; - - case PARM_DECL: - /* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE. */ - error ("parameter `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - break; - - default: - /* Don't allow initializations for incomplete types - except for arrays which might be completed by the initialization. */ - if (TYPE_SIZE (TREE_TYPE (decl)) != 0) - { - /* A complete type is ok if size is fixed. */ - - if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST - || C_DECL_VARIABLE_SIZE (decl)) - { - error ("variable-sized object may not be initialized"); - initialized = 0; - } - } - else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) - { - error ("variable `%s' has initializer but incomplete type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - else if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))) == 0) - { - error ("elements of array `%s' have incomplete type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - } - - if (initialized) - { -#if 0 /* Seems redundant with grokdeclarator. */ - if (current_binding_level != global_binding_level - && DECL_EXTERNAL (decl) - && TREE_CODE (decl) != FUNCTION_DECL) - warning ("declaration of `%s' has `extern' and is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); -#endif - DECL_EXTERNAL (decl) = 0; - if (current_binding_level == global_binding_level) - TREE_STATIC (decl) = 1; - - /* Tell `pushdecl' this is an initialized decl - even though we don't yet have the initializer expression. - Also tell `finish_decl' it may store the real initializer. */ - DECL_INITIAL (decl) = error_mark_node; - } - - /* If this is a function declaration, write a record describing it to the - prototypes file (if requested). */ - - if (TREE_CODE (decl) == FUNCTION_DECL) - gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0); - - /* Add this decl to the current binding level. - TEM may equal DECL or it may be a previous decl of the same name. */ - tem = pushdecl (decl); - - /* For a local variable, define the RTL now. */ - if (current_binding_level != global_binding_level - /* But not if this is a duplicate decl - and we preserved the rtl from the previous one - (which may or may not happen). */ - && DECL_RTL (tem) == 0) - { - if (TYPE_SIZE (TREE_TYPE (tem)) != 0) - expand_decl (tem); - else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE - && DECL_INITIAL (tem) != 0) - expand_decl (tem); - } - - if (init_written) - { - /* When parsing and digesting the initializer, - use temporary storage. Do this even if we will ignore the value. */ - if (current_binding_level == global_binding_level && debug_temp_inits) - temporary_allocation (); - } - - return tem; -} - -/* Finish processing of a declaration; - install its initial value. - If the length of an array type is not known before, - it must be determined now, from the initial value, or it is an error. */ - -void -finish_decl (decl, init, asmspec_tree) - tree decl, init; - tree asmspec_tree; -{ - register tree type = TREE_TYPE (decl); - int was_incomplete = (DECL_SIZE (decl) == 0); - int temporary = allocation_temporary_p (); - char *asmspec = 0; - - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - /* If `start_decl' didn't like having an initialization, ignore it now. */ - - if (init != 0 && DECL_INITIAL (decl) == 0) - init = 0; - /* Don't crash if parm is initialized. */ - if (TREE_CODE (decl) == PARM_DECL) - init = 0; - - if (ITERATOR_P (decl)) - { - if (init == 0) - error_with_decl (decl, "iterator has no initial value"); - else - init = save_expr (init); - } - - if (init) - { - if (TREE_CODE (decl) != TYPE_DECL) - store_init_value (decl, init); - else - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = TREE_TYPE (init); - DECL_INITIAL (decl) = init = 0; - } - } - - /* Pop back to the obstack that is current for this binding level. - This is because MAXINDEX, rtl, etc. to be made below - must go in the permanent obstack. But don't discard the - temporary data yet. */ - pop_obstacks (); -#if 0 /* pop_obstacks was near the end; this is what was here. */ - if (current_binding_level == global_binding_level && temporary) - end_temporary_allocation (); -#endif - - /* Deduce size of array from initialization, if not already known */ - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == 0 - && TREE_CODE (decl) != TYPE_DECL) - { - int do_default - = (TREE_STATIC (decl) - /* Even if pedantic, an external linkage array - may have incomplete type at first. */ - ? pedantic && !TREE_PUBLIC (decl) - : !DECL_EXTERNAL (decl)); - int failure - = complete_array_type (type, DECL_INITIAL (decl), do_default); - - /* Get the completed type made by complete_array_type. */ - type = TREE_TYPE (decl); - - if (failure == 1) - error_with_decl (decl, "initializer fails to determine size of `%s'"); - - if (failure == 2) - { - if (do_default) - error_with_decl (decl, "array size missing in `%s'"); - /* If a `static' var's size isn't known, - make it extern as well as static, so it does not get - allocated. - If it is not `static', then do not mark extern; - finish_incomplete_decl will give it a default size - and it will get allocated. */ - else if (!pedantic && TREE_STATIC (decl) && ! TREE_PUBLIC (decl)) - DECL_EXTERNAL (decl) = 1; - } - - if (pedantic && TYPE_DOMAIN (type) != 0 - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) - error_with_decl (decl, "zero-size array `%s'"); - - layout_decl (decl, 0); - } - - if (TREE_CODE (decl) == VAR_DECL) - { - if (DECL_SIZE (decl) == 0 - && TYPE_SIZE (TREE_TYPE (decl)) != 0) - layout_decl (decl, 0); - - if (DECL_SIZE (decl) == 0 - && (TREE_STATIC (decl) - ? - /* A static variable with an incomplete type - is an error if it is initialized or `static'. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - !TREE_PUBLIC (decl) || DECL_INITIAL (decl) - : - /* An automatic variable with an incomplete type - is an error. */ - !DECL_EXTERNAL (decl))) - { - error_with_decl (decl, "storage size of `%s' isn't known"); - TREE_TYPE (decl) = error_mark_node; - } - - if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) - && DECL_SIZE (decl) != 0) - { - if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) - constant_expression_warning (DECL_SIZE (decl)); - else - error_with_decl (decl, "storage size of `%s' isn't constant"); - } - } - - /* Output the assembler code and/or RTL code for variables and functions, - unless the type is an undefined structure or union. - If not, it will get done when the type is completed. */ - - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL) - { - if (flag_traditional && allocation_temporary_p ()) - { - push_obstacks_nochange (); - end_temporary_allocation (); - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, asmspec, - current_binding_level == global_binding_level, - 0); - pop_obstacks (); - } - else - { - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, asmspec, - current_binding_level == global_binding_level, - 0); - } - if (current_binding_level != global_binding_level) - { - /* Recompute the RTL of a local array now - if it used to be an incomplete type. */ - if (was_incomplete - && ! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == 0) - DECL_INITIAL (decl) = 0; - expand_decl (decl); - } - /* Compute and store the initial value. */ - if (TREE_CODE (decl) != FUNCTION_DECL) - expand_decl_init (decl); - } - } - - if (TREE_CODE (decl) == TYPE_DECL) - { - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, - current_binding_level == global_binding_level, - 0); - } - - /* ??? After 2.3, test (init != 0) instead of TREE_CODE. */ - if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) - && temporary && TREE_PERMANENT (decl) - /* DECL_INITIAL is not defined in PARM_DECLs, since it shares - space with DECL_ARG_TYPE. */ - && TREE_CODE (decl) != PARM_DECL) - { - /* We need to remember that this array HAD an initialization, - but discard the actual temporary nodes, - since we can't have a permanent node keep pointing to them. */ - /* We make an exception for inline functions, since it's - normal for a local extern redeclaration of an inline function - to have a copy of the top-level decl's DECL_INLINE. */ - if (DECL_INITIAL (decl) != 0) - DECL_INITIAL (decl) = error_mark_node; - } - -#if 0 - /* Resume permanent allocation, if not within a function. */ - /* The corresponding push_obstacks_nochange is in start_decl, - and in push_parm_decl and in grokfield. */ - pop_obstacks (); -#endif - - /* If we have gone back from temporary to permanent allocation, - actually free the temporary space that we no longer need. */ - if (temporary && !allocation_temporary_p ()) - permanent_allocation (); - - /* At the end of a declaration, throw away any variable type sizes - of types defined inside that declaration. There is no use - computing them in the following function definition. */ - if (current_binding_level == global_binding_level) - get_pending_sizes (); -} - -/* If DECL has a cleanup, build and return that cleanup here. - This is a callback called by expand_expr. */ - -tree -maybe_build_cleanup (decl) - tree decl; -{ - /* There are no cleanups in C. */ - return NULL_TREE; -} - -/* Given a parsed parameter declaration, - decode it into a PARM_DECL and push that on the current binding level. - Also, for the sake of forward parm decls, - record the given order of parms in `parm_order'. */ - -void -push_parm_decl (parm) - tree parm; -{ - tree decl, olddecl; - int old_immediate_size_expand = immediate_size_expand; - /* Don't try computing parm sizes now -- wait till fn is called. */ - immediate_size_expand = 0; - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - decl = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), PARM, 0); - -#if 0 - if (DECL_NAME (decl)) - { - olddecl = lookup_name (DECL_NAME (decl)); - if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL) - pedwarn_with_decl (decl, "ANSI C forbids parameter `%s' shadowing typedef"); - } -#endif - - decl = pushdecl (decl); - - immediate_size_expand = old_immediate_size_expand; - - current_binding_level->parm_order - = tree_cons (NULL_TREE, decl, current_binding_level->parm_order); - - /* Add this decl to the current binding level. */ - finish_decl (decl, NULL_TREE, NULL_TREE); -} - -/* Clear the given order of parms in `parm_order'. - Used at start of parm list, - and also at semicolon terminating forward decls. */ - -void -clear_parm_order () -{ - current_binding_level->parm_order = NULL_TREE; -} - -/* Make TYPE a complete type based on INITIAL_VALUE. - Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ - -int -complete_array_type (type, initial_value, do_default) - tree type; - tree initial_value; - int do_default; -{ - register tree maxindex = NULL_TREE; - int value = 0; - - if (initial_value) - { - /* Note MAXINDEX is really the maximum index, - one less than the size. */ - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = build_int_2 (TREE_STRING_LENGTH (initial_value) / eltsize - 1, 0); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - register int nelts - = list_length (CONSTRUCTOR_ELTS (initial_value)); - maxindex = build_int_2 (nelts - 1, - (nelts == 0)); - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - - /* Prevent further error messages. */ - maxindex = build_int_2 (0, 0); - } - } - - if (!maxindex) - { - if (do_default) - maxindex = build_int_2 (0, 0); - value = 2; - } - - if (maxindex) - { - TYPE_DOMAIN (type) = build_index_type (maxindex); - if (!TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (type); -#if 0 /* I took out this change - together with the change in build_array_type. --rms */ - change_main_variant (type, - build_array_type (TREE_TYPE (type), - TYPE_DOMAIN (type))); -#endif - } - - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; -} - -/* Given declspecs and a declarator, - determine the name and type of the object declared - and construct a ..._DECL node for it. - (In one case we can return a ..._TYPE node instead. - For invalid input we sometimes return 0.) - - DECLSPECS is a chain of tree_list nodes whose value fields - are the storage classes and type specifiers. - - DECL_CONTEXT says which syntactic context this declaration is in: - NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL. - FUNCDEF for a function definition. Like NORMAL but a few different - error messages in each case. Return value may be zero meaning - this definition is too screwy to try to parse. - PARM for a parameter declaration (either within a function prototype - or before a function body). Make a PARM_DECL, or return void_type_node. - TYPENAME if for a typename (in a cast or sizeof). - Don't make a DECL node; just return the ..._TYPE node. - FIELD for a struct or union field; make a FIELD_DECL. - BITFIELD for a field with specified width. - INITIALIZED is 1 if the decl has an initializer. - - In the TYPENAME case, DECLARATOR is really an absolute declarator. - It may also be so in the PARM case, for a prototype where the - argument type is specified but not the name. - - This function is where the complicated C meanings of `static' - and `extern' are interpreted. */ - -static tree -grokdeclarator (declarator, declspecs, decl_context, initialized) - tree declspecs; - tree declarator; - enum decl_context decl_context; - int initialized; -{ - int specbits = 0; - tree spec; - tree type = NULL_TREE; - int longlong = 0; - int constp; - int volatilep; - int inlinep; - int explicit_int = 0; - int explicit_char = 0; - int defaulted_int = 0; - tree typedef_decl = 0; - char *name; - tree typedef_type = 0; - int funcdef_flag = 0; - enum tree_code innermost_code = ERROR_MARK; - int bitfield = 0; - int size_varies = 0; - - if (decl_context == BITFIELD) - bitfield = 1, decl_context = FIELD; - - if (decl_context == FUNCDEF) - funcdef_flag = 1, decl_context = NORMAL; - - push_obstacks_nochange (); - - if (flag_traditional && allocation_temporary_p ()) - end_temporary_allocation (); - - /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ - { - register tree decl = declarator; - name = 0; - - while (decl) - switch (TREE_CODE (decl)) - { - case ARRAY_REF: - case INDIRECT_REF: - case CALL_EXPR: - innermost_code = TREE_CODE (decl); - decl = TREE_OPERAND (decl, 0); - break; - - case IDENTIFIER_NODE: - name = IDENTIFIER_POINTER (decl); - decl = 0; - break; - - default: - abort (); - } - if (name == 0) - name = "type name"; - } - - /* A function definition's declarator must have the form of - a function declarator. */ - - if (funcdef_flag && innermost_code != CALL_EXPR) - return 0; - - /* Anything declared one level down from the top level - must be one of the parameters of a function - (because the body is at least two levels down). */ - - /* If this looks like a function definition, make it one, - even if it occurs where parms are expected. - Then store_parm_decls will reject it and not use it as a parm. */ - if (decl_context == NORMAL && !funcdef_flag - && current_binding_level->level_chain == global_binding_level) - decl_context = PARM; - - /* Look through the decl specs and record which ones appear. - Some typespecs are defined as built-in typenames. - Others, the ones that are modifiers of other types, - are represented by bits in SPECBITS: set the bits for - the modifiers that appear. Storage class keywords are also in SPECBITS. - - If there is a typedef name or a type, store the type in TYPE. - This includes builtin typedefs such as `int'. - - Set EXPLICIT_INT or EXPLICIT_CHAR if the type is `int' or `char' - and did not come from a user typedef. - - Set LONGLONG if `long' is mentioned twice. */ - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - register int i; - register tree id = TREE_VALUE (spec); - - if (id == ridpointers[(int) RID_INT]) - explicit_int = 1; - if (id == ridpointers[(int) RID_CHAR]) - explicit_char = 1; - - if (TREE_CODE (id) == IDENTIFIER_NODE) - for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++) - { - if (ridpointers[i] == id) - { - if (i == (int) RID_LONG && specbits & (1< 1) - pedwarn ("duplicate `const'"); - if (volatilep > 1) - pedwarn ("duplicate `volatile'"); - if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type))) - type = TYPE_MAIN_VARIANT (type); - - /* Warn if two storage classes are given. Default to `auto'. */ - - { - int nclasses = 0; - - if (specbits & 1 << (int) RID_AUTO) nclasses++; - if (specbits & 1 << (int) RID_STATIC) nclasses++; - if (specbits & 1 << (int) RID_EXTERN) nclasses++; - if (specbits & 1 << (int) RID_REGISTER) nclasses++; - if (specbits & 1 << (int) RID_TYPEDEF) nclasses++; - if (specbits & 1 << (int) RID_ITERATOR) nclasses++; - - /* Warn about storage classes that are invalid for certain - kinds of declarations (parameters, typenames, etc.). */ - - if (nclasses > 1) - error ("multiple storage classes in declaration of `%s'", name); - else if (funcdef_flag - && (specbits - & ((1 << (int) RID_REGISTER) - | (1 << (int) RID_AUTO) - | (1 << (int) RID_TYPEDEF)))) - { - if (specbits & 1 << (int) RID_AUTO - && (pedantic || current_binding_level == global_binding_level)) - pedwarn ("function definition declared `auto'"); - if (specbits & 1 << (int) RID_REGISTER) - error ("function definition declared `register'"); - if (specbits & 1 << (int) RID_TYPEDEF) - error ("function definition declared `typedef'"); - specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER) - | (1 << (int) RID_AUTO)); - } - else if (decl_context != NORMAL && nclasses > 0) - { - if (decl_context == PARM && specbits & 1 << (int) RID_REGISTER) - ; - else - { - error ((decl_context == FIELD - ? "storage class specified for structure field `%s'" - : (decl_context == PARM - ? "storage class specified for parameter `%s'" - : "storage class specified for typename")), - name); - specbits &= ~ ((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER) - | (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC) - | (1 << (int) RID_EXTERN)); - } - } - else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag) - { - /* `extern' with initialization is invalid if not at top level. */ - if (current_binding_level == global_binding_level) - warning ("`%s' initialized and declared `extern'", name); - else - error ("`%s' has both `extern' and initializer", name); - } - else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag - && current_binding_level != global_binding_level) - error ("nested function `%s' declared `extern'", name); - else if (current_binding_level == global_binding_level - && specbits & (1 << (int) RID_AUTO)) - error ("top-level declaration of `%s' specifies `auto'", name); - else if ((specbits & 1 << (int) RID_ITERATOR) - && TREE_CODE (declarator) != IDENTIFIER_NODE) - { - error ("iterator `%s' has derived type", name); - type = error_mark_node; - } - else if ((specbits & 1 << (int) RID_ITERATOR) - && TREE_CODE (type) != INTEGER_TYPE) - { - error ("iterator `%s' has noninteger type", name); - type = error_mark_node; - } - } - - /* Now figure out the structure of the declarator proper. - Descend through it, creating more complex types, until we reach - the declared identifier (or NULL_TREE, in an absolute declarator). */ - - while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE) - { - if (type == error_mark_node) - { - declarator = TREE_OPERAND (declarator, 0); - continue; - } - - /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), - an INDIRECT_REF (for *...), - a CALL_EXPR (for ...(...)), - an identifier (for the name being declared) - or a null pointer (for the place in an absolute declarator - where the name was omitted). - For the last two cases, we have just exited the loop. - - At this point, TYPE is the type of elements of an array, - or for a function to return, or for a pointer to point to. - After this sequence of ifs, TYPE is the type of the - array or function or pointer, and DECLARATOR has had its - outermost layer removed. */ - - if (TREE_CODE (declarator) == ARRAY_REF) - { - register tree itype = NULL_TREE; - register tree size = TREE_OPERAND (declarator, 1); - /* An uninitialized decl with `extern' is a reference. */ - int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN)); - - declarator = TREE_OPERAND (declarator, 0); - - /* Check for some types that there cannot be arrays of. */ - - if (TYPE_MAIN_VARIANT (type) == void_type_node) - { - error ("declaration of `%s' as array of voids", name); - type = error_mark_node; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("declaration of `%s' as array of functions", name); - type = error_mark_node; - } - - if (size == error_mark_node) - type = error_mark_node; - - if (type == error_mark_node) - continue; - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other extern - declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - /* If size was specified, set ITYPE to a range-type for that size. - Otherwise, ITYPE remains null. finish_decl may figure it out - from an initial value. */ - - if (size) - { - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (size); - - if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE) - { - error ("size of array `%s' has non-integer type", name); - size = integer_one_node; - } - if (pedantic && integer_zerop (size)) - pedwarn ("ANSI C forbids zero-size array `%s'", name); - if (TREE_CODE (size) == INTEGER_CST) - { - constant_expression_warning (size); - if (INT_CST_LT (size, integer_zero_node)) - { - error ("size of array `%s' is negative", name); - size = integer_one_node; - } - itype = build_index_type (size_binop (MINUS_EXPR, size, - size_one_node)); - } - else - { - if (pedantic) - { - if (TREE_CONSTANT (size)) - pedwarn ("ANSI C forbids array `%s' whose size can't be evaluated", name); - else - pedwarn ("ANSI C forbids variable-size array `%s'", name); - } - itype = build_binary_op (MINUS_EXPR, size, integer_one_node, - 1); - /* Make sure the array size remains visibly nonconstant - even if it is (eg) a const variable with known value. */ - size_varies = 1; - itype = variable_size (itype); - itype = build_index_type (itype); - } - } - -#if 0 /* This had bad results for pointers to arrays, as in - union incomplete (*foo)[4]; */ - /* Complain about arrays of incomplete types, except in typedefs. */ - - if (TYPE_SIZE (type) == 0 - /* Avoid multiple warnings for nested array types. */ - && TREE_CODE (type) != ARRAY_TYPE - && !(specbits & (1 << (int) RID_TYPEDEF)) - && !C_TYPE_BEING_DEFINED (type)) - warning ("array type has incomplete element type"); -#endif - -#if 0 /* We shouldn't have a function type here at all! - Functions aren't allowed as array elements. */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); -#endif - - /* Build the array type itself, then merge any constancy or - volatility into the target type. We must do it in this order - to ensure that the TYPE_MAIN_VARIANT field of the array type - is set correctly. */ - - type = build_array_type (type, itype); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - -#if 0 /* don't clear these; leave them set so that the array type - or the variable is itself const or volatile. */ - constp = 0; - volatilep = 0; -#endif - - if (size_varies) - C_TYPE_VARIABLE_SIZE (type) = 1; - } - else if (TREE_CODE (declarator) == CALL_EXPR) - { - int extern_ref = (!(specbits & (1 << (int) RID_AUTO)) - || current_binding_level == global_binding_level); - tree arg_types; - - /* Declaring a function type. - Make sure we have a valid type for the function to return. */ - if (type == error_mark_node) - continue; - - size_varies = 0; - - /* Warn about some types functions can't return. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("`%s' declared as function returning a function", name); - type = integer_type_node; - } - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("`%s' declared as function returning an array", name); - type = integer_type_node; - } - -#ifndef TRADITIONAL_RETURN_FLOAT - /* Traditionally, declaring return type float means double. */ - - if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node) - type = double_type_node; -#endif /* TRADITIONAL_RETURN_FLOAT */ - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other extern - declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - /* Construct the function type and go to the next - inner layer of declarator. */ - - arg_types = grokparms (TREE_OPERAND (declarator, 1), - funcdef_flag - /* Say it's a definition - only for the CALL_EXPR - closest to the identifier. */ - && TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE); -#if 0 /* This seems to be false. We turn off temporary allocation - above in this function if -traditional. - And this code caused inconsistent results with prototypes: - callers would ignore them, and pass arguments wrong. */ - - /* Omit the arg types if -traditional, since the arg types - and the list links might not be permanent. */ - type = build_function_type (type, - flag_traditional - ? NULL_TREE : arg_types); -#endif - type = build_function_type (type, arg_types); - declarator = TREE_OPERAND (declarator, 0); - - /* Set the TYPE_CONTEXTs for each tagged type which is local to - the formal parameter list of this FUNCTION_TYPE to point to - the FUNCTION_TYPE node itself. */ - - { - register tree link; - - for (link = current_function_parm_tags; - link; - link = TREE_CHAIN (link)) - TYPE_CONTEXT (TREE_VALUE (link)) = type; - } - } - else if (TREE_CODE (declarator) == INDIRECT_REF) - { - /* Merge any constancy or volatility into the target type - for the pointer. */ - - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - constp = 0; - volatilep = 0; - size_varies = 0; - - type = build_pointer_type (type); - - /* Process a list of type modifier keywords - (such as const or volatile) that were given inside the `*'. */ - - if (TREE_TYPE (declarator)) - { - register tree typemodlist; - int erred = 0; - for (typemodlist = TREE_TYPE (declarator); typemodlist; - typemodlist = TREE_CHAIN (typemodlist)) - { - if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST]) - constp++; - else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE]) - volatilep++; - else if (!erred) - { - erred = 1; - error ("invalid type modifier within pointer declarator"); - } - } - if (constp > 1) - pedwarn ("duplicate `const'"); - if (volatilep > 1) - pedwarn ("duplicate `volatile'"); - } - - declarator = TREE_OPERAND (declarator, 0); - } - else - abort (); - - } - - /* Now TYPE has the actual type. */ - - /* If this is declaring a typedef name, return a TYPE_DECL. */ - - if (specbits & (1 << (int) RID_TYPEDEF)) - { - tree decl; - /* Note that the grammar rejects storage classes - in typenames, fields or parameters */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - pop_obstacks (); - decl = build_decl (TYPE_DECL, declarator, type); - if ((specbits & (1 << (int) RID_SIGNED)) - || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) - C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - return decl; - } - - /* Detect the case of an array type of unspecified size - which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ - - if (type != 0 && typedef_type != 0 - && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type) - && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0) - { - type = build_array_type (TREE_TYPE (type), 0); - if (size_varies) - C_TYPE_VARIABLE_SIZE (type) = 1; - } - - /* If this is a type name (such as, in a cast or sizeof), - compute the type and return it now. */ - - if (decl_context == TYPENAME) - { - /* Note that the grammar rejects storage classes - in typenames, fields or parameters */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - pop_obstacks (); - return type; - } - - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM) - { - error ("variable or field `%s' declared void", - IDENTIFIER_POINTER (declarator)); - type = integer_type_node; - } - - /* Now create the decl, which may be a VAR_DECL, a PARM_DECL - or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ - - { - register tree decl; - - if (decl_context == PARM) - { - tree type_as_written = type; - tree main_type; - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type pointed to. */ - type = build_pointer_type - (c_build_type_variant (TREE_TYPE (type), constp, volatilep)); - volatilep = constp = 0; - size_varies = 0; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - if (pedantic && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - type = build_pointer_type (c_build_type_variant (type, constp, volatilep)); - volatilep = constp = 0; - } - - decl = build_decl (PARM_DECL, declarator, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - DECL_ARG_TYPE (decl) = type; - main_type = (type == error_mark_node - ? error_mark_node - : TYPE_MAIN_VARIANT (type)); - if (main_type == float_type_node) - DECL_ARG_TYPE (decl) = double_type_node; - /* Don't use TYPE_PRECISION to decide whether to promote, - because we should convert short if it's the same size as int, - but we should not convert long if it's the same size as int. */ - else if (TREE_CODE (main_type) != ERROR_MARK - && C_PROMOTING_INTEGER_TYPE_P (main_type)) - { - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node) - && TREE_UNSIGNED (type)) - DECL_ARG_TYPE (decl) = unsigned_type_node; - else - DECL_ARG_TYPE (decl) = integer_type_node; - } - - DECL_ARG_TYPE_AS_WRITTEN (decl) = type_as_written; - } - else if (decl_context == FIELD) - { - /* Structure field. It may not be a function. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("field `%s' declared as a function", - IDENTIFIER_POINTER (declarator)); - type = build_pointer_type (type); - } - else if (TREE_CODE (type) != ERROR_MARK && TYPE_SIZE (type) == 0) - { - error ("field `%s' has incomplete type", - IDENTIFIER_POINTER (declarator)); - type = error_mark_node; - } - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) - { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), - TYPE_DOMAIN (type)); -#if 0 /* Leave the field const or volatile as well. */ - constp = volatilep = 0; -#endif - } - decl = build_decl (FIELD_DECL, declarator, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - /* Every function declaration is "external" - except for those which are inside a function body - in which `auto' is used. - That is a case not specified by ANSI C, - and we use it for forward declarations for nested functions. */ - int extern_ref = (!(specbits & (1 << (int) RID_AUTO)) - || current_binding_level == global_binding_level); - - if (specbits & (1 << (int) RID_AUTO) - && (pedantic || current_binding_level == global_binding_level)) - pedwarn ("invalid storage class for function `%s'", - IDENTIFIER_POINTER (declarator)); - if (specbits & (1 << (int) RID_REGISTER)) - error ("invalid storage class for function `%s'", - IDENTIFIER_POINTER (declarator)); - /* Function declaration not at top level. - Storage classes other than `extern' are not allowed - and `extern' makes no difference. */ - if (current_binding_level != global_binding_level - && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE))) - && pedantic) - pedwarn ("invalid storage class for function `%s'", - IDENTIFIER_POINTER (declarator)); - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other - extern declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - decl = build_decl (FUNCTION_DECL, declarator, type); - - if (pedantic && (constp || volatilep) - && ! DECL_IN_SYSTEM_HEADER (decl)) - pedwarn ("ANSI C forbids const or volatile functions"); - - if (extern_ref) - DECL_EXTERNAL (decl) = 1; - /* Record absence of global scope for `static' or `auto'. */ - TREE_PUBLIC (decl) - = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); - /* Record presence of `inline', if it is reasonable. */ - if (inlinep) - { - tree last = tree_last (TYPE_ARG_TYPES (type)); - - if (! strcmp (IDENTIFIER_POINTER (declarator), "main")) - warning ("cannot inline function `main'"); - else if (last && (TYPE_MAIN_VARIANT (TREE_VALUE (last)) - != void_type_node)) - warning ("inline declaration ignored for function with `...'"); - else - /* Assume that otherwise the function can be inlined. */ - DECL_INLINE (decl) = 1; - - if (specbits & (1 << (int) RID_EXTERN)) - current_extern_inline = 1; - } - } - else - { - /* It's a variable. */ - /* An uninitialized decl with `extern' is a reference. */ - int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN)); - - /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) - { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), - TYPE_DOMAIN (type)); -#if 0 /* Leave the variable const or volatile as well. */ - constp = volatilep = 0; -#endif - } - - /* If this is a block level extern, it must live past the end - of the function so that we can check it against other - extern declarations (IDENTIFIER_LIMBO_VALUE). */ - if (extern_ref && allocation_temporary_p ()) - end_temporary_allocation (); - - decl = build_decl (VAR_DECL, declarator, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - - if (inlinep) - pedwarn_with_decl (decl, "variable `%s' declared `inline'"); - - DECL_EXTERNAL (decl) = extern_ref; - /* At top level, the presence of a `static' or `register' storage - class specifier, or the absence of all storage class specifiers - makes this declaration a definition (perhaps tentative). Also, - the absence of both `static' and `register' makes it public. */ - if (current_binding_level == global_binding_level) - { - TREE_PUBLIC (decl) - = !(specbits - & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER))); - TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); - } - /* Not at top level, only `static' makes a static definition. */ - else - { - TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0; - TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); - } - - if (specbits & 1 << (int) RID_ITERATOR) - ITERATOR_P (decl) = 1; - } - - /* Record `register' declaration for warnings on & - and in case doing stupid register allocation. */ - - if (specbits & (1 << (int) RID_REGISTER)) - DECL_REGISTER (decl) = 1; - - /* Record constancy and volatility. */ - - if (constp) - TREE_READONLY (decl) = 1; - if (volatilep) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } - /* If a type has volatile components, it should be stored in memory. - Otherwise, the fact that those components are volatile - will be ignored, and would even crash the compiler. */ - if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))) - mark_addressable (decl); - - pop_obstacks (); - - return decl; - } -} - -/* Decode the parameter-list info for a function type or function definition. - The argument is the value returned by `get_parm_info' (or made in parse.y - if there is an identifier list instead of a parameter decl list). - These two functions are separate because when a function returns - or receives functions then each is called multiple times but the order - of calls is different. The last call to `grokparms' is always the one - that contains the formal parameter names of a function definition. - - Store in `last_function_parms' a chain of the decls of parms. - Also store in `last_function_parm_tags' a chain of the struct, union, - and enum tags declared among the parms. - - Return a list of arg types to use in the FUNCTION_TYPE for this function. - - FUNCDEF_FLAG is nonzero for a function definition, 0 for - a mere declaration. A nonempty identifier-list gets an error message - when FUNCDEF_FLAG is zero. */ - -static tree -grokparms (parms_info, funcdef_flag) - tree parms_info; - int funcdef_flag; -{ - tree first_parm = TREE_CHAIN (parms_info); - - last_function_parms = TREE_PURPOSE (parms_info); - last_function_parm_tags = TREE_VALUE (parms_info); - - if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag - && !in_system_header) - warning ("function declaration isn't a prototype"); - - if (first_parm != 0 - && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE) - { - if (! funcdef_flag) - pedwarn ("parameter names (without types) in function declaration"); - - last_function_parms = first_parm; - return 0; - } - else - { - tree parm; - tree typelt; - /* We no longer test FUNCDEF_FLAG. - If the arg types are incomplete in a declaration, - they must include undefined tags. - These tags can never be defined in the scope of the declaration, - so the types can never be completed, - and no call can be compiled successfully. */ -#if 0 - /* In a fcn definition, arg types must be complete. */ - if (funcdef_flag) -#endif - for (parm = last_function_parms, typelt = first_parm; - parm; - parm = TREE_CHAIN (parm)) - /* Skip over any enumeration constants declared here. */ - if (TREE_CODE (parm) == PARM_DECL) - { - /* Barf if the parameter itself has an incomplete type. */ - tree type = TREE_VALUE (typelt); - if (TYPE_SIZE (type) == 0) - { - if (funcdef_flag && DECL_NAME (parm) != 0) - error ("parameter `%s' has incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parm))); - else - warning ("parameter has incomplete type"); - if (funcdef_flag) - { - TREE_VALUE (typelt) = error_mark_node; - TREE_TYPE (parm) = error_mark_node; - } - } -#if 0 /* This has been replaced by parm_tags_warning - which uses a more accurate criterion for what to warn about. */ - else - { - /* Now warn if is a pointer to an incomplete type. */ - while (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - type = TYPE_MAIN_VARIANT (type); - if (TYPE_SIZE (type) == 0) - { - if (DECL_NAME (parm) != 0) - warning ("parameter `%s' points to incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parm))); - else - warning ("parameter points to incomplete type"); - } - } -#endif - typelt = TREE_CHAIN (typelt); - } - - /* Allocate the list of types the way we allocate a type. */ - if (first_parm && ! TREE_PERMANENT (first_parm)) - { - /* Construct a copy of the list of types - on the saveable obstack. */ - tree result = NULL; - for (typelt = first_parm; typelt; typelt = TREE_CHAIN (typelt)) - result = saveable_tree_cons (NULL_TREE, TREE_VALUE (typelt), - result); - return nreverse (result); - } - else - /* The list we have is permanent already. */ - return first_parm; - } -} - - -/* Return a tree_list node with info on a parameter list just parsed. - The TREE_PURPOSE is a chain of decls of those parms. - The TREE_VALUE is a list of structure, union and enum tags defined. - The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE. - This tree_list node is later fed to `grokparms'. - - VOID_AT_END nonzero means append `void' to the end of the type-list. - Zero means the parmlist ended with an ellipsis so don't append `void'. */ - -tree -get_parm_info (void_at_end) - int void_at_end; -{ - register tree decl, t; - register tree types = 0; - int erred = 0; - tree tags = gettags (); - tree parms = getdecls (); - tree new_parms = 0; - tree order = current_binding_level->parm_order; - - /* Just `void' (and no ellipsis) is special. There are really no parms. */ - if (void_at_end && parms != 0 - && TREE_CHAIN (parms) == 0 - && TYPE_MAIN_VARIANT (TREE_TYPE (parms)) == void_type_node - && DECL_NAME (parms) == 0) - { - parms = NULL_TREE; - storedecls (NULL_TREE); - return saveable_tree_cons (NULL_TREE, NULL_TREE, - saveable_tree_cons (NULL_TREE, void_type_node, NULL_TREE)); - } - - /* Extract enumerator values and other non-parms declared with the parms. - Likewise any forward parm decls that didn't have real parm decls. */ - for (decl = parms; decl; ) - { - tree next = TREE_CHAIN (decl); - - if (TREE_CODE (decl) != PARM_DECL) - { - TREE_CHAIN (decl) = new_parms; - new_parms = decl; - } - else if (TREE_ASM_WRITTEN (decl)) - { - error_with_decl (decl, "parameter `%s' has just a forward declaration"); - TREE_CHAIN (decl) = new_parms; - new_parms = decl; - } - decl = next; - } - - /* Put the parm decls back in the order they were in in the parm list. */ - for (t = order; t; t = TREE_CHAIN (t)) - { - if (TREE_CHAIN (t)) - TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (TREE_CHAIN (t)); - else - TREE_CHAIN (TREE_VALUE (t)) = 0; - } - - new_parms = chainon (order ? nreverse (TREE_VALUE (order)) : 0, - new_parms); - - /* Store the parmlist in the binding level since the old one - is no longer a valid list. (We have changed the chain pointers.) */ - storedecls (new_parms); - - for (decl = new_parms; decl; decl = TREE_CHAIN (decl)) - /* There may also be declarations for enumerators if an enumeration - type is declared among the parms. Ignore them here. */ - if (TREE_CODE (decl) == PARM_DECL) - { - /* Since there is a prototype, - args are passed in their declared types. */ - tree type = TREE_TYPE (decl); - DECL_ARG_TYPE (decl) = type; -#ifdef PROMOTE_PROTOTYPES - if (TREE_CODE (type) == INTEGER_TYPE - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (decl) = integer_type_node; -#endif - - types = saveable_tree_cons (NULL_TREE, TREE_TYPE (decl), types); - if (TYPE_MAIN_VARIANT (TREE_VALUE (types)) == void_type_node && ! erred - && DECL_NAME (decl) == 0) - { - error ("`void' in parameter list must be the entire list"); - erred = 1; - } - } - - if (void_at_end) - return saveable_tree_cons (new_parms, tags, - nreverse (saveable_tree_cons (NULL_TREE, void_type_node, types))); - - return saveable_tree_cons (new_parms, tags, nreverse (types)); -} - -/* At end of parameter list, warn about any struct, union or enum tags - defined within. Do so because these types cannot ever become complete. */ - -void -parmlist_tags_warning () -{ - tree elt; - static int already; - - for (elt = current_binding_level->tags; elt; elt = TREE_CHAIN (elt)) - { - enum tree_code code = TREE_CODE (TREE_VALUE (elt)); - /* An anonymous union parm type is meaningful as a GNU extension. - So don't warn for that. */ - if (code == UNION_TYPE && !pedantic) - continue; - if (TREE_PURPOSE (elt) != 0) - warning ("`%s %s' declared inside parameter list", - (code == RECORD_TYPE ? "struct" - : code == UNION_TYPE ? "union" - : "enum"), - IDENTIFIER_POINTER (TREE_PURPOSE (elt))); - else - warning ("anonymous %s declared inside parameter list", - (code == RECORD_TYPE ? "struct" - : code == UNION_TYPE ? "union" - : "enum")); - - if (! already) - { - warning ("its scope is only this definition or declaration,"); - warning ("which is probably not what you want."); - already = 1; - } - } -} - -/* Get the struct, enum or union (CODE says which) with tag NAME. - Define the tag as a forward-reference if it is not defined. */ - -tree -xref_tag (code, name) - enum tree_code code; - tree name; -{ - int temporary = allocation_temporary_p (); - - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - - register tree ref = lookup_tag (code, name, current_binding_level, 0); - /* Even if this is the wrong type of tag, return what we found. - There will be an error message anyway, from pending_xref_error. - If we create an empty xref just for an invalid use of the type, - the main result is to create lots of superfluous error messages. */ - if (ref) - return ref; - - push_obstacks_nochange (); - - if (current_binding_level == global_binding_level && temporary) - end_temporary_allocation (); - - /* If no such tag is yet defined, create a forward-reference node - and record it as the "definition". - When a real declaration of this type is found, - the forward-reference will be altered into a real type. */ - - ref = make_node (code); - if (code == ENUMERAL_TYPE) - { - /* (In ANSI, Enums can be referred to only if already defined.) */ - if (pedantic) - pedwarn ("ANSI C forbids forward references to `enum' types"); - /* Give the type a default layout like unsigned int - to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); - TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); - TREE_UNSIGNED (ref) = 1; - TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); - TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); - TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); - } - - pushtag (name, ref); - - pop_obstacks (); - - return ref; -} - -/* Make sure that the tag NAME is defined *in the current binding level* - at least as a forward reference. - CODE says which kind of tag NAME ought to be. - - We also do a push_obstacks_nochange - whose matching pop is in finish_struct. */ - -tree -start_struct (code, name) - enum tree_code code; - tree name; -{ - /* If there is already a tag defined at this binding level - (as a forward reference), just return it. */ - - register tree ref = 0; - - push_obstacks_nochange (); - if (current_binding_level == global_binding_level) - end_temporary_allocation (); - - if (name != 0) - ref = lookup_tag (code, name, current_binding_level, 1); - if (ref && TREE_CODE (ref) == code) - { - C_TYPE_BEING_DEFINED (ref) = 1; - if (TYPE_FIELDS (ref)) - error ((code == UNION_TYPE ? "redefinition of `union %s'" - : "redefinition of `struct %s'"), - IDENTIFIER_POINTER (name)); - - return ref; - } - - /* Otherwise create a forward-reference just so the tag is in scope. */ - - ref = make_node (code); - pushtag (name, ref); - C_TYPE_BEING_DEFINED (ref) = 1; - return ref; -} - -/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) - of a structure component, returning a FIELD_DECL node. - WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. - - This is done during the parsing of the struct declaration. - The FIELD_DECL nodes are chained together and the lot of them - are ultimately passed to `build_struct' to make the RECORD_TYPE node. */ - -tree -grokfield (filename, line, declarator, declspecs, width) - char *filename; - int line; - tree declarator, declspecs, width; -{ - tree value; - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0); - - finish_decl (value, NULL_TREE, NULL_TREE); - DECL_INITIAL (value) = width; - - maybe_objc_check_decl (value); - return value; -} - -/* Function to help qsort sort FIELD_DECLs by name order. */ - -static int -field_decl_cmp (x, y) - tree *x, *y; -{ - return (long)DECL_NAME (*x) - (long)DECL_NAME (*y); -} - -/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. - FIELDLIST is a chain of FIELD_DECL nodes for the fields. - - We also do a pop_obstacks to match the push in start_struct. */ - -tree -finish_struct (t, fieldlist) - register tree t, fieldlist; -{ - register tree x; - int old_momentary; - int toplevel = global_binding_level == current_binding_level; - - /* If this type was previously laid out as a forward reference, - make sure we lay it out again. */ - - TYPE_SIZE (t) = 0; - - /* Nameless union parm types are useful as GCC extension. */ - if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic) - /* Otherwise, warn about any struct or union def. in parmlist. */ - if (in_parm_level_p ()) - { - if (pedantic) - pedwarn ((TREE_CODE (t) == UNION_TYPE ? "union defined inside parms" - : "structure defined inside parms")); - else if (! flag_traditional) - warning ((TREE_CODE (t) == UNION_TYPE ? "union defined inside parms" - : "structure defined inside parms")); - } - - old_momentary = suspend_momentary (); - - if (fieldlist == 0 && pedantic) - pedwarn ((TREE_CODE (t) == UNION_TYPE ? "union has no members" - : "structure has no members")); - - /* Install struct as DECL_CONTEXT of each field decl. - Also process specified field sizes. - Set DECL_FIELD_SIZE to the specified size, or 0 if none specified. - The specified size is found in the DECL_INITIAL. - Store 0 there, except for ": 0" fields (so we can find them - and delete them, below). */ - - for (x = fieldlist; x; x = TREE_CHAIN (x)) - { - DECL_CONTEXT (x) = t; - DECL_FIELD_SIZE (x) = 0; - - /* If any field is const, the structure type is pseudo-const. */ - if (TREE_READONLY (x)) - C_TYPE_FIELDS_READONLY (t) = 1; - else - { - /* A field that is pseudo-const makes the structure likewise. */ - tree t1 = TREE_TYPE (x); - while (TREE_CODE (t1) == ARRAY_TYPE) - t1 = TREE_TYPE (t1); - if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (t1)) - C_TYPE_FIELDS_READONLY (t) = 1; - } - - /* Any field that is volatile means variables of this type must be - treated in some ways as volatile. */ - if (TREE_THIS_VOLATILE (x)) - C_TYPE_FIELDS_VOLATILE (t) = 1; - - /* Any field of nominal variable size implies structure is too. */ - if (C_DECL_VARIABLE_SIZE (x)) - C_TYPE_VARIABLE_SIZE (t) = 1; - - /* Detect invalid nested redefinition. */ - if (TREE_TYPE (x) == t) - error ("nested redefinition of `%s'", - IDENTIFIER_POINTER (TYPE_NAME (t))); - - /* Detect invalid bit-field size. */ - if (DECL_INITIAL (x)) - STRIP_NOPS (DECL_INITIAL (x)); - if (DECL_INITIAL (x)) - { - if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST) - constant_expression_warning (DECL_INITIAL (x)); - else - { - error_with_decl (x, "bit-field `%s' width not an integer constant"); - DECL_INITIAL (x) = NULL; - } - } - - /* Detect invalid bit-field type. */ - if (DECL_INITIAL (x) - && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) - { - error_with_decl (x, "bit-field `%s' has invalid type"); - DECL_INITIAL (x) = NULL; - } - if (DECL_INITIAL (x) && pedantic - && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node - && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node) - pedwarn_with_decl (x, "bit-field `%s' type invalid in ANSI C"); - - /* Detect and ignore out of range field width. */ - if (DECL_INITIAL (x)) - { - unsigned HOST_WIDE_INT width = TREE_INT_CST_LOW (DECL_INITIAL (x)); - - if (tree_int_cst_lt (DECL_INITIAL (x), integer_zero_node)) - { - DECL_INITIAL (x) = NULL; - error_with_decl (x, "negative width in bit-field `%s'"); - } - else if (TREE_INT_CST_HIGH (DECL_INITIAL (x)) != 0 - || width > TYPE_PRECISION (TREE_TYPE (x))) - { - DECL_INITIAL (x) = NULL; - pedwarn_with_decl (x, "width of `%s' exceeds its type"); - } - else if (width == 0 && DECL_NAME (x) != 0) - { - error_with_decl (x, "zero width for bit-field `%s'"); - DECL_INITIAL (x) = NULL; - } - } - - /* Process valid field width. */ - if (DECL_INITIAL (x)) - { - register int width = TREE_INT_CST_LOW (DECL_INITIAL (x)); - - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; - DECL_INITIAL (x) = NULL; - - if (width == 0) - { - /* field size 0 => force desired amount of alignment. */ -#ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); -#endif -#ifdef PCC_BITFIELD_TYPE_MATTERS - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); -#endif - } - } - else - { - int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT - : TYPE_ALIGN (TREE_TYPE (x))); - /* Non-bit-fields are aligned for their type, except packed - fields which require only BITS_PER_UNIT alignment. */ - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align); - } - } - - /* Now DECL_INITIAL is null on all members. */ - - /* Delete all duplicate fields from the fieldlist */ - for (x = fieldlist; x && TREE_CHAIN (x);) - /* Anonymous fields aren't duplicates. */ - if (DECL_NAME (TREE_CHAIN (x)) == 0) - x = TREE_CHAIN (x); - else - { - register tree y = fieldlist; - - while (1) - { - if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x))) - break; - if (y == x) - break; - y = TREE_CHAIN (y); - } - if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x))) - { - error_with_decl (TREE_CHAIN (x), "duplicate member `%s'"); - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - } - else x = TREE_CHAIN (x); - } - - /* Now we have the nearly final fieldlist. Record it, - then lay out the structure or union (including the fields). */ - - TYPE_FIELDS (t) = fieldlist; - - layout_type (t); - - /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fieldlist - && DECL_INITIAL (fieldlist)) - fieldlist = TREE_CHAIN (fieldlist); - /* Delete all such members from the rest of the fieldlist */ - for (x = fieldlist; x;) - { - if (TREE_CHAIN (x) && DECL_INITIAL (TREE_CHAIN (x))) - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - else x = TREE_CHAIN (x); - } - - /* Now we have the truly final field list. - Store it in this type and in the variants. */ - - TYPE_FIELDS (t) = fieldlist; - - /* If there are lots of fields, sort so we can look through them fast. - We arbitrarily consider 16 or more elts to be "a lot". */ - { - int len = 0; - - for (x = fieldlist; x; x = TREE_CHAIN (x)) - { - if (len > 15) - break; - len += 1; - } - if (len > 15) - { - tree *field_array; - char *space; - - len += list_length (x); - /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ - if (allocation_temporary_p ()) - space = savealloc (sizeof (struct lang_type) + len * sizeof (tree)); - else - space = oballoc (sizeof (struct lang_type) + len * sizeof (tree)); - - TYPE_LANG_SPECIFIC (t) = (struct lang_type *) space; - TYPE_LANG_SPECIFIC (t)->len = len; - - field_array = &TYPE_LANG_SPECIFIC (t)->elts[0]; - len = 0; - for (x = fieldlist; x; x = TREE_CHAIN (x)) - field_array[len++] = x; - - qsort (field_array, len, sizeof (tree), field_decl_cmp); - } - } - - for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) - { - TYPE_FIELDS (x) = TYPE_FIELDS (t); - TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); - TYPE_ALIGN (x) = TYPE_ALIGN (t); - } - - /* Promote each bit-field's type to int if it is narrower than that. */ - for (x = fieldlist; x; x = TREE_CHAIN (x)) - if (DECL_BIT_FIELD (x) - && (C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x)) - || DECL_FIELD_SIZE (x) < TYPE_PRECISION (integer_type_node))) - { - tree type = TREE_TYPE (x); - - /* Preserve unsignedness if traditional - or if not really getting any wider. */ - if (TREE_UNSIGNED (type) - && (flag_traditional - || - (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node) - && - DECL_FIELD_SIZE (x) == TYPE_PRECISION (integer_type_node)))) - TREE_TYPE (x) = unsigned_type_node; - else - TREE_TYPE (x) = integer_type_node; - } - - /* If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ - - if (current_binding_level->n_incomplete != 0) - { - tree decl; - for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl)) - { - if (TREE_TYPE (decl) == t - && TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - /* This is a no-op in c-lang.c or something real in objc-actions.c. */ - maybe_objc_check_decl (decl); - rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); - if (! toplevel) - expand_decl (decl); - --current_binding_level->n_incomplete; - } - else if (TYPE_SIZE (TREE_TYPE (decl)) == 0 - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - tree element = TREE_TYPE (decl); - while (TREE_CODE (element) == ARRAY_TYPE) - element = TREE_TYPE (element); - if (element == t) - layout_array_type (TREE_TYPE (decl)); - } - } - } - - resume_momentary (old_momentary); - - /* Finish debugging output for this type. */ - rest_of_type_compilation (t, toplevel); - - /* The matching push is in start_struct. */ - pop_obstacks (); - - return t; -} - -/* Lay out the type T, and its element type, and so on. */ - -static void -layout_array_type (t) - tree t; -{ - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) - layout_array_type (TREE_TYPE (t)); - layout_type (t); -} - -/* Begin compiling the definition of an enumeration type. - NAME is its name (or null if anonymous). - Returns the type object, as yet incomplete. - Also records info about it so that build_enumerator - may be used to declare the individual values as they are read. */ - -tree -start_enum (name) - tree name; -{ - register tree enumtype = 0; - - /* If this is the real definition for a previous forward reference, - fill in the contents in the same object that used to be the - forward reference. */ - - if (name != 0) - enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1); - - /* The corresponding pop_obstacks is in finish_enum. */ - push_obstacks_nochange (); - /* If these symbols and types are global, make them permanent. */ - if (current_binding_level == global_binding_level) - end_temporary_allocation (); - - if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE) - { - enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype); - } - - C_TYPE_BEING_DEFINED (enumtype) = 1; - - if (TYPE_VALUES (enumtype) != 0) - { - /* This enum is a named one that has been declared already. */ - error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name)); - - /* Completely replace its old definition. - The old enumerators remain defined, however. */ - TYPE_VALUES (enumtype) = 0; - } - - enum_next_value = integer_zero_node; - enum_overflow = 0; - - return enumtype; -} - -/* After processing and defining all the values of an enumeration type, - install their decls in the enumeration type and finish it off. - ENUMTYPE is the type object and VALUES a list of decl-value pairs. - Returns ENUMTYPE. */ - -tree -finish_enum (enumtype, values) - register tree enumtype, values; -{ - register tree pair, tem; - tree minnode = 0, maxnode = 0; - register HOST_WIDE_INT maxvalue = 0; - register HOST_WIDE_INT minvalue = 0; - register int i; - unsigned precision = 0; - int toplevel = global_binding_level == current_binding_level; - int temporary = allocation_temporary_p (); - - if (in_parm_level_p ()) - warning ("enum defined inside parms"); - - /* Calculate the maximum value of any enumerator in this type. */ - - for (pair = values; pair; pair = TREE_CHAIN (pair)) - { - tree value = TREE_VALUE (pair); - if (pair == values) - minnode = maxnode = TREE_VALUE (pair); - else - { - if (tree_int_cst_lt (maxnode, value)) - maxnode = value; - if (tree_int_cst_lt (value, minnode)) - minnode = value; - } - } - - TYPE_MIN_VALUE (enumtype) = minnode; - TYPE_MAX_VALUE (enumtype) = maxnode; - - /* Determine the precision this type needs. */ - - if (TREE_INT_CST_HIGH (minnode) >= 0 - ? tree_int_cst_lt (TYPE_MAX_VALUE (unsigned_type_node), maxnode) - : (tree_int_cst_lt (minnode, TYPE_MIN_VALUE (integer_type_node)) - || tree_int_cst_lt (TYPE_MAX_VALUE (integer_type_node), maxnode))) - precision = TYPE_PRECISION (long_long_integer_type_node); - else - { - maxvalue = TREE_INT_CST_LOW (maxnode); - minvalue = TREE_INT_CST_LOW (minnode); - - if (maxvalue > 0) - precision = floor_log2 (maxvalue) + 1; - if (minvalue < 0) - { - /* Compute number of bits to represent magnitude of a negative value. - Add one to MINVALUE since range of negative numbers - includes the power of two. */ - unsigned negprecision = floor_log2 (-minvalue - 1) + 1; - if (negprecision > precision) - precision = negprecision; - precision += 1; /* room for sign bit */ - } - - if (!precision) - precision = 1; - } - - if (flag_short_enums || precision > TYPE_PRECISION (integer_type_node)) - /* Use the width of the narrowest normal C type which is wide enough. */ - TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size (precision, 1)); - else - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - - TYPE_SIZE (enumtype) = 0; - layout_type (enumtype); - - /* An enum can have some negative values; then it is signed. */ - TREE_UNSIGNED (enumtype) = ! tree_int_cst_lt (minnode, integer_zero_node); - - /* If the enumerators might not fit in an int, change their type now. */ - /* It seems more useful in the debugger to leave these as int - unless the enumerator is wider than int. */ - if (TYPE_PRECISION (enumtype) <= TYPE_PRECISION (integer_type_node)) - for (pair = values; pair; pair = TREE_CHAIN (pair)) - { - TREE_TYPE (TREE_PURPOSE (pair)) = enumtype; - DECL_SIZE (TREE_PURPOSE (pair)) = TYPE_SIZE (enumtype); - if (TREE_CODE (TREE_PURPOSE (pair)) != FUNCTION_DECL) - DECL_ALIGN (TREE_PURPOSE (pair)) = TYPE_ALIGN (enumtype); - } - - /* Replace the decl nodes in VALUES with their names. */ - for (pair = values; pair; pair = TREE_CHAIN (pair)) - TREE_PURPOSE (pair) = DECL_NAME (TREE_PURPOSE (pair)); - - TYPE_VALUES (enumtype) = values; - - /* Fix up all variant types of this enum type. */ - for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) - { - TYPE_VALUES (tem) = TYPE_VALUES (enumtype); - TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); - TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); - TYPE_SIZE (tem) = TYPE_SIZE (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); - TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); - TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); - TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); - } - - /* Finish debugging output for this type. */ - rest_of_type_compilation (enumtype, toplevel); - - /* This matches a push in start_enum. */ - pop_obstacks (); - - return enumtype; -} - -/* Build and install a CONST_DECL for one value of the - current enumeration type (one that was begun with start_enum). - Return a tree-list containing the CONST_DECL and its value. - Assignment of sequential values by default is handled here. */ - -tree -build_enumerator (name, value) - tree name, value; -{ - register tree decl; - - /* Validate and default VALUE. */ - - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); - - if (value != 0) - { - if (TREE_CODE (value) == INTEGER_CST) - constant_expression_warning (value); - else - { - error ("enumerator value for `%s' not integer constant", - IDENTIFIER_POINTER (name)); - value = 0; - } - } - - /* Default based on previous value. */ - /* It should no longer be possible to have NON_LVALUE_EXPR - in the default. */ - if (value == 0) - { - value = enum_next_value; - if (enum_overflow) - error ("overflow in enumeration values"); - } - - if (pedantic && ! int_fits_type_p (value, integer_type_node)) - { - pedwarn ("ANSI C restricts enumerator values to range of `int'"); - value = integer_zero_node; - } - - /* Set basis for default for next value. */ - enum_next_value = build_binary_op (PLUS_EXPR, value, integer_one_node, 0); - enum_overflow = tree_int_cst_lt (enum_next_value, value); - - /* Now create a declaration for the enum value name. */ - - decl = build_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - TREE_TYPE (value) = integer_type_node; - pushdecl (decl); - - return saveable_tree_cons (decl, value, NULL_TREE); -} - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. - - NESTED is nonzero for a function nested within another function. */ - -int -start_function (declspecs, declarator, nested) - tree declarator, declspecs; - int nested; -{ - tree decl1, old_decl; - tree restype; - - current_function_returns_value = 0; /* Assume, until we see it does. */ - current_function_returns_null = 0; - warn_about_return_type = 0; - current_extern_inline = 0; - c_function_varargs = 0; - named_labels = 0; - shadowed_labels = 0; - - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1); - - /* If the declarator is not suitable for a function definition, - cause a syntax error. */ - if (decl1 == 0) - return 0; - - announce_function (decl1); - - if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl1))) == 0) - { - error ("return-type is an incomplete type"); - /* Make it return void instead. */ - TREE_TYPE (decl1) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl1))); - } - - if (warn_about_return_type) - warning ("return-type defaults to `int'"); - - /* Save the parm names or decls from this function's declarator - where store_parm_decls will find them. */ - current_function_parms = last_function_parms; - current_function_parm_tags = last_function_parm_tags; - - /* Make the init_value nonzero so pushdecl knows this is not tentative. - error_mark_node is replaced below (in poplevel) with the BLOCK. */ - DECL_INITIAL (decl1) = error_mark_node; - - /* If this definition isn't a prototype and we had a prototype declaration - before, copy the arg type info from that prototype. - But not if what we had before was a builtin function. */ - old_decl = lookup_name_current_level (DECL_NAME (decl1)); - if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE - && !DECL_BUILT_IN (old_decl) - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1))) - == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl)))) - && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0) - { - TREE_TYPE (decl1) = TREE_TYPE (old_decl); - current_function_prototype_file = DECL_SOURCE_FILE (old_decl); - current_function_prototype_line = DECL_SOURCE_LINE (old_decl); - } - - /* Optionally warn of old-fashioned def with no previous prototype. */ - if (warn_strict_prototypes - && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0 - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)) - warning ("function declaration isn't a prototype"); - /* Optionally warn of any global def with no previous prototype. */ - else if (warn_missing_prototypes - && TREE_PUBLIC (decl1) - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0) - && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1)))) - warning_with_decl (decl1, "no previous prototype for `%s'"); - /* Optionally warn of any def with no previous prototype - if the function has already been used. */ - else if (warn_missing_prototypes - && old_decl != 0 && TREE_USED (old_decl) - && !(old_decl != 0 && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0)) - warning_with_decl (decl1, "`%s' was used with no prototype before its definition"); - - /* This is a definition, not a reference. - So normally clear DECL_EXTERNAL. - However, `extern inline' acts like a declaration - except for defining how to inline. So set DECL_EXTERNAL in that case. */ - DECL_EXTERNAL (decl1) = current_extern_inline; - - /* This function exists in static storage. - (This does not mean `static' in the C sense!) */ - TREE_STATIC (decl1) = 1; - - /* A nested function is not global. */ - if (current_function_decl != 0) - TREE_PUBLIC (decl1) = 0; - - /* Record the decl so that the function name is defined. - If we already have a decl for this name, and it is a FUNCTION_DECL, - use the old decl. */ - - current_function_decl = pushdecl (decl1); - - pushlevel (0); - declare_parm_level (1); - current_binding_level->subblocks_tag_transparent = 1; - - make_function_rtl (current_function_decl); - - restype = TREE_TYPE (TREE_TYPE (current_function_decl)); - /* Promote the value to int before returning it. */ - if (C_PROMOTING_INTEGER_TYPE_P (restype)) - { - /* It retains unsignedness if traditional - or if not really getting wider. */ - if (TREE_UNSIGNED (restype) - && (flag_traditional - || (TYPE_PRECISION (restype) - == TYPE_PRECISION (integer_type_node)))) - restype = unsigned_type_node; - else - restype = integer_type_node; - } - DECL_RESULT (current_function_decl) - = build_decl (RESULT_DECL, NULL_TREE, restype); - - if (!nested) - /* Allocate further tree nodes temporarily during compilation - of this function only. */ - temporary_allocation (); - - /* If this fcn was already referenced via a block-scope `extern' decl - (or an implicit decl), propagate certain information about the usage. */ - if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl))) - TREE_ADDRESSABLE (current_function_decl) = 1; - - return 1; -} - -/* Record that this function is going to be a varargs function. - This is called before store_parm_decls, which is too early - to call mark_varargs directly. */ - -void -c_mark_varargs () -{ - c_function_varargs = 1; -} - -/* Store the parameter declarations into the current function declaration. - This is called after parsing the parameter declarations, before - digesting the body of the function. - - For an old-style definition, modify the function's type - to specify at least the number of arguments. */ - -void -store_parm_decls () -{ - register tree fndecl = current_function_decl; - register tree parm; - - /* This is either a chain of PARM_DECLs (if a prototype was used) - or a list of IDENTIFIER_NODEs (for an old-fashioned C definition). */ - tree specparms = current_function_parms; - - /* This is a list of types declared among parms in a prototype. */ - tree parmtags = current_function_parm_tags; - - /* This is a chain of PARM_DECLs from old-style parm declarations. */ - register tree parmdecls = getdecls (); - - /* This is a chain of any other decls that came in among the parm - declarations. If a parm is declared with enum {foo, bar} x; - then CONST_DECLs for foo and bar are put here. */ - tree nonparms = 0; - - /* Nonzero if this definition is written with a prototype. */ - int prototype = 0; - - if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST) - { - /* This case is when the function was defined with an ANSI prototype. - The parms already have decls, so we need not do anything here - except record them as in effect - and complain if any redundant old-style parm decls were written. */ - - register tree next; - tree others = 0; - - prototype = 1; - - if (parmdecls != 0) - { - tree decl, link; - - error_with_decl (fndecl, - "parm types given both in parmlist and separately"); - /* Get rid of the erroneous decls; don't keep them on - the list of parms, since they might not be PARM_DECLs. */ - for (decl = current_binding_level->names; - decl; decl = TREE_CHAIN (decl)) - if (DECL_NAME (decl)) - IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) = 0; - for (link = current_binding_level->shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - current_binding_level->names = 0; - current_binding_level->shadowed = 0; - } - - specparms = nreverse (specparms); - for (parm = specparms; parm; parm = next) - { - next = TREE_CHAIN (parm); - if (TREE_CODE (parm) == PARM_DECL) - { - if (DECL_NAME (parm) == 0) - error_with_decl (parm, "parameter name omitted"); - else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) - { - error_with_decl (parm, "parameter `%s' declared void"); - /* Change the type to error_mark_node so this parameter - will be ignored by assign_parms. */ - TREE_TYPE (parm) = error_mark_node; - } - pushdecl (parm); - } - else - { - /* If we find an enum constant or a type tag, - put it aside for the moment. */ - TREE_CHAIN (parm) = 0; - others = chainon (others, parm); - } - } - - /* Get the decls in their original chain order - and record in the function. */ - DECL_ARGUMENTS (fndecl) = getdecls (); - -#if 0 - /* If this function takes a variable number of arguments, - add a phony parameter to the end of the parm list, - to represent the position of the first unnamed argument. */ - if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))) - != void_type_node) - { - tree dummy = build_decl (PARM_DECL, NULL_TREE, void_type_node); - /* Let's hope the address of the unnamed parm - won't depend on its type. */ - TREE_TYPE (dummy) = integer_type_node; - DECL_ARG_TYPE (dummy) = integer_type_node; - DECL_ARGUMENTS (fndecl) - = chainon (DECL_ARGUMENTS (fndecl), dummy); - } -#endif - - /* Now pushdecl the enum constants. */ - for (parm = others; parm; parm = next) - { - next = TREE_CHAIN (parm); - if (DECL_NAME (parm) == 0) - ; - else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) - ; - else if (TREE_CODE (parm) != PARM_DECL) - pushdecl (parm); - } - - storetags (chainon (parmtags, gettags ())); - } - else - { - /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes - each with a parm name as the TREE_VALUE. - - PARMDECLS is a chain of declarations for parameters. - Warning! It can also contain CONST_DECLs which are not parameters - but are names of enumerators of any enum types - declared among the parameters. - - First match each formal parameter name with its declaration. - Associate decls with the names and store the decls - into the TREE_PURPOSE slots. */ - - for (parm = parmdecls; parm; parm = TREE_CHAIN (parm)) - DECL_RESULT (parm) = 0; - - for (parm = specparms; parm; parm = TREE_CHAIN (parm)) - { - register tree tail, found = NULL; - - if (TREE_VALUE (parm) == 0) - { - error_with_decl (fndecl, "parameter name missing from parameter list"); - TREE_PURPOSE (parm) = 0; - continue; - } - - /* See if any of the parmdecls specifies this parm by name. - Ignore any enumerator decls. */ - for (tail = parmdecls; tail; tail = TREE_CHAIN (tail)) - if (DECL_NAME (tail) == TREE_VALUE (parm) - && TREE_CODE (tail) == PARM_DECL) - { - found = tail; - break; - } - - /* If declaration already marked, we have a duplicate name. - Complain, and don't use this decl twice. */ - if (found && DECL_RESULT (found) != 0) - { - error_with_decl (found, "multiple parameters named `%s'"); - found = 0; - } - - /* If the declaration says "void", complain and ignore it. */ - if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node) - { - error_with_decl (found, "parameter `%s' declared void"); - TREE_TYPE (found) = integer_type_node; - DECL_ARG_TYPE (found) = integer_type_node; - layout_decl (found, 0); - } - - /* Traditionally, a parm declared float is actually a double. */ - if (found && flag_traditional - && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node) - { - TREE_TYPE (found) = double_type_node; - DECL_ARG_TYPE (found) = double_type_node; - layout_decl (found, 0); - } - - /* If no declaration found, default to int. */ - if (!found) - { - found = build_decl (PARM_DECL, TREE_VALUE (parm), - integer_type_node); - DECL_ARG_TYPE (found) = TREE_TYPE (found); - DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl); - DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl); - if (extra_warnings) - warning_with_decl (found, "type of `%s' defaults to `int'"); - pushdecl (found); - } - - TREE_PURPOSE (parm) = found; - - /* Mark this decl as "already found" -- see test, above. - It is safe to use DECL_RESULT for this - since it is not used in PARM_DECLs or CONST_DECLs. */ - DECL_RESULT (found) = error_mark_node; - } - - /* Put anything which is on the parmdecls chain and which is - not a PARM_DECL onto the list NONPARMS. (The types of - non-parm things which might appear on the list include - enumerators and NULL-named TYPE_DECL nodes.) Complain about - any actual PARM_DECLs not matched with any names. */ - - nonparms = 0; - for (parm = parmdecls; parm; ) - { - tree next = TREE_CHAIN (parm); - TREE_CHAIN (parm) = 0; - - if (TREE_CODE (parm) != PARM_DECL) - nonparms = chainon (nonparms, parm); - else - { - /* Complain about args with incomplete types. */ - if (TYPE_SIZE (TREE_TYPE (parm)) == 0) - { - error_with_decl (parm, "parameter `%s' has incomplete type"); - TREE_TYPE (parm) = error_mark_node; - } - - if (DECL_RESULT (parm) == 0) - { - error_with_decl (parm, - "declaration for parameter `%s' but no such parameter"); - /* Pretend the parameter was not missing. - This gets us to a standard state and minimizes - further error messages. */ - specparms - = chainon (specparms, - tree_cons (parm, NULL_TREE, NULL_TREE)); - } - } - - parm = next; - } - - /* Chain the declarations together in the order of the list of names. */ - /* Store that chain in the function decl, replacing the list of names. */ - parm = specparms; - DECL_ARGUMENTS (fndecl) = 0; - { - register tree last; - for (last = 0; parm; parm = TREE_CHAIN (parm)) - if (TREE_PURPOSE (parm)) - { - if (last == 0) - DECL_ARGUMENTS (fndecl) = TREE_PURPOSE (parm); - else - TREE_CHAIN (last) = TREE_PURPOSE (parm); - last = TREE_PURPOSE (parm); - TREE_CHAIN (last) = 0; - } - } - - /* If there was a previous prototype, - set the DECL_ARG_TYPE of each argument according to - the type previously specified, and report any mismatches. */ - - if (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) - { - register tree type; - for (parm = DECL_ARGUMENTS (fndecl), - type = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type)) - != void_type_node)); - parm = TREE_CHAIN (parm), type = TREE_CHAIN (type)) - { - if (parm == 0 || type == 0 - || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) - { - error ("number of arguments doesn't match prototype"); - error_with_file_and_line (current_function_prototype_file, - current_function_prototype_line, - "prototype declaration"); - break; - } - /* Type for passing arg must be consistent - with that declared for the arg. */ - if (! comptypes (DECL_ARG_TYPE (parm), TREE_VALUE (type))) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) - == TYPE_MAIN_VARIANT (TREE_VALUE (type))) - { - /* Adjust argument to match prototype. E.g. a previous - `int foo(float);' prototype causes - `int foo(x) float x; {...}' to be treated like - `int foo(float x) {...}'. This is particularly - useful for argument types like uid_t. */ - DECL_ARG_TYPE (parm) = TREE_TYPE (parm); -#ifdef PROMOTE_PROTOTYPES - if (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE - && TYPE_PRECISION (TREE_TYPE (parm)) - < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (parm) = integer_type_node; -#endif - if (pedantic) - { - pedwarn ("promoted argument `%s' doesn't match prototype", - IDENTIFIER_POINTER (DECL_NAME (parm))); - warning_with_file_and_line - (current_function_prototype_file, - current_function_prototype_line, - "prototype declaration"); - } - } - /* If -traditional, allow `int' argument to match - `unsigned' prototype. */ - else if (! (flag_traditional - && TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node - && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)) - { - error ("argument `%s' doesn't match prototype", - IDENTIFIER_POINTER (DECL_NAME (parm))); - error_with_file_and_line (current_function_prototype_file, - current_function_prototype_line, - "prototype declaration"); - } - } - } - TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0; - } - - /* Otherwise, create a prototype that would match. */ - - else - { - register tree actual, type; - register tree last = 0; - - for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm)) - { - type = perm_tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), - NULL_TREE); - if (last) - TREE_CHAIN (last) = type; - else - actual = type; - last = type; - } - type = perm_tree_cons (NULL_TREE, void_type_node, NULL_TREE); - if (last) - TREE_CHAIN (last) = type; - else - actual = type; - - /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES - of the type of this function, but we need to avoid having this - affect the types of other similarly-typed functions, so we must - first force the generation of an identical (but separate) type - node for the relevant function type. The new node we create - will be a variant of the main variant of the original function - type. */ - - TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl)); - - TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual; - } - - /* Now store the final chain of decls for the arguments - as the decl-chain of the current lexical scope. - Put the enumerators in as well, at the front so that - DECL_ARGUMENTS is not modified. */ - - storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); - } - - /* Make sure the binding level for the top of the function body - gets a BLOCK if there are any in the function. - Otherwise, the dbx output is wrong. */ - - keep_next_if_subblocks = 1; - - /* ??? This might be an improvement, - but needs to be thought about some more. */ -#if 0 - keep_next_level_flag = 1; -#endif - - /* Write a record describing this function definition to the prototypes - file (if requested). */ - - gen_aux_info_record (fndecl, 1, 0, prototype); - - /* Initialize the RTL code for the function. */ - - init_function_start (fndecl, input_filename, lineno); - - /* If this is a varargs function, inform function.c. */ - - if (c_function_varargs) - mark_varargs (); - - /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ - - declare_function_name (); - - /* Set up parameters and prepare for return, for the function. */ - - expand_function_start (fndecl, 0); - - /* If this function is `main', emit a call to `__main' - to run global initializers, etc. */ - if (DECL_NAME (fndecl) - && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0 - && DECL_CONTEXT (fndecl) == NULL_TREE) - expand_main_function (); -} - -/* SPECPARMS is an identifier list--a chain of TREE_LIST nodes - each with a parm name as the TREE_VALUE. A null pointer as TREE_VALUE - stands for an ellipsis in the identifier list. - - PARMLIST is the data returned by get_parm_info for the - parmlist that follows the semicolon. - - We return a value of the same sort that get_parm_info returns, - except that it describes the combination of identifiers and parmlist. */ - -tree -combine_parm_decls (specparms, parmlist, void_at_end) - tree specparms, parmlist; - int void_at_end; -{ - register tree fndecl = current_function_decl; - register tree parm; - - tree parmdecls = TREE_PURPOSE (parmlist); - - /* This is a chain of any other decls that came in among the parm - declarations. They were separated already by get_parm_info, - so we just need to keep them separate. */ - tree nonparms = TREE_VALUE (parmlist); - - tree types = 0; - - for (parm = parmdecls; parm; parm = TREE_CHAIN (parm)) - DECL_RESULT (parm) = 0; - - for (parm = specparms; parm; parm = TREE_CHAIN (parm)) - { - register tree tail, found = NULL; - - /* See if any of the parmdecls specifies this parm by name. */ - for (tail = parmdecls; tail; tail = TREE_CHAIN (tail)) - if (DECL_NAME (tail) == TREE_VALUE (parm)) - { - found = tail; - break; - } - - /* If declaration already marked, we have a duplicate name. - Complain, and don't use this decl twice. */ - if (found && DECL_RESULT (found) != 0) - { - error_with_decl (found, "multiple parameters named `%s'"); - found = 0; - } - - /* If the declaration says "void", complain and ignore it. */ - if (found && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == void_type_node) - { - error_with_decl (found, "parameter `%s' declared void"); - TREE_TYPE (found) = integer_type_node; - DECL_ARG_TYPE (found) = integer_type_node; - layout_decl (found, 0); - } - - /* Traditionally, a parm declared float is actually a double. */ - if (found && flag_traditional - && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node) - { - TREE_TYPE (found) = double_type_node; - DECL_ARG_TYPE (found) = double_type_node; - layout_decl (found, 0); - } - - /* If no declaration found, default to int. */ - if (!found) - { - found = build_decl (PARM_DECL, TREE_VALUE (parm), - integer_type_node); - DECL_ARG_TYPE (found) = TREE_TYPE (found); - DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl); - DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl); - error_with_decl (found, "type of parameter `%s' is not declared"); - pushdecl (found); - } - - TREE_PURPOSE (parm) = found; - - /* Mark this decl as "already found" -- see test, above. - It is safe to use DECL_RESULT for this - since it is not used in PARM_DECLs or CONST_DECLs. */ - DECL_RESULT (found) = error_mark_node; - } - - /* Complain about any actual PARM_DECLs not matched with any names. */ - - for (parm = parmdecls; parm; ) - { - tree next = TREE_CHAIN (parm); - TREE_CHAIN (parm) = 0; - - /* Complain about args with incomplete types. */ - if (TYPE_SIZE (TREE_TYPE (parm)) == 0) - { - error_with_decl (parm, "parameter `%s' has incomplete type"); - TREE_TYPE (parm) = error_mark_node; - } - - if (DECL_RESULT (parm) == 0) - { - error_with_decl (parm, - "declaration for parameter `%s' but no such parameter"); - /* Pretend the parameter was not missing. - This gets us to a standard state and minimizes - further error messages. */ - specparms - = chainon (specparms, - tree_cons (parm, NULL_TREE, NULL_TREE)); - } - - parm = next; - } - - /* Chain the declarations together in the order of the list of names. - At the same time, build up a list of their types, in reverse order. */ - - parm = specparms; - parmdecls = 0; - { - register tree last; - for (last = 0; parm; parm = TREE_CHAIN (parm)) - if (TREE_PURPOSE (parm)) - { - if (last == 0) - parmdecls = TREE_PURPOSE (parm); - else - TREE_CHAIN (last) = TREE_PURPOSE (parm); - last = TREE_PURPOSE (parm); - TREE_CHAIN (last) = 0; - - types = saveable_tree_cons (NULL_TREE, TREE_TYPE (parm), types); - } - } - - if (void_at_end) - return saveable_tree_cons (parmdecls, nonparms, - nreverse (saveable_tree_cons (NULL_TREE, void_type_node, types))); - - return saveable_tree_cons (parmdecls, nonparms, nreverse (types)); -} - -/* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage - for the function definition. - - This is called after parsing the body of the function definition. - - NESTED is nonzero if the function being finished is nested in another. */ - -void -finish_function (nested) - int nested; -{ - register tree fndecl = current_function_decl; - -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ - - poplevel (1, 0, 1); - BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - - /* Must mark the RESULT_DECL as being in this function. */ - - DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; - - /* Obey `register' declarations if `setjmp' is called in this fn. */ - if (flag_traditional && current_function_calls_setjmp) - { - setjmp_protect (DECL_INITIAL (fndecl)); - setjmp_protect_args (); - } - -#ifdef DEFAULT_MAIN_RETURN - if (! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main")) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) - != integer_type_node) - warning_with_decl (fndecl, "return type of `%s' is not `int'"); - else - { - /* Make it so that `main' always returns success by default. */ - DEFAULT_MAIN_RETURN; - } - } -#endif - - /* Generate rtl for function exit. */ - expand_function_end (input_filename, lineno); - - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - - /* Run the optimizers and output the assembler code for this function. */ - rest_of_compilation (fndecl); - - current_function_returns_null |= can_reach_end; - - if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) - warning ("`volatile' function does return"); - else if (warn_return_type && can_reach_end - && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) != void_type_node) - /* If this function returns non-void and control can drop through, - complain. */ - warning ("control reaches end of non-void function"); - /* With just -W, complain only if function returns both with - and without a value. */ - else if (extra_warnings - && current_function_returns_value && current_function_returns_null) - warning ("this function may return with or without a value"); - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently - until we start another function. */ - if (! nested) - permanent_allocation (); - - if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - /* For a nested function, this is done in pop_c_function_context. */ - DECL_INITIAL (fndecl) = error_mark_node; - DECL_ARGUMENTS (fndecl) = 0; - } - - if (! nested) - { - /* Let the error reporting routines know that we're outside a - function. For a nested function, this value is used in - pop_c_function_context and then reset via pop_function_context. */ - current_function_decl = NULL; - } -} - -/* Save and restore the variables in this file and elsewhere - that keep track of the progress of compilation of the current function. - Used for nested functions. */ - -struct c_function -{ - struct c_function *next; - tree enum_next_value; - tree named_labels; - tree shadowed_labels; - int returns_value; - int returns_null; - int warn_about_return_type; - int extern_inline; - struct binding_level *binding_level; -}; - -struct c_function *c_function_chain; - -/* Save and reinitialize the variables - used during compilation of a C function. */ - -void -push_c_function_context () -{ - struct c_function *p - = (struct c_function *) xmalloc (sizeof (struct c_function)); - - if (pedantic) - pedwarn ("ANSI C forbids nested functions"); - - push_function_context (); - - p->next = c_function_chain; - c_function_chain = p; - - p->enum_next_value = enum_next_value; - p->named_labels = named_labels; - p->shadowed_labels = shadowed_labels; - p->returns_value = current_function_returns_value; - p->returns_null = current_function_returns_null; - p->warn_about_return_type = warn_about_return_type; - p->extern_inline = current_extern_inline; - p->binding_level = current_binding_level; -} - -/* Restore the variables used during compilation of a C function. */ - -void -pop_c_function_context () -{ - struct c_function *p = c_function_chain; - tree link; - - /* Bring back all the labels that were shadowed. */ - for (link = shadowed_labels; link; link = TREE_CHAIN (link)) - if (DECL_NAME (TREE_VALUE (link)) != 0) - IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) - = TREE_VALUE (link); - - if (DECL_SAVED_INSNS (current_function_decl) == 0) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - DECL_INITIAL (current_function_decl) = error_mark_node; - DECL_ARGUMENTS (current_function_decl) = 0; - } - - pop_function_context (); - - c_function_chain = p->next; - - enum_next_value = p->enum_next_value; - named_labels = p->named_labels; - shadowed_labels = p->shadowed_labels; - current_function_returns_value = p->returns_value; - current_function_returns_null = p->returns_null; - warn_about_return_type = p->warn_about_return_type; - current_extern_inline = p->extern_inline; - current_binding_level = p->binding_level; - - free (p); -} diff --git a/gnu/usr.bin/gcc2/cc1/c-iterate.c b/gnu/usr.bin/gcc2/cc1/c-iterate.c deleted file mode 100644 index dc0d67617c5..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-iterate.c +++ /dev/null @@ -1,597 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-iterate.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -/* This file is part of the C front end. - It is responsible for implementing iterators, - both their declarations and the expansion of statements using them. */ - -#include "config.h" -#include -#include "tree.h" -#include "c-tree.h" -#include "flags.h" -#include "obstack.h" -#include "rtl.h" - -static void expand_stmt_with_iterators_1 (); -static tree collect_iterators (); -static void iterator_loop_prologue (); -static void iterator_loop_epilogue (); -static void add_ixpansion (); -static void delete_ixpansion(); -static int top_level_ixpansion_p (); -static void istack_sublevel_to_current (); - -/* A special obstack, and a pointer to the start of - all the data in it (so we can free everything easily). */ -static struct obstack ixp_obstack; -static char *ixp_firstobj; - -/* - KEEPING TRACK OF EXPANSIONS - - In order to clean out expansions corresponding to statements inside - "{(...)}" constructs we have to keep track of all expansions. The - cleanup is needed when an automatic, or implicit, expansion on - iterator, say X, happens to a statement which contains a {(...)} - form with a statement already expanded on X. In this case we have - to go back and cleanup the inner expansion. This can be further - complicated by the fact that {(...)} can be nested. - - To make this cleanup possible, we keep lists of all expansions, and - to make it work for nested constructs, we keep a stack. The list at - the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the - currently parsed level. All expansions of the levels below the - current one are kept in one list whose head is pointed to by - ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges - easy). The process works as follows: - - -- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK. - The sublevel list is not changed at this point. - - -- On "})" the list for the current level is appended to the sublevel - list. - - -- On ";" sublevel lists are appended to the current level lists. - The reason is this: if they have not been superseded by the - expansion at the current level, they still might be - superseded later by the expansion on the higher level. - The levels do not have to distinguish levels below, so we - can merge the lists together. */ - -struct ixpansion -{ - tree ixdecl; /* Iterator decl */ - rtx ixprologue_start; /* First insn of epilogue. NULL means */ - /* explicit (FOR) expansion*/ - rtx ixprologue_end; - rtx ixepilogue_start; - rtx ixepilogue_end; - struct ixpansion *next; /* Next in the list */ -}; - -struct iter_stack_node -{ - struct ixpansion *first; /* Head of list of ixpansions */ - struct ixpansion *last; /* Last node in list of ixpansions */ - struct iter_stack_node *next; /* Next level iterator stack node */ -}; - -struct iter_stack_node *iter_stack; - -struct iter_stack_node sublevel_ixpansions; - -/* During collect_iterators, a list of SAVE_EXPRs already scanned. */ -static tree save_exprs; - -/* Initialize our obstack once per compilation. */ - -void -init_iterators () -{ - gcc_obstack_init (&ixp_obstack); - ixp_firstobj = (char *) obstack_alloc (&ixp_obstack, 0); -} - -/* Handle the start of an explicit `for' loop for iterator IDECL. */ - -void -iterator_for_loop_start (idecl) - tree idecl; -{ - ITERATOR_BOUND_P (idecl) = 1; - add_ixpansion (idecl, 0, 0, 0, 0); - iterator_loop_prologue (idecl, 0, 0); -} - -/* Handle the end of an explicit `for' loop for iterator IDECL. */ - -void -iterator_for_loop_end (idecl) - tree idecl; -{ - iterator_loop_epilogue (idecl, 0, 0); - ITERATOR_BOUND_P (idecl) = 0; -} - -/* - ITERATOR RTL EXPANSIONS - - Expanding simple statements with iterators is straightforward: - collect the list of all free iterators in the statement, and - generate a loop for each of them. - - An iterator is "free" if it has not been "bound" by a FOR - operator. The DECL_RTL of the iterator is the loop counter. */ - -/* Expand a statement STMT, possibly containing iterator usage, into RTL. */ - -void -iterator_expand (stmt) - tree stmt; -{ - tree iter_list; - save_exprs = NULL_TREE; - iter_list = collect_iterators (stmt, NULL_TREE); - expand_stmt_with_iterators_1 (stmt, iter_list); - istack_sublevel_to_current (); -} - - -static void -expand_stmt_with_iterators_1 (stmt, iter_list) - tree stmt, iter_list; -{ - if (iter_list == 0) - expand_expr_stmt (stmt); - else - { - tree current_iterator = TREE_VALUE (iter_list); - tree iter_list_tail = TREE_CHAIN (iter_list); - rtx p_start, p_end, e_start, e_end; - - iterator_loop_prologue (current_iterator, &p_start, &p_end); - expand_stmt_with_iterators_1 (stmt, iter_list_tail); - iterator_loop_epilogue (current_iterator, &e_start, &e_end); - - /** Delete all inner expansions based on current_iterator **/ - /** before adding the outer one. **/ - - delete_ixpansion (current_iterator); - add_ixpansion (current_iterator, p_start, p_end, e_start, e_end); - } -} - - -/* Return a list containing all the free (i.e. not bound by a - containing `for' statement) iterators mentioned in EXP, plus those - in LIST. Do not add duplicate entries to the list. */ - -static tree -collect_iterators (exp, list) - tree exp, list; -{ - if (exp == 0) return list; - - switch (TREE_CODE (exp)) - { - case VAR_DECL: - if (! ITERATOR_P (exp) || ITERATOR_BOUND_P (exp)) - return list; - if (value_member (exp, list)) - return list; - return tree_cons (NULL_TREE, exp, list); - - case TREE_LIST: - { - tree tail; - for (tail = exp; tail; tail = TREE_CHAIN (tail)) - list = collect_iterators (TREE_VALUE (tail), list); - return list; - } - - case SAVE_EXPR: - /* In each scan, scan a given save_expr only once. */ - { - tree tail; - for (tail = save_exprs; tail; tail = TREE_CHAIN (tail)) - if (TREE_VALUE (tail) == exp) - return list; - } - save_exprs = tree_cons (NULL_TREE, exp, save_exprs); - return collect_iterators (TREE_OPERAND (exp, 0), list); - - /* we do not automatically iterate blocks -- one must */ - /* use the FOR construct to do that */ - - case BLOCK: - return list; - - default: - switch (TREE_CODE_CLASS (TREE_CODE (exp))) - { - case '1': - return collect_iterators (TREE_OPERAND (exp, 0), list); - - case '2': - case '<': - return collect_iterators (TREE_OPERAND (exp, 0), - collect_iterators (TREE_OPERAND (exp, 1), - list)); - - case 'e': - case 'r': - { - int num_args = tree_code_length[(int) TREE_CODE (exp)]; - int i; - - /* Some tree codes have RTL, not trees, as operands. */ - switch (TREE_CODE (exp)) - { - case CALL_EXPR: - num_args = 2; - break; - case METHOD_CALL_EXPR: - num_args = 3; - break; - case WITH_CLEANUP_EXPR: - num_args = 1; - break; - case RTL_EXPR: - return list; - } - - for (i = 0; i < num_args; i++) - list = collect_iterators (TREE_OPERAND (exp, i), list); - return list; - } - default: - return list; - } - } -} - -/* Emit rtl for the start of a loop for iterator IDECL. - - If necessary, create loop counter rtx and store it as DECL_RTL of IDECL. - - The prologue normally starts and ends with notes, which are returned - by this function in *START_NOTE and *END_NODE. - If START_NOTE and END_NODE are 0, we don't make those notes. */ - -static void -iterator_loop_prologue (idecl, start_note, end_note) - tree idecl; - rtx *start_note, *end_note; -{ - /* Force the save_expr in DECL_INITIAL to be calculated - if it hasn't been calculated yet. */ - expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0); - - if (DECL_RTL (idecl) == 0) - expand_decl (idecl); - - if (start_note) - *start_note = emit_note (0, NOTE_INSN_DELETED); - /* Initialize counter. */ - expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), - idecl, integer_zero_node), - 0, VOIDmode, 0); - - expand_start_loop_continue_elsewhere (1); - - ITERATOR_BOUND_P (idecl) = 1; - - if (end_note) - *end_note = emit_note (0, NOTE_INSN_DELETED); -} - -/* Similar to the previous function, but for the end of the loop. - - DECL_RTL is zeroed unless we are inside "({...})". The reason for that is - described below. - - When we create two (or more) loops based on the same IDECL, and - both inside the same "({...})" construct, we must be prepared to - delete both of the loops and create a single one on the level - above, i.e. enclosing the "({...})". The new loop has to use the - same counter rtl because the references to the iterator decl - (IDECL) have already been expanded as references to the counter - rtl. - - It is incorrect to use the same counter reg in different functions, - and it is desirable to use different counters in disjoint loops - when we know there's no need to combine them (because then they can - get allocated separately). */ - -static void -iterator_loop_epilogue (idecl, start_note, end_note) - tree idecl; - rtx *start_note, *end_note; -{ - tree test, incr; - - if (start_note) - *start_note = emit_note (0, NOTE_INSN_DELETED); - expand_loop_continue_here (); - incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0); - expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr), - 0, VOIDmode, 0); - test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0); - expand_exit_loop_if_false (0, test); - expand_end_loop (); - - ITERATOR_BOUND_P (idecl) = 0; - /* we can reset rtl since there is not chance that this expansion */ - /* would be superceded by a higher level one */ - if (top_level_ixpansion_p ()) - DECL_RTL (idecl) = 0; - if (end_note) - *end_note = emit_note (0, NOTE_INSN_DELETED); -} - -/* Return true if we are not currently inside a "({...})" construct. */ - -static int -top_level_ixpansion_p () -{ - return iter_stack == 0; -} - -/* Given two chains of iter_stack_nodes, - append the nodes in X into Y. */ - -static void -isn_append (x, y) - struct iter_stack_node *x, *y; -{ - if (x->first == 0) - return; - - if (y->first == 0) - { - y->first = x->first; - y->last = x->last; - } - else - { - y->last->next = x->first; - y->last = x->last; - } -} - -/** Make X empty **/ - -#define ISN_ZERO(X) (X).first=(X).last=0 - -/* Move the ixpansions in sublevel_ixpansions into the current - node on the iter_stack, or discard them if the iter_stack is empty. - We do this at the end of a statement. */ - -static void -istack_sublevel_to_current () -{ - /* At the top level we can throw away sublevel's expansions **/ - /* because there is nobody above us to ask for a cleanup **/ - if (iter_stack != 0) - /** Merging with empty sublevel list is a no-op **/ - if (sublevel_ixpansions.last) - isn_append (&sublevel_ixpansions, iter_stack); - - if (iter_stack == 0) - obstack_free (&ixp_obstack, ixp_firstobj); - - ISN_ZERO (sublevel_ixpansions); -} - -/* Push a new node on the iter_stack, when we enter a ({...}). */ - -void -push_iterator_stack () -{ - struct iter_stack_node *new_top - = (struct iter_stack_node*) - obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node)); - - new_top->first = 0; - new_top->last = 0; - new_top->next = iter_stack; - iter_stack = new_top; -} - -/* Pop iter_stack, moving the ixpansions in the node being popped - into sublevel_ixpansions. */ - -void -pop_iterator_stack () -{ - if (iter_stack == 0) - abort (); - - isn_append (iter_stack, &sublevel_ixpansions); - /** Pop current level node: */ - iter_stack = iter_stack->next; -} - - -/* Record an iterator expansion ("ixpansion") for IDECL. - The remaining paramters are the notes in the loop entry - and exit rtl. */ - -static void -add_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end) - tree idecl; - rtx pro_start, pro_end, epi_start, epi_end; -{ - struct ixpansion* newix; - - /* Do nothing if we are not inside "({...})", - as in that case this expansion can't need subsequent RTL modification. */ - if (iter_stack == 0) - return; - - newix = (struct ixpansion*) obstack_alloc (&ixp_obstack, - sizeof (struct ixpansion)); - newix->ixdecl = idecl; - newix->ixprologue_start = pro_start; - newix->ixprologue_end = pro_end; - newix->ixepilogue_start = epi_start; - newix->ixepilogue_end = epi_end; - - newix->next = iter_stack->first; - iter_stack->first = newix; - if (iter_stack->last == 0) - iter_stack->last = newix; -} - -/* Delete the RTL for all ixpansions for iterator IDECL - in our sublevels. We do this when we make a larger - containing expansion for IDECL. */ - -static void -delete_ixpansion (idecl) - tree idecl; -{ - struct ixpansion* previx = 0, *ix; - - for (ix = sublevel_ixpansions.first; ix; ix = ix->next) - if (ix->ixdecl == idecl) - { - /** zero means that this is a mark for FOR -- **/ - /** we do not delete anything, just issue an error. **/ - - if (ix->ixprologue_start == 0) - error_with_decl (idecl, - "`for (%s)' appears within implicit iteration"); - else - { - rtx insn; - /* We delete all insns, including notes because leaving loop */ - /* notes and barriers produced by iterator expansion would */ - /* be misleading to other phases */ - - for (insn = NEXT_INSN (ix->ixprologue_start); - insn != ix->ixprologue_end; - insn = NEXT_INSN (insn)) - delete_insn (insn); - for (insn = NEXT_INSN (ix->ixepilogue_start); - insn != ix->ixepilogue_end; - insn = NEXT_INSN (insn)) - delete_insn (insn); - } - - /* Delete this ixpansion from sublevel_ixpansions. */ - if (previx) - previx->next = ix->next; - else - sublevel_ixpansions.first = ix->next; - if (sublevel_ixpansions.last == ix) - sublevel_ixpansions.last = previx; - } - else - previx = ix; -} - -#ifdef DEBUG_ITERATORS - -/* The functions below are for use from source level debugger. - They print short forms of iterator lists and the iterator stack. */ - -/* Print the name of the iterator D. */ - -void -prdecl (d) - tree d; -{ - if (d) - { - if (TREE_CODE (d) == VAR_DECL) - { - tree tname = DECL_NAME (d); - char *dname = IDENTIFIER_POINTER (tname); - fprintf (stderr, dname); - } - else - fprintf (stderr, "<>"); - } - else - fprintf (stderr, "<>"); -} - -/* Print Iterator List -- names only */ - -tree -pil (head) - tree head; -{ - tree current, next; - for (current = head; current; current = next) - { - tree node = TREE_VALUE (current); - prdecl (node); - next = TREE_CHAIN (current); - if (next) fprintf (stderr, ","); - } - fprintf (stderr, "\n"); -} - -/* Print IXpansion List */ - -struct ixpansion * -pixl (head) - struct ixpansion *head; -{ - struct ixpansion *current, *next; - fprintf (stderr, "> "); - if (head == 0) - fprintf (stderr, "(empty)"); - - for (current=head; current; current = next) - { - tree node = current->ixdecl; - prdecl (node); - next = current->next; - if (next) - fprintf (stderr, ","); - } - fprintf (stderr, "\n"); - return head; -} - -/* Print Iterator Stack*/ - -void -pis () -{ - struct iter_stack_node *stack_node; - - fprintf (stderr, "--SubLevel: "); - pixl (sublevel_ixpansions.first); - fprintf (stderr, "--Stack:--\n"); - for (stack_node = iter_stack; - stack_node; - stack_node = stack_node->next) - pixl (stack_node->first); -} - -#endif /* DEBUG_ITERATORS */ diff --git a/gnu/usr.bin/gcc2/cc1/c-lang.c b/gnu/usr.bin/gcc2/cc1/c-lang.c deleted file mode 100644 index a81a33a18c9..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-lang.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Language-specific hook definitions for C front end. - Copyright (C) 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-lang.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -#include "config.h" -#include "tree.h" -#include -#include "input.h" - -/* Each of the functions defined here - is an alternative to a function in objc-actions.c. */ - -int -lang_decode_option (p) - char *p; -{ - return c_decode_option (p); -} - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ - ungetc (check_newline (), finput); -} - -void -lang_finish () -{ -} - -char * -lang_identify () -{ - return "c"; -} - -void -print_lang_statistics () -{ -} - -/* Used by c-lex.c, but only for objc. */ - -tree -lookup_interface (arg) - tree arg; -{ - return 0; -} - -tree -is_class_name (arg) - tree arg; -{ - return 0; -} - -void -maybe_objc_check_decl (decl) - tree decl; -{ -} - -int -maybe_objc_comptypes (lhs, rhs, reflexive) - tree lhs, rhs; - int reflexive; -{ - return -1; -} - -tree -maybe_objc_method_name (decl) - tree decl; -{ - return 0; -} - -tree -maybe_building_objc_message_expr () -{ - return 0; -} - -int -recognize_objc_keyword () -{ - return 0; -} - -tree -build_objc_string (len, str) - int len; - char *str; -{ - abort (); - return NULL_TREE; -} - -void -GNU_xref_begin () -{ - fatal ("GCC does not yet support XREF"); -} - -void -GNU_xref_end () -{ - fatal ("GCC does not yet support XREF"); -} diff --git a/gnu/usr.bin/gcc2/cc1/c-lex.c b/gnu/usr.bin/gcc2/cc1/c-lex.c deleted file mode 100644 index 9e94f94d43d..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-lex.c +++ /dev/null @@ -1,2114 +0,0 @@ -/* Lexical analyzer for C and Objective C. - Copyright (C) 1987, 1988, 1989, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-lex.c,v 1.1.1.1 1995/10/18 08:39:27 deraadt Exp $"; -#endif /* not lint */ - -#include -#include -#include - -#include "config.h" -#include "rtl.h" -#include "tree.h" -#include "input.h" -#include "c-lex.h" -#include "c-tree.h" -#include "flags.h" -#include "c-parse.h" - -#ifdef MULTIBYTE_CHARS -#include -#include -#endif - -#ifndef errno -extern int errno; -#endif - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -tree ridpointers[(int) RID_MAX]; - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -tree lastiddecl; - -/* Nonzero enables objc features. */ - -int doing_objc_thang; - -extern tree is_class_name (); - -extern int yydebug; - -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; - -#ifndef WCHAR_TYPE_SIZE -#ifdef INT_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#else -#define WCHAR_TYPE_SIZE BITS_PER_WORD -#endif -#endif - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. - This is not static because objc-parse.y uses it. */ - -/* Nonzero if end-of-file has been seen on input. */ -static int end_of_file; - -/* Buffered-back input character; faster than using ungetc. */ -static int nextchar = -1; - -int check_newline (); - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag = 0; - -/* C code produced by gperf version 2.5 (GNU C++ version) */ -/* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */ -struct resword { char *name; short token; enum rid rid; }; - -#define TOTAL_KEYWORDS 79 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 20 -#define MIN_HASH_VALUE 10 -#define MAX_HASH_VALUE 144 -/* maximum key range = 135, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -hash (str, len) - register char *str; - register int unsigned len; -{ - static unsigned char asso_values[] = - { - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 25, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 1, 145, 46, 8, 15, - 61, 6, 36, 48, 3, 5, 145, 18, 63, 25, - 29, 76, 1, 145, 13, 2, 1, 51, 37, 9, - 9, 1, 3, 145, 145, 145, 145, 145, - }; - register int hval = len; - - switch (hval) - { - default: - case 3: - hval += asso_values[str[2]]; - case 2: - case 1: - hval += asso_values[str[0]]; - } - return hval + asso_values[str[len - 1]]; -} - -static struct resword wordlist[] = -{ - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, - {"int", TYPESPEC, RID_INT}, - {"",}, {"",}, - {"__typeof__", TYPEOF, NORID}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"__imag__", IMAGPART, NORID}, - {"switch", SWITCH, NORID}, - {"__inline__", SCSPEC, RID_INLINE}, - {"else", ELSE, NORID}, - {"__iterator__", SCSPEC, RID_ITERATOR}, - {"__inline", SCSPEC, RID_INLINE}, - {"__extension__", EXTENSION, NORID}, - {"struct", STRUCT, NORID}, - {"__real__", REALPART, NORID}, - {"__const", TYPE_QUAL, RID_CONST}, - {"while", WHILE, NORID}, - {"__const__", TYPE_QUAL, RID_CONST}, - {"case", CASE, NORID}, - {"__complex__", TYPESPEC, RID_COMPLEX}, - {"__iterator", SCSPEC, RID_ITERATOR}, - {"bycopy", TYPE_QUAL, RID_BYCOPY}, - {"",}, {"",}, {"",}, - {"__complex", TYPESPEC, RID_COMPLEX}, - {"",}, - {"in", TYPE_QUAL, RID_IN}, - {"break", BREAK, NORID}, - {"@defs", DEFS, NORID}, - {"",}, {"",}, {"",}, - {"extern", SCSPEC, RID_EXTERN}, - {"if", IF, NORID}, - {"typeof", TYPEOF, NORID}, - {"typedef", SCSPEC, RID_TYPEDEF}, - {"__typeof", TYPEOF, NORID}, - {"sizeof", SIZEOF, NORID}, - {"",}, - {"return", RETURN, NORID}, - {"const", TYPE_QUAL, RID_CONST}, - {"__volatile__", TYPE_QUAL, RID_VOLATILE}, - {"@private", PRIVATE, NORID}, - {"@selector", SELECTOR, NORID}, - {"__volatile", TYPE_QUAL, RID_VOLATILE}, - {"__asm__", ASM_KEYWORD, NORID}, - {"",}, {"",}, - {"continue", CONTINUE, NORID}, - {"__alignof__", ALIGNOF, NORID}, - {"__imag", IMAGPART, NORID}, - {"__attribute__", ATTRIBUTE, NORID}, - {"",}, {"",}, - {"__attribute", ATTRIBUTE, NORID}, - {"for", FOR, NORID}, - {"",}, - {"@encode", ENCODE, NORID}, - {"id", OBJECTNAME, RID_ID}, - {"static", SCSPEC, RID_STATIC}, - {"@interface", INTERFACE, NORID}, - {"",}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"",}, - {"__label__", LABEL, NORID}, - {"",}, {"",}, - {"__asm", ASM_KEYWORD, NORID}, - {"char", TYPESPEC, RID_CHAR}, - {"",}, - {"inline", SCSPEC, RID_INLINE}, - {"out", TYPE_QUAL, RID_OUT}, - {"register", SCSPEC, RID_REGISTER}, - {"__real", REALPART, NORID}, - {"short", TYPESPEC, RID_SHORT}, - {"",}, - {"enum", ENUM, NORID}, - {"inout", TYPE_QUAL, RID_INOUT}, - {"",}, - {"oneway", TYPE_QUAL, RID_ONEWAY}, - {"union", UNION, NORID}, - {"",}, - {"__alignof", ALIGNOF, NORID}, - {"",}, - {"@implementation", IMPLEMENTATION, NORID}, - {"",}, - {"@class", CLASS, NORID}, - {"",}, - {"@public", PUBLIC, NORID}, - {"asm", ASM_KEYWORD, NORID}, - {"",}, {"",}, {"",}, {"",}, {"",}, - {"default", DEFAULT, NORID}, - {"",}, - {"void", TYPESPEC, RID_VOID}, - {"",}, - {"@protected", PROTECTED, NORID}, - {"@protocol", PROTOCOL, NORID}, - {"",}, {"",}, {"",}, - {"volatile", TYPE_QUAL, RID_VOLATILE}, - {"",}, {"",}, - {"signed", TYPESPEC, RID_SIGNED}, - {"float", TYPESPEC, RID_FLOAT}, - {"@end", END, NORID}, - {"",}, {"",}, - {"unsigned", TYPESPEC, RID_UNSIGNED}, - {"@compatibility_alias", ALIAS, NORID}, - {"double", TYPESPEC, RID_DOUBLE}, - {"",}, {"",}, - {"auto", SCSPEC, RID_AUTO}, - {"",}, - {"goto", GOTO, NORID}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"do", DO, NORID}, - {"",}, {"",}, {"",}, {"",}, - {"long", TYPESPEC, RID_LONG}, -}; - -#ifdef __GNUC__ -__inline -#endif -struct resword * -is_reserved_word (str, len) - register char *str; - register unsigned int len; -{ - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register char *s = wordlist[key].name; - - if (*s == *str && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - TYPE_QUALS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (type_quals, target) - tree type_quals, target; -{ - return build1 (INDIRECT_REF, type_quals, target); -} - -void -forget_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if ((int) wordlist[i].rid >= (int) RID_IN - && (int) wordlist[i].rid <= (int) RID_ONEWAY) - wordlist[i].name = ""; -} - -void -remember_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if (wordlist[i].rid == RID_IN) - wordlist[i].name = "in"; - else if (wordlist[i].rid == RID_OUT) - wordlist[i].name = "out"; - else if (wordlist[i].rid == RID_INOUT) - wordlist[i].name = "inout"; - else if (wordlist[i].rid == RID_BYCOPY) - wordlist[i].name = "bycopy"; - else if (wordlist[i].rid == RID_ONEWAY) - wordlist[i].name = "oneway"; -} - -void -init_lex () -{ - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); -#endif - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers[(int) RID_INT] = get_identifier ("int"); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - ridpointers[(int) RID_ITERATOR] = get_identifier ("iterator"); - ridpointers[(int) RID_COMPLEX] = get_identifier ("complex"); - ridpointers[(int) RID_ID] = get_identifier ("id"); - ridpointers[(int) RID_IN] = get_identifier ("in"); - ridpointers[(int) RID_OUT] = get_identifier ("out"); - ridpointers[(int) RID_INOUT] = get_identifier ("inout"); - ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy"); - ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway"); - forget_protocol_qualifiers(); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - - if (! doing_objc_thang) - UNSET_RESERVED_WORD ("id"); - - if (flag_traditional) - { - UNSET_RESERVED_WORD ("const"); - UNSET_RESERVED_WORD ("volatile"); - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("signed"); - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("iterator"); - UNSET_RESERVED_WORD ("complex"); - } - if (flag_no_asm) - { - UNSET_RESERVED_WORD ("asm"); - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("iterator"); - UNSET_RESERVED_WORD ("complex"); - } -} - -void -reinit_parse_for_function () -{ -} - -/* Function used when yydebug is set, to print a token in more detail. */ - -void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; -{ - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case OBJECTNAME: - t = yylval.ttype; - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - - case CONSTANT: - t = yylval.ttype; - if (TREE_CODE (t) == INTEGER_CST) - fprintf (file, -#if HOST_BITS_PER_WIDE_INT == 64 -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%016lx", -#else - " 0x%x%016x", -#endif -#else -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%08lx", -#else - " 0x%x%08x", -#endif -#endif - TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); - break; - } -} - - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - static int newline_warning = 0; - - for (;;) - { - switch (c) - { - /* We don't recognize comments here, because - cpp output can include / and * consecutively as operators. - Also, there's no need, since cpp removes all comments. */ - - case '\n': - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getc (finput); - break; - - case '\r': - /* ANSI C says the effects of a carriage return in a source file - are undefined. */ - if (pedantic && !newline_warning) - { - warning ("carriage return in source file"); - warning ("(we only warn about the first carriage return)"); - newline_warning = 1; - } - c = getc (finput); - break; - - case '\\': - c = getc (finput); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = getc (finput); - break; - - default: - return (c); - } - } -} - -/* Skips all of the white space at the current location in the input file. - Must use and reset nextchar if it has the next character. */ - -void -position_after_white_space () -{ - register int c; - - if (nextchar != -1) - c = nextchar, nextchar = -1; - else - c = getc (finput); - - ungetc (skip_white_space (c), finput); -} - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static char * -extend_token_buffer (p) - char *p; -{ - int offset = p - token_buffer; - - maxtoken = maxtoken * 2 + 10; - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); - - return token_buffer + offset; -} - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. */ - -int -check_newline () -{ - register int c; - register int token; - - lineno++; - - /* Read first nonwhite char on the line. */ - - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - - if (c != '#') - { - /* If not #, return it so caller will use it. */ - return c; - } - - /* Read first nonwhite char after the `#'. */ - - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma', `ident', `define', or `undef'. */ - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (c == 'p') - { - if (getc (finput) == 'r' - && getc (finput) == 'a' - && getc (finput) == 'g' - && getc (finput) == 'm' - && getc (finput) == 'a' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef HANDLE_SYSV_PRAGMA - return handle_sysv_pragma (finput, c); -#endif /* HANDLE_SYSV_PRAGMA */ -#ifdef HANDLE_PRAGMA - HANDLE_PRAGMA (finput); -#endif /* HANDLE_PRAGMA */ - goto skipline; - } - } - - else if (c == 'd') - { - if (getc (finput) == 'e' - && getc (finput) == 'f' - && getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'u') - { - if (getc (finput) == 'n' - && getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'f' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'l') - { - if (getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t')) - goto linenum; - } - else if (c == 'i') - { - if (getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'n' - && getc (finput) == 't' - && ((c = getc (finput)) == ' ' || c == '\t')) - { - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If no argument, ignore the line. */ - if (c == '\n') - return c; - - ungetc (c, finput); - token = yylex (); - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (!flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - - error ("undefined or invalid # directive"); - goto skipline; - } - -linenum: - /* Here we have either `#line' or `# '. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == '\n') - return c; - - /* Something follows the #; read a token. */ - - ungetc (c, finput); - token = yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - int old_lineno = lineno; - int used_up = 0; - /* subtract one, because it is the following line that - gets the specified number */ - - int l = TREE_INT_CST_LOW (yylval.ttype) - 1; - - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - { - /* No more: store the line number and check following line. */ - lineno = l; - return c; - } - ungetc (c, finput); - - /* More follows: it must be a string constant (filename). */ - - /* Read the string constant, but don't treat \ as special. */ - ignore_escape_flag = 1; - token = yylex (); - ignore_escape_flag = 0; - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - input_filename - = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); - strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); - lineno = l; - - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; - - if (main_input_filename == 0) - main_input_filename = input_filename; - - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - { - /* Update the name in the top element of input_file_stack. */ - if (input_file_stack) - input_file_stack->name = input_filename; - - return c; - } - ungetc (c, finput); - - token = yylex (); - used_up = 0; - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - if (TREE_INT_CST_LOW (yylval.ttype) == 1) - { - /* Pushing to a new file. */ - struct file_stack *p - = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ - - used_up = 1; - } - else if (TREE_INT_CST_LOW (yylval.ttype) == 2) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - struct file_stack *p = input_file_stack; - input_file_stack = p->next; - free (p); - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ - } - else - error ("#-lines for entering and leaving files don't match"); - - used_up = 1; - } - } - - /* Now that we've pushed or popped the input stack, - update the name in the top element. */ - if (input_file_stack) - input_file_stack->name = input_filename; - - /* If we have handled a `1' or a `2', - see if there is another number to read. */ - if (used_up) - { - /* Is this the last nonwhite stuff on the line? */ - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n') - return c; - ungetc (c, finput); - - token = yylex (); - used_up = 0; - } - - /* `3' after file name means this is a system header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 3) - in_system_header = 1; - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - if (c == '\n') - return c; - while ((c = getc (finput)) != EOF && c != '\n'); - return c; -} - -#ifdef HANDLE_SYSV_PRAGMA - -/* Handle a #pragma directive. INPUT is the current input stream, - and C is a character to reread. Processes the entire input line - and returns a character for the caller to reread: either \n or EOF. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -int -handle_sysv_pragma (input, c) - FILE *input; - int c; -{ - for (;;) - { - while (c == ' ' || c == '\t') - c = getc (input); - if (c == '\n' || c == EOF) - { - handle_pragma_token (0, 0); - return c; - } - ungetc (c, input); - switch (yylex ()) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - default: - handle_pragma_token (token_buffer, 0); - } - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getc (input); - } -} - -#endif /* HANDLE_SYSV_PRAGMA */ - -#define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9')) -#define isdigit(char) (char >= '0' && char <= '9') -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getc (finput); - register int code; - register unsigned count; - unsigned firstdig; - int nonnull; - - switch (c) - { - case 'x': - if (warn_traditional) - warning ("the meaning of `\\x' varies with -traditional"); - - if (flag_traditional) - return c; - - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getc (finput); - if (!(c >= 'a' && c <= 'f') - && !(c >= 'A' && c <= 'F') - && !(c >= '0' && c <= '9')) - { - ungetc (c, finput); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getc (finput); - } - ungetc (c, finput); - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - if (warn_traditional) - warning ("the meaning of `\\a' varies with -traditional"); - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': -#if 0 /* Vertical tab is present in common usage compilers. */ - if (flag_traditional) - return c; -#endif - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("non-ANSI escape sequence `\\%c'", c); - return c; - } - if (c >= 040 && c < 0177) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -void -yyerror (string) - char *string; -{ - char buf[200]; - - strcpy (buf, string); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - strcat (buf, " at end of input"); - else if (token_buffer[0] == 0) - strcat (buf, " at null character"); - else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); - else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); - else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); - else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); -} - -#if 0 - -struct try_type -{ - tree *node_var; - char unsigned_flag; - char long_flag; - char long_long_flag; -}; - -struct try_type type_sequence[] = -{ - { &integer_type_node, 0, 0, 0}, - { &unsigned_type_node, 1, 0, 0}, - { &long_integer_type_node, 0, 1, 0}, - { &long_unsigned_type_node, 1, 1, 0}, - { &long_long_integer_type_node, 0, 1, 1}, - { &long_long_unsigned_type_node, 1, 1, 1} -}; -#endif /* 0 */ - -int -yylex () -{ - register int c; - register char *p; - register int value; - int wide_flag = 0; - int objc_flag = 0; - - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getc (finput); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getc (finput); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - end_of_file = 1; - token_buffer[0] = 0; - value = ENDFILE; - break; - - case '$': - if (dollars_in_ident) - goto letter; - return '$'; - - case 'L': - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = getc (finput); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - ungetc (c, finput); - } - goto letter; - - case '@': - if (!doing_objc_thang) - { - value = c; - break; - } - else - { - /* '@' may start a constant string object. */ - register int c = getc(finput); - if (c == '"') - { - objc_flag = 1; - goto string_constant; - } - ungetc(c, finput); - /* Fall through to treat '@' as the start of an indentifier. */ - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '_': - letter: - p = token_buffer; - while (isalnum (c) || c == '_' || c == '$' || c == '@') - { - /* Make sure this char really belongs in an identifier. */ - if (c == '@' && ! doing_objc_thang) - break; - if (c == '$' && ! dollars_in_ident) - break; - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getc (finput); - } - - *p = 0; - nextchar = c; - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if (ptr = is_reserved_word (token_buffer, p - token_buffer)) - { - if (ptr->rid) - yylval.ttype = ridpointers[(int) ptr->rid]; - value = (int) ptr->token; - - /* Only return OBJECTNAME if it is a typedef. */ - if (doing_objc_thang && value == OBJECTNAME) - { - lastiddecl = lookup_name(yylval.ttype); - - if (lastiddecl == NULL_TREE - || TREE_CODE (lastiddecl) != TYPE_DECL) - value = IDENTIFIER; - } - - /* Even if we decided to recognize asm, still perhaps warn. */ - if (pedantic - && (value == ASM_KEYWORD || value == TYPEOF - || ptr->rid == RID_INLINE) - && token_buffer[0] != '_') - pedwarn ("ANSI does not permit the keyword `%s'", - token_buffer); - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER) - { - if (token_buffer[0] == '@') - error("invalid identifier `%s'", token_buffer); - - yylval.ttype = get_identifier (token_buffer); - lastiddecl = lookup_name (yylval.ttype); - - if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL) - value = TYPENAME; - /* A user-invisible read-only initialized variable - should be replaced by its value. - We handle only strings since that's the only case used in C. */ - else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL - && DECL_IGNORED_P (lastiddecl) - && TREE_READONLY (lastiddecl) - && DECL_INITIAL (lastiddecl) != 0 - && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST) - { - tree stringval = DECL_INITIAL (lastiddecl); - - /* Copy the string value so that we won't clobber anything - if we put something in the TREE_CHAIN of this one. */ - yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), - TREE_STRING_POINTER (stringval)); - value = STRING; - } - else if (doing_objc_thang) - { - tree objc_interface_decl = is_class_name (yylval.ttype); - - if (objc_interface_decl) - { - value = CLASSNAME; - yylval.ttype = objc_interface_decl; - } - } - } - - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': - { - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - /* for multi-precision arithmetic, - we actually store only HOST_BITS_PER_CHAR bits in each part. - The number of parts is chosen so as to be sufficient to hold - the enough bits to fit into the two HOST_WIDE_INTs that contain - the integer value (this is always at least as many bits as are - in a target `long long' value, but may be wider). */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) - int parts[TOTAL_PARTS]; - int overflow = 0; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = getc (finput)); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = getc (finput)); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (isalnum (c) && c != 'l' && c != 'L' - && c != 'u' && c != 'U' - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) - { - if (c == '.') - { - if (base == 16) - error ("floating constant may not be in radix 16"); - if (floatflag == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - } - else - floatflag = AFTER_POINT; - - base = 10; - *p++ = c = getc (finput); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. - Otherwise, unread the following non-digit - and use the '.' as a structural token. */ - if (p == token_buffer + 2 && !isdigit (c)) - { - if (c == '.') - { - c = getc (finput); - if (c == '.') - { - *p++ = c; - *p = 0; - return ELLIPSIS; - } - error ("parse error at `..'"); - } - ungetc (c, finput); - token_buffer[1] = 0; - value = '.'; - goto done; - } - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (isdigit (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_POINT; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the extra highest-order part ever gets anything in it, - the number is certainly too big. */ - if (parts[TOTAL_PARTS - 1] != 0) - overflow = 1; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = getc (finput)); - } - } - - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the string */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type = double_type_node; - int garbage_chars = 0, exceeds_double = 0; - int imag = 0; - REAL_VALUE_TYPE value; - jmp_buf handler; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((c == 'e') || (c == 'E')) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = getc (finput); - } - if (! isdigit (c)) - error ("floating constant exponent has no digits"); - while (isdigit (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - } - - *p = 0; - errno = 0; - - /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) - { - error ("floating constant out of range"); - value = dconst0; - } - else - { - set_float_handler (handler); - -/* The second argument, machine_mode, of REAL_VALUE_ATOF tells the - desired precision of the binary result of decimal-to-binary conversion. */ - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - type = float_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `float'"); - garbage_chars = -1; - break; - - case 'l': case 'L': - type = long_double_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ( - "floating point number exceeds range of `long double'"); - garbage_chars = -1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - imag = 1; - garbage_chars = -1; - break; - - default: - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `double'"); - } - set_float_handler (NULL_PTR); - } -#ifdef ERANGE - if (errno == ERANGE && !flag_traditional && pedantic) - { - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) - { - pedwarn ("floating point number exceeds range of `double'"); - exceeds_double = 1; - } - } -#endif - /* Note: garbage_chars is -1 if first char is *not* garbage. */ - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - garbage_chars++; - } - if (garbage_chars > 0) - error ("garbage at end of number"); - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - - ungetc (c, finput); - *p = 0; - } - else - { - tree traditional_type, ansi_type, type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int bytes, warn, i; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic) - pedwarn ("ANSI C forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - spec_imag = 1; - } - else - { - if (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - error ("garbage at end of number"); - while (isalnum (c) || c == '.' || c == '_' - || (!flag_traditional && (c == '+' || c == '-') - && (p[-1] == 'e' || p[-1] == 'E'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - } - break; - } - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getc (finput); - } - - ungetc (c, finput); - - /* If the constant is not long long and it won't fit in an - unsigned long, or if the constant is long long and won't fit - in an unsigned long long, then warn that the constant is out - of range. */ - - /* ??? This assumes that long long and long integer types are - a multiple of 8 bits. This better than the original code - though which assumed that long was exactly 32 bits and long - long was exactly 64 bits. */ - - if (spec_long_long) - bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; - else - bytes = TYPE_PRECISION (long_integer_type_node) / 8; - - warn = overflow; - for (i = bytes; i < TOTAL_PARTS; i++) - if (parts[i]) - warn = 1; - if (warn) - pedwarn ("integer constant out of range"); - - /* This is simplified by the fact that our constant - is always positive. */ - - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* If warn_traditional, calculate both the ANSI type and the - traditional type, then see if they disagree. - Otherwise, calculate only the type for the dialect in use. */ - if (warn_traditional || flag_traditional) - { - /* Calculate the traditional type. */ - /* Traditionally, any constant is signed; - but if unsigned is specified explicitly, obey that. - Use the smallest size with the right number of bits, - except for one special case with decimal constants. */ - if (! spec_long && base != 10 - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - /* A decimal constant must be long - if it does not fit in type int. - I think this is independent of whether - the constant is signed. */ - else if (! spec_long && base == 10 - && int_fits_type_p (yylval.ttype, integer_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - else if (! spec_long_long) - traditional_type = (spec_unsigned ? long_unsigned_type_node - : long_integer_type_node); - else - traditional_type = (spec_unsigned - ? long_long_unsigned_type_node - : long_long_integer_type_node); - } - if (warn_traditional || ! flag_traditional) - { - /* Calculate the ANSI type. */ - if (! spec_long && ! spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - ansi_type = integer_type_node; - else if (! spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - ansi_type = unsigned_type_node; - else if (! spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - ansi_type = long_integer_type_node; - else if (! spec_long_long) - ansi_type = long_unsigned_type_node; - else if (! spec_unsigned - /* Verify value does not overflow into sign bit. */ - && TREE_INT_CST_HIGH (yylval.ttype) >= 0 - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - ansi_type = long_long_integer_type_node; - else - ansi_type = long_long_unsigned_type_node; - } - - type = flag_traditional ? traditional_type : ansi_type; - - if (warn_traditional && traditional_type != ansi_type) - { - if (TYPE_PRECISION (traditional_type) - != TYPE_PRECISION (ansi_type)) - warning ("width of integer constant changes with -traditional"); - else if (TREE_UNSIGNED (traditional_type) - != TREE_UNSIGNED (ansi_type)) - warning ("integer constant is unsigned in ANSI C, signed with -traditional"); - else - warning ("width of integer constant may change on other systems with -traditional"); - } - - if (!flag_traditional && !int_fits_type_p (yylval.ttype, type) - && !warn) - pedwarn ("integer constant out of range"); - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (integer_zero_node, - convert (integer_type_node, yylval.ttype)); - else - error ("complex integer constant is too wide for `complex int'"); - } - else if (flag_traditional && !int_fits_type_p (yylval.ttype, type)) - /* The traditional constant 0x80000000 is signed - but doesn't fit in the range of int. - This will change it to -0x80000000, which does fit. */ - { - TREE_TYPE (yylval.ttype) = unsigned_type (type); - yylval.ttype = convert (type, yylval.ttype); - } - else - TREE_TYPE (yylval.ttype) = type; - - *p = 0; - } - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; - - if (wide_flag) - { - width = WCHAR_TYPE_SIZE; -#ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; -#endif - } - else - max_chars = TYPE_PRECISION (integer_type_node) / width; - - while (1) - { - tryagain: - - c = getc (finput); - - if (c == '\'' || c == EOF) - break; - - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (isprint (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in character constant"); - lineno++; - } -#ifdef MAP_CHARACTER - else - c = MAP_CHARACTER (c); -#endif - - num_chars++; - if (num_chars > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[num_chars] = c; - - /* Merge character into result; ignore excess chars. */ - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } - } - - token_buffer[num_chars + 1] = '\''; - token_buffer[num_chars + 2] = 0; - - if (c != '\'') - error ("malformatted character constant"); - else if (num_chars == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (num_chars != 1 && ! flag_traditional) - warning ("multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (num_bits == 0) - /* We already got an error; avoid invalid shift. */ - yylval.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[1] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) - result = wc; - else - warning ("Ignoring invalid multibyte character"); - } -#endif - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - c = getc (finput); - p = token_buffer + 1; - - while (c != '"' && c >= 0) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && c >= (1 << TYPE_PRECISION (char_type_node))) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in string constant"); - lineno++; - } - - if (p == token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - - skipnewline: - c = getc (finput); - } - *p = 0; - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - if (wide_flag) - { - /* If this is a L"..." wide-string, convert the multibyte string - to a wide character string. */ - char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); - int len; - -#ifdef MULTIBYTE_CHARS - len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); - if (len < 0 || len >= (p - token_buffer)) - { - warning ("Ignoring invalid multibyte string"); - len = 0; - } - bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); -#else - { - union { long l; char c[sizeof (long)]; } u; - int big_endian; - char *wp, *cp; - - /* Determine whether host is little or big endian. */ - u.l = 1; - big_endian = u.c[sizeof (long) - 1]; - wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0); - - bzero (widep, (p - token_buffer) * WCHAR_BYTES); - for (cp = token_buffer + 1; cp < p; cp++) - *wp = *cp, wp += WCHAR_BYTES; - len = p - token_buffer - 1; - } -#endif - yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - value = STRING; - } - else if (objc_flag) - { - extern tree build_objc_string(); - /* Return an Objective-C @"..." constant string object. */ - yylval.ttype = build_objc_string (p - token_buffer, - token_buffer + 1); - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = OBJC_STRING; - } - else - { - yylval.ttype = build_string (p - token_buffer, token_buffer + 1); - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = STRING; - } - - *p++ = '"'; - *p = 0; - - break; - } - - case '+': - case '-': - case '&': - case '|': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = getc (finput); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else if ((c == '-') && (c1 == '>')) - { value = POINTSAT; goto done; } - ungetc (c1, finput); - token_buffer[1] = 0; - - if ((c == '<') || (c == '>')) - value = ARITHCOMPARE; - else value = c; - goto done; - } - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - default: - value = c; - } - -done: -/* yylloc.last_line = lineno; */ - - return value; -} - -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - -void -set_yydebug (value) - int value; -{ -#if YYDEBUG != 0 - yydebug = value; -#else - warning ("YYDEBUG not defined."); -#endif -} diff --git a/gnu/usr.bin/gcc2/cc1/c-parse.c b/gnu/usr.bin/gcc2/cc1/c-parse.c deleted file mode 100644 index 35ec2652649..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-parse.c +++ /dev/null @@ -1,3439 +0,0 @@ - -/* A Bison parser, made from c-parse.y */ - -#ifndef lint -static char rcsid[] = "$Id: c-parse.c,v 1.1.1.1 1995/10/18 08:39:28 deraadt Exp $"; -#endif /* not lint */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define IDENTIFIER 258 -#define TYPENAME 259 -#define SCSPEC 260 -#define TYPESPEC 261 -#define TYPE_QUAL 262 -#define CONSTANT 263 -#define STRING 264 -#define ELLIPSIS 265 -#define SIZEOF 266 -#define ENUM 267 -#define STRUCT 268 -#define UNION 269 -#define IF 270 -#define ELSE 271 -#define WHILE 272 -#define DO 273 -#define FOR 274 -#define SWITCH 275 -#define CASE 276 -#define DEFAULT 277 -#define BREAK 278 -#define CONTINUE 279 -#define RETURN 280 -#define GOTO 281 -#define ASM_KEYWORD 282 -#define TYPEOF 283 -#define ALIGNOF 284 -#define ALIGN 285 -#define ATTRIBUTE 286 -#define EXTENSION 287 -#define LABEL 288 -#define REALPART 289 -#define IMAGPART 290 -#define ASSIGN 291 -#define OROR 292 -#define ANDAND 293 -#define EQCOMPARE 294 -#define ARITHCOMPARE 295 -#define LSHIFT 296 -#define RSHIFT 297 -#define UNARY 298 -#define PLUSPLUS 299 -#define MINUSMINUS 300 -#define HYPERUNARY 301 -#define POINTSAT 302 -#define INTERFACE 303 -#define IMPLEMENTATION 304 -#define END 305 -#define SELECTOR 306 -#define DEFS 307 -#define ENCODE 308 -#define CLASSNAME 309 -#define PUBLIC 310 -#define PRIVATE 311 -#define PROTECTED 312 -#define PROTOCOL 313 -#define OBJECTNAME 314 -#define CLASS 315 -#define ALIAS 316 -#define OBJC_STRING 317 - -#line 44 "c-parse.y" - -#include -#include -#include - -#include "config.h" -#include "tree.h" -#include "input.h" -#include "c-lex.h" -#include "c-tree.h" -#include "flags.h" - -#ifdef MULTIBYTE_CHARS -#include -#include -#endif - - -/* Since parsers are distinct for each language, put the language string - definition here. */ -char *language_string = "GNU C"; - -#ifndef errno -extern int errno; -#endif - -void yyerror (); - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#line 81 "c-parse.y" -typedef union {long itype; tree ttype; enum tree_code code; - char *filename; int lineno; } YYSTYPE; -#line 192 "c-parse.y" - -/* Number of statements (loosely speaking) seen so far. */ -static int stmt_count; - -/* Input file and line number of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static char *if_stmt_file; -static int if_stmt_line; - -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* Stack of saved values of current_declspecs. */ -static tree declspec_stack; - -/* 1 if we explained undeclared var errors. */ -static int undeclared_variable_notice; - - -/* Tell yyparse how to print a token's value, if yydebug is set. */ - -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint (); - -#ifndef YYLTYPE -typedef - struct yyltype - { - int timestamp; - int first_line; - int first_column; - int last_line; - int last_column; - char *text; - } - yyltype; - -#define YYLTYPE yyltype -#endif - -#include - -#ifndef __STDC__ -#define const -#endif - - - -#define YYFINAL 613 -#define YYFLAG -32768 -#define YYNTBASE 85 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 317 ? yytranslate[x] : 212) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 81, 2, 2, 2, 53, 44, 2, 60, - 77, 51, 49, 82, 50, 59, 52, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 39, 78, 2, - 37, 2, 38, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 61, 2, 84, 43, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 83, 42, 79, 80, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 40, 41, 45, 46, 47, 48, 54, 55, 56, - 57, 58, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76 -}; - -static const short yyprhs[] = { 0, - 0, 1, 3, 4, 7, 8, 12, 14, 16, 22, - 26, 31, 36, 39, 42, 45, 48, 50, 51, 52, - 60, 65, 66, 67, 75, 80, 81, 82, 89, 93, - 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, - 114, 116, 118, 122, 124, 127, 128, 132, 135, 138, - 141, 146, 149, 154, 157, 160, 162, 167, 175, 177, - 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, - 221, 225, 229, 233, 239, 243, 247, 249, 251, 253, - 257, 261, 262, 267, 272, 277, 281, 285, 288, 291, - 293, 296, 297, 299, 302, 306, 308, 310, 313, 316, - 321, 326, 329, 332, 336, 338, 340, 343, 346, 347, - 352, 357, 361, 365, 368, 371, 374, 378, 379, 382, - 385, 387, 389, 392, 395, 398, 402, 403, 406, 408, - 410, 412, 417, 422, 424, 426, 428, 430, 434, 436, - 440, 441, 446, 447, 454, 458, 459, 466, 470, 471, - 478, 480, 484, 486, 491, 496, 505, 507, 510, 514, - 519, 521, 523, 527, 534, 543, 548, 555, 559, 565, - 566, 570, 571, 575, 577, 579, 583, 587, 592, 596, - 600, 602, 606, 611, 615, 619, 621, 625, 629, 633, - 638, 642, 644, 645, 652, 657, 660, 661, 668, 673, - 676, 677, 685, 686, 693, 696, 697, 699, 700, 702, - 704, 707, 708, 712, 715, 719, 721, 725, 727, 729, - 731, 735, 740, 747, 753, 755, 759, 761, 765, 768, - 771, 772, 774, 776, 779, 780, 783, 787, 791, 794, - 798, 803, 807, 810, 814, 817, 819, 822, 825, 826, - 828, 831, 832, 833, 835, 837, 840, 844, 846, 849, - 852, 859, 865, 871, 874, 877, 882, 883, 888, 889, - 890, 894, 899, 903, 905, 907, 909, 911, 914, 915, - 920, 922, 926, 927, 928, 936, 942, 945, 946, 947, - 948, 961, 962, 969, 972, 975, 978, 982, 989, 998, - 1009, 1022, 1026, 1031, 1033, 1035, 1036, 1043, 1047, 1053, - 1056, 1059, 1060, 1062, 1063, 1065, 1066, 1068, 1070, 1074, - 1079, 1081, 1085, 1086, 1089, 1092, 1093, 1098, 1101, 1102, - 1104, 1106, 1110, 1112, 1116, 1119, 1122, 1125, 1128, 1131, - 1132, 1135, 1137, 1140, 1142, 1146, 1148 -}; - -static const short yyrhs[] = { -1, - 86, 0, 0, 87, 89, 0, 0, 86, 88, 89, - 0, 91, 0, 90, 0, 27, 60, 100, 77, 78, - 0, 116, 126, 78, 0, 120, 116, 126, 78, 0, - 118, 116, 125, 78, 0, 120, 78, 0, 118, 78, - 0, 1, 78, 0, 1, 79, 0, 78, 0, 0, - 0, 118, 116, 141, 92, 110, 93, 171, 0, 118, - 116, 141, 1, 0, 0, 0, 120, 116, 144, 94, - 110, 95, 171, 0, 120, 116, 144, 1, 0, 0, - 0, 116, 144, 96, 110, 97, 171, 0, 116, 144, - 1, 0, 3, 0, 4, 0, 44, 0, 50, 0, - 49, 0, 55, 0, 56, 0, 80, 0, 81, 0, - 102, 0, 0, 102, 0, 106, 0, 102, 82, 106, - 0, 107, 0, 51, 105, 0, 0, 32, 104, 105, - 0, 99, 105, 0, 41, 98, 0, 11, 103, 0, - 11, 60, 159, 77, 0, 29, 103, 0, 29, 60, - 159, 77, 0, 34, 105, 0, 35, 105, 0, 103, - 0, 60, 159, 77, 105, 0, 60, 159, 77, 83, - 136, 150, 79, 0, 105, 0, 106, 49, 106, 0, - 106, 50, 106, 0, 106, 51, 106, 0, 106, 52, - 106, 0, 106, 53, 106, 0, 106, 47, 106, 0, - 106, 48, 106, 0, 106, 46, 106, 0, 106, 45, - 106, 0, 106, 44, 106, 0, 106, 42, 106, 0, - 106, 43, 106, 0, 106, 41, 106, 0, 106, 40, - 106, 0, 106, 38, 195, 39, 106, 0, 106, 37, - 106, 0, 106, 36, 106, 0, 3, 0, 8, 0, - 109, 0, 60, 100, 77, 0, 60, 1, 77, 0, - 0, 60, 108, 172, 77, 0, 107, 60, 101, 77, - 0, 107, 61, 100, 84, 0, 107, 59, 98, 0, - 107, 58, 98, 0, 107, 55, 0, 107, 56, 0, - 9, 0, 109, 9, 0, 0, 112, 0, 112, 10, - 0, 177, 178, 113, 0, 111, 0, 166, 0, 112, - 111, 0, 111, 166, 0, 118, 116, 125, 78, 0, - 120, 116, 126, 78, 0, 118, 78, 0, 120, 78, - 0, 177, 178, 117, 0, 114, 0, 166, 0, 115, - 114, 0, 114, 166, 0, 0, 118, 116, 125, 78, - 0, 120, 116, 126, 78, 0, 118, 116, 137, 0, - 120, 116, 139, 0, 118, 78, 0, 120, 78, 0, - 123, 119, 0, 120, 123, 119, 0, 0, 119, 124, - 0, 119, 5, 0, 7, 0, 5, 0, 120, 7, - 0, 120, 5, 0, 123, 122, 0, 161, 123, 122, - 0, 0, 122, 124, 0, 6, 0, 145, 0, 4, - 0, 28, 60, 100, 77, 0, 28, 60, 159, 77, - 0, 6, 0, 7, 0, 145, 0, 128, 0, 125, - 82, 128, 0, 130, 0, 126, 82, 128, 0, 0, - 27, 60, 109, 77, 0, 0, 141, 127, 132, 37, - 129, 135, 0, 141, 127, 132, 0, 0, 144, 127, - 132, 37, 131, 135, 0, 144, 127, 132, 0, 0, - 31, 60, 60, 133, 77, 77, 0, 134, 0, 133, - 82, 134, 0, 3, 0, 3, 60, 3, 77, 0, - 3, 60, 8, 77, 0, 3, 60, 3, 82, 8, - 82, 8, 77, 0, 106, 0, 83, 79, 0, 83, - 136, 79, 0, 83, 136, 82, 79, 0, 1, 0, - 135, 0, 136, 82, 135, 0, 61, 106, 10, 106, - 84, 135, 0, 136, 82, 61, 106, 10, 106, 84, - 135, 0, 61, 106, 84, 135, 0, 136, 82, 61, - 106, 84, 135, 0, 98, 39, 135, 0, 136, 82, - 98, 39, 135, 0, 0, 141, 138, 172, 0, 0, - 144, 140, 172, 0, 142, 0, 144, 0, 60, 142, - 77, 0, 142, 60, 207, 0, 142, 61, 100, 84, - 0, 142, 61, 84, 0, 51, 162, 142, 0, 4, - 0, 143, 60, 207, 0, 143, 61, 100, 84, 0, - 143, 61, 84, 0, 51, 162, 143, 0, 4, 0, - 144, 60, 207, 0, 60, 144, 77, 0, 51, 162, - 144, 0, 144, 61, 100, 84, 0, 144, 61, 84, - 0, 3, 0, 0, 13, 98, 83, 146, 152, 79, - 0, 13, 83, 152, 79, 0, 13, 98, 0, 0, - 14, 98, 83, 147, 152, 79, 0, 14, 83, 152, - 79, 0, 14, 98, 0, 0, 12, 98, 83, 148, - 157, 151, 79, 0, 0, 12, 83, 149, 157, 151, - 79, 0, 12, 98, 0, 0, 82, 0, 0, 82, - 0, 153, 0, 153, 154, 0, 0, 153, 154, 78, - 0, 153, 78, 0, 121, 116, 155, 0, 121, 0, - 161, 116, 155, 0, 161, 0, 1, 0, 156, 0, - 155, 82, 156, 0, 177, 178, 141, 132, 0, 177, - 178, 141, 39, 106, 132, 0, 177, 178, 39, 106, - 132, 0, 158, 0, 157, 82, 158, 0, 98, 0, - 98, 37, 106, 0, 121, 160, 0, 161, 160, 0, - 0, 163, 0, 7, 0, 161, 7, 0, 0, 162, - 7, 0, 60, 163, 77, 0, 51, 162, 163, 0, - 51, 162, 0, 163, 60, 200, 0, 163, 61, 100, - 84, 0, 163, 61, 84, 0, 60, 200, 0, 61, - 100, 84, 0, 61, 84, 0, 180, 0, 164, 180, - 0, 164, 166, 0, 0, 164, 0, 1, 78, 0, - 0, 0, 169, 0, 170, 0, 169, 170, 0, 33, - 211, 78, 0, 172, 0, 1, 172, 0, 83, 79, - 0, 83, 167, 168, 115, 165, 79, 0, 83, 167, - 168, 1, 79, 0, 83, 167, 168, 164, 79, 0, - 174, 179, 0, 174, 1, 0, 15, 60, 100, 77, - 0, 0, 18, 176, 179, 17, 0, 0, 0, 177, - 178, 182, 0, 177, 178, 193, 179, 0, 177, 178, - 181, 0, 182, 0, 193, 0, 172, 0, 190, 0, - 100, 78, 0, 0, 173, 16, 183, 179, 0, 173, - 0, 173, 16, 1, 0, 0, 0, 17, 184, 60, - 100, 77, 185, 179, 0, 175, 60, 100, 77, 78, - 0, 175, 1, 0, 0, 0, 0, 19, 60, 195, - 78, 186, 195, 78, 187, 195, 77, 188, 179, 0, - 0, 20, 60, 100, 77, 189, 179, 0, 23, 78, - 0, 24, 78, 0, 25, 78, 0, 25, 100, 78, - 0, 27, 194, 60, 100, 77, 78, 0, 27, 194, - 60, 100, 39, 196, 77, 78, 0, 27, 194, 60, - 100, 39, 196, 39, 196, 77, 78, 0, 27, 194, - 60, 100, 39, 196, 39, 196, 39, 199, 77, 78, - 0, 26, 98, 78, 0, 26, 51, 100, 78, 0, - 78, 0, 191, 0, 0, 19, 60, 107, 77, 192, - 179, 0, 21, 106, 39, 0, 21, 106, 10, 106, - 39, 0, 22, 39, 0, 98, 39, 0, 0, 7, - 0, 0, 100, 0, 0, 197, 0, 198, 0, 197, - 82, 198, 0, 9, 60, 100, 77, 0, 109, 0, - 199, 82, 109, 0, 0, 201, 202, 0, 204, 77, - 0, 0, 205, 78, 203, 202, 0, 1, 77, 0, - 0, 10, 0, 205, 0, 205, 82, 10, 0, 206, - 0, 205, 82, 206, 0, 118, 143, 0, 118, 144, - 0, 118, 160, 0, 120, 144, 0, 120, 160, 0, - 0, 208, 209, 0, 202, 0, 210, 77, 0, 3, - 0, 210, 82, 3, 0, 98, 0, 211, 82, 98, - 0 -}; - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 218, 222, 235, 237, 237, 238, 240, 242, 243, 253, - 259, 261, 263, 265, 267, 268, 269, 274, 280, 282, - 283, 285, 290, 292, 293, 295, 300, 302, 303, 307, - 309, 312, 314, 316, 318, 320, 322, 324, 328, 332, - 335, 338, 341, 345, 347, 350, 353, 356, 360, 386, - 391, 393, 395, 397, 399, 403, 405, 408, 433, 435, - 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, - 457, 459, 461, 463, 465, 468, 474, 575, 576, 578, - 584, 586, 600, 618, 620, 622, 626, 632, 634, 639, - 641, 646, 648, 649, 659, 664, 666, 667, 668, 671, - 676, 680, 683, 691, 696, 698, 699, 700, 707, 715, - 720, 724, 728, 732, 734, 742, 745, 749, 751, 753, - 764, 768, 770, 773, 786, 789, 793, 795, 803, 804, - 805, 809, 811, 817, 818, 819, 822, 824, 827, 829, - 832, 835, 841, 846, 848, 854, 859, 861, 868, 871, - 876, 878, 883, 888, 898, 909, 927, 929, 933, 935, - 937, 943, 946, 951, 955, 960, 962, 964, 966, 970, - 987, 991, 1008, 1015, 1017, 1022, 1025, 1030, 1032, 1034, - 1036, 1044, 1050, 1052, 1054, 1056, 1062, 1068, 1070, 1072, - 1074, 1076, 1079, 1084, 1088, 1091, 1093, 1095, 1097, 1100, - 1102, 1105, 1108, 1111, 1114, 1118, 1120, 1123, 1125, 1129, - 1132, 1137, 1139, 1141, 1155, 1161, 1166, 1171, 1176, 1180, - 1182, 1186, 1190, 1194, 1204, 1206, 1211, 1214, 1218, 1221, - 1225, 1228, 1231, 1234, 1238, 1241, 1245, 1249, 1251, 1253, - 1255, 1257, 1259, 1261, 1263, 1271, 1273, 1274, 1277, 1279, - 1282, 1285, 1296, 1298, 1303, 1305, 1308, 1322, 1325, 1328, - 1330, 1335, 1340, 1348, 1353, 1356, 1369, 1377, 1381, 1385, - 1389, 1395, 1399, 1404, 1406, 1417, 1420, 1421, 1426, 1431, - 1434, 1442, 1444, 1454, 1464, 1465, 1473, 1476, 1488, 1492, - 1509, 1516, 1525, 1527, 1532, 1537, 1541, 1545, 1556, 1563, - 1570, 1577, 1588, 1592, 1595, 1600, 1623, 1654, 1678, 1706, - 1721, 1732, 1735, 1739, 1742, 1747, 1749, 1752, 1754, 1758, - 1763, 1766, 1772, 1777, 1782, 1784, 1793, 1794, 1800, 1802, - 1807, 1809, 1813, 1816, 1822, 1825, 1827, 1829, 1831, 1838, - 1843, 1848, 1850, 1859, 1862, 1867, 1870 -}; - -static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", -"TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", -"ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", -"BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ALIGN", -"ATTRIBUTE","EXTENSION","LABEL","REALPART","IMAGPART","ASSIGN","'='","'?'","':'", -"OROR","ANDAND","'|'","'^'","'&'","EQCOMPARE","ARITHCOMPARE","LSHIFT","RSHIFT", -"'+'","'-'","'*'","'/'","'%'","UNARY","PLUSPLUS","MINUSMINUS","HYPERUNARY","POINTSAT", -"'.'","'('","'['","INTERFACE","IMPLEMENTATION","END","SELECTOR","DEFS","ENCODE", -"CLASSNAME","PUBLIC","PRIVATE","PROTECTED","PROTOCOL","OBJECTNAME","CLASS","ALIAS", -"OBJC_STRING","')'","';'","'}'","'~'","'!'","','","'{'","']'","program","extdefs", -"@1","@2","extdef","datadef","fndef","@3","@4","@5","@6","@7","@8","identifier", -"unop","expr","exprlist","nonnull_exprlist","unary_expr","@9","cast_expr","expr_no_commas", -"primary","@10","string","xdecls","lineno_datadecl","datadecls","datadecl","lineno_decl", -"decls","setspecs","decl","typed_declspecs","reserved_declspecs","declmods", -"typed_typespecs","reserved_typespecquals","typespec","typespecqual_reserved", -"initdecls","notype_initdecls","maybeasm","initdcl","@11","notype_initdcl","@12", -"maybe_attribute","attribute_list","attrib","init","initlist","nested_function", -"@13","notype_nested_function","@14","declarator","after_type_declarator","parm_declarator", -"notype_declarator","structsp","@15","@16","@17","@18","maybecomma","maybecomma_warn", -"component_decl_list","component_decl_list2","component_decl","components","component_declarator", -"enumlist","enumerator","typename","absdcl","nonempty_type_quals","type_quals", -"absdcl1","stmts","xstmts","errstmt","pushlevel","maybe_label_decls","label_decls", -"label_decl","compstmt_or_error","compstmt","simple_if","if_prefix","do_stmt_start", -"@19","save_filename","save_lineno","lineno_labeled_stmt","lineno_stmt_or_label", -"stmt_or_label","stmt","@20","@21","@22","@23","@24","@25","@26","all_iter_stmt", -"all_iter_stmt_simple","@27","label","maybe_type_qual","xexpr","asm_operands", -"nonnull_asm_operands","asm_operand","asm_clobbers","parmlist","@28","parmlist_1", -"@29","parmlist_2","parms","parm","parmlist_or_identifiers","@30","parmlist_or_identifiers_1", -"identifiers","identifiers_or_typenames","" -}; -#endif - -static const short yyr1[] = { 0, - 85, 85, 87, 86, 88, 86, 89, 89, 89, 90, - 90, 90, 90, 90, 90, 90, 90, 92, 93, 91, - 91, 94, 95, 91, 91, 96, 97, 91, 91, 98, - 98, 99, 99, 99, 99, 99, 99, 99, 100, 101, - 101, 102, 102, 103, 103, 104, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 105, 105, 105, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, - 107, 108, 107, 107, 107, 107, 107, 107, 107, 109, - 109, 110, 110, 110, 111, 112, 112, 112, 112, 113, - 113, 113, 113, 114, 115, 115, 115, 115, 116, 117, - 117, 117, 117, 117, 117, 118, 118, 119, 119, 119, - 120, 120, 120, 120, 121, 121, 122, 122, 123, 123, - 123, 123, 123, 124, 124, 124, 125, 125, 126, 126, - 127, 127, 129, 128, 128, 131, 130, 130, 132, 132, - 133, 133, 134, 134, 134, 134, 135, 135, 135, 135, - 135, 136, 136, 136, 136, 136, 136, 136, 136, 138, - 137, 140, 139, 141, 141, 142, 142, 142, 142, 142, - 142, 143, 143, 143, 143, 143, 144, 144, 144, 144, - 144, 144, 146, 145, 145, 145, 147, 145, 145, 145, - 148, 145, 149, 145, 145, 150, 150, 151, 151, 152, - 152, 153, 153, 153, 154, 154, 154, 154, 154, 155, - 155, 156, 156, 156, 157, 157, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 164, 164, 164, 165, 165, - 166, 167, 168, 168, 169, 169, 170, 171, 171, 172, - 172, 172, 172, 173, 173, 174, 176, 175, 177, 178, - 179, 179, 180, 181, 181, 182, 182, 182, 183, 182, - 182, 182, 184, 185, 182, 182, 182, 186, 187, 188, - 182, 189, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 182, 190, 192, 191, 193, 193, 193, - 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, - 199, 199, 201, 200, 202, 203, 202, 202, 204, 204, - 204, 204, 205, 205, 206, 206, 206, 206, 206, 208, - 207, 209, 209, 210, 210, 211, 211 -}; - -static const short yyr2[] = { 0, - 0, 1, 0, 2, 0, 3, 1, 1, 5, 3, - 4, 4, 2, 2, 2, 2, 1, 0, 0, 7, - 4, 0, 0, 7, 4, 0, 0, 6, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 3, 1, 2, 0, 3, 2, 2, 2, - 4, 2, 4, 2, 2, 1, 4, 7, 1, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 5, 3, 3, 1, 1, 1, 3, - 3, 0, 4, 4, 4, 3, 3, 2, 2, 1, - 2, 0, 1, 2, 3, 1, 1, 2, 2, 4, - 4, 2, 2, 3, 1, 1, 2, 2, 0, 4, - 4, 3, 3, 2, 2, 2, 3, 0, 2, 2, - 1, 1, 2, 2, 2, 3, 0, 2, 1, 1, - 1, 4, 4, 1, 1, 1, 1, 3, 1, 3, - 0, 4, 0, 6, 3, 0, 6, 3, 0, 6, - 1, 3, 1, 4, 4, 8, 1, 2, 3, 4, - 1, 1, 3, 6, 8, 4, 6, 3, 5, 0, - 3, 0, 3, 1, 1, 3, 3, 4, 3, 3, - 1, 3, 4, 3, 3, 1, 3, 3, 3, 4, - 3, 1, 0, 6, 4, 2, 0, 6, 4, 2, - 0, 7, 0, 6, 2, 0, 1, 0, 1, 1, - 2, 0, 3, 2, 3, 1, 3, 1, 1, 1, - 3, 4, 6, 5, 1, 3, 1, 3, 2, 2, - 0, 1, 1, 2, 0, 2, 3, 3, 2, 3, - 4, 3, 2, 3, 2, 1, 2, 2, 0, 1, - 2, 0, 0, 1, 1, 2, 3, 1, 2, 2, - 6, 5, 5, 2, 2, 4, 0, 4, 0, 0, - 3, 4, 3, 1, 1, 1, 1, 2, 0, 4, - 1, 3, 0, 0, 7, 5, 2, 0, 0, 0, - 12, 0, 6, 2, 2, 2, 3, 6, 8, 10, - 12, 3, 4, 1, 1, 0, 6, 3, 5, 2, - 2, 0, 1, 0, 1, 0, 1, 1, 3, 4, - 1, 3, 0, 2, 2, 0, 4, 2, 0, 1, - 1, 3, 1, 3, 2, 2, 2, 2, 2, 0, - 2, 1, 2, 1, 3, 1, 3 -}; - -static const short yydefact[] = { 3, - 5, 0, 0, 0, 131, 122, 129, 121, 0, 0, - 0, 0, 0, 17, 4, 8, 7, 0, 109, 109, - 118, 130, 6, 15, 16, 30, 31, 203, 205, 212, - 196, 212, 200, 0, 0, 192, 235, 0, 0, 139, - 0, 14, 0, 124, 123, 13, 0, 118, 116, 0, - 201, 0, 0, 193, 0, 197, 77, 78, 90, 0, - 0, 46, 0, 0, 0, 32, 34, 33, 0, 35, - 36, 0, 37, 38, 0, 0, 39, 56, 59, 42, - 44, 79, 233, 0, 231, 127, 0, 231, 0, 0, - 10, 0, 29, 0, 340, 0, 0, 149, 181, 235, - 0, 0, 137, 0, 174, 175, 0, 0, 117, 120, - 134, 135, 119, 136, 227, 208, 225, 0, 195, 219, - 214, 109, 211, 109, 212, 199, 212, 0, 50, 0, - 52, 0, 54, 55, 49, 45, 0, 0, 0, 0, - 48, 0, 0, 0, 0, 314, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 88, 89, 0, 0, 40, 0, 91, 132, 235, 323, - 0, 229, 232, 125, 133, 234, 127, 230, 236, 189, - 188, 140, 141, 0, 187, 0, 191, 0, 0, 27, - 0, 269, 97, 270, 0, 148, 0, 0, 12, 0, - 21, 0, 149, 340, 0, 11, 25, 0, 0, 209, - 0, 208, 269, 213, 269, 0, 0, 0, 0, 47, - 81, 80, 252, 0, 0, 9, 43, 76, 75, 315, - 0, 73, 72, 70, 71, 69, 68, 67, 65, 66, - 60, 61, 62, 63, 64, 87, 86, 0, 41, 0, - 239, 0, 243, 0, 245, 0, 323, 0, 128, 126, - 0, 0, 344, 330, 231, 231, 342, 0, 331, 333, - 341, 0, 190, 251, 0, 99, 94, 98, 0, 0, - 146, 180, 176, 138, 19, 145, 177, 179, 0, 23, - 228, 226, 204, 0, 215, 220, 270, 217, 194, 198, - 51, 53, 260, 253, 83, 0, 57, 0, 84, 85, - 238, 237, 324, 244, 240, 242, 0, 142, 328, 186, - 235, 323, 335, 336, 337, 235, 338, 339, 325, 326, - 0, 343, 0, 0, 28, 258, 95, 109, 109, 0, - 0, 0, 143, 178, 0, 202, 269, 0, 0, 0, - 254, 255, 161, 77, 0, 0, 0, 157, 162, 206, - 74, 241, 239, 340, 0, 239, 0, 332, 334, 345, - 259, 102, 0, 103, 0, 153, 0, 151, 147, 20, - 0, 24, 221, 0, 149, 346, 0, 0, 0, 269, - 0, 106, 270, 246, 256, 0, 158, 0, 0, 0, - 0, 185, 182, 184, 0, 327, 0, 0, 141, 0, - 0, 0, 144, 149, 0, 222, 257, 0, 262, 108, - 107, 0, 0, 263, 248, 270, 247, 0, 0, 0, - 159, 0, 168, 0, 0, 163, 58, 183, 100, 101, - 0, 0, 150, 152, 224, 149, 347, 261, 0, 131, - 0, 283, 267, 0, 0, 0, 0, 0, 0, 0, - 0, 312, 304, 0, 0, 104, 109, 109, 276, 281, - 0, 0, 273, 274, 277, 305, 275, 0, 166, 160, - 0, 0, 154, 0, 155, 223, 0, 0, 269, 314, - 0, 0, 310, 294, 295, 296, 0, 0, 0, 313, - 0, 311, 278, 114, 0, 115, 0, 0, 265, 270, - 264, 287, 0, 0, 0, 0, 169, 0, 0, 0, - 0, 44, 0, 0, 0, 308, 297, 0, 302, 0, - 0, 112, 141, 0, 113, 141, 282, 269, 0, 0, - 164, 0, 167, 0, 266, 0, 268, 306, 288, 292, - 0, 303, 0, 110, 0, 111, 0, 280, 271, 269, - 0, 0, 0, 284, 269, 314, 269, 309, 316, 0, - 171, 173, 272, 286, 165, 156, 269, 307, 0, 293, - 0, 0, 317, 318, 298, 285, 289, 0, 316, 0, - 0, 314, 0, 0, 299, 319, 0, 320, 0, 0, - 290, 321, 0, 300, 269, 0, 0, 291, 301, 322, - 0, 0, 0 -}; - -static const short yydefgoto[] = { 611, - 1, 2, 3, 15, 16, 17, 202, 342, 208, 345, - 97, 275, 115, 75, 230, 248, 77, 78, 132, 79, - 80, 81, 139, 82, 190, 191, 192, 337, 389, 390, - 18, 466, 265, 49, 266, 85, 174, 21, 113, 102, - 39, 98, 103, 381, 40, 341, 196, 377, 378, 359, - 360, 532, 555, 535, 557, 183, 105, 323, 106, 22, - 125, 127, 118, 50, 401, 211, 52, 53, 123, 295, - 296, 116, 117, 87, 172, 88, 89, 173, 391, 423, - 193, 304, 350, 351, 352, 335, 336, 470, 471, 472, - 489, 510, 279, 511, 394, 473, 474, 538, 488, 577, - 566, 592, 605, 567, 475, 476, 565, 477, 501, 231, - 582, 583, 584, 603, 253, 254, 267, 367, 268, 269, - 270, 185, 186, 271, 272, 387 -}; - -static const short yypact[] = { 49, - 95, 710, 710, 262,-32768,-32768,-32768,-32768, 64, 66, - 70, 60, 86,-32768,-32768,-32768,-32768, 33, -36, 332, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 65,-32768, - 79,-32768, 128, 1837, 1753,-32768,-32768, 33, 94,-32768, - 391,-32768, 444,-32768,-32768,-32768, 33,-32768, 312, 68, --32768, 141, 154,-32768, 144,-32768,-32768,-32768,-32768, 1850, - 1900,-32768, 1837, 1837, 68,-32768,-32768,-32768, 1837,-32768, --32768, 1032,-32768,-32768, 1837, 165, 169,-32768,-32768, 2059, - 637, 247,-32768, 188, 187,-32768, 191, 951, 356, 0, --32768, 444,-32768, 211,-32768, 1379, 529, 245,-32768,-32768, - 444, 153,-32768, 273, 297, 308, 176, 486, 312,-32768, --32768,-32768,-32768,-32768, 244, 202,-32768, 68,-32768,-32768, --32768, 311, 224, 215,-32768,-32768,-32768, 1032,-32768, 1032, --32768, 1837,-32768,-32768,-32768,-32768, 228, 231, 251, 243, --32768, 265, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, --32768,-32768, 68, 68, 1837, 1837,-32768,-32768,-32768, 187, - 1392,-32768, 352, 538,-32768,-32768,-32768,-32768,-32768, 308, --32768,-32768, 321, 362,-32768, 632,-32768, 307, 322,-32768, - 360, 42,-32768,-32768, 346, 377, 263, 4,-32768, 444, --32768, 529, 245,-32768, 1446,-32768,-32768, 529, 1837, 68, - 341, 202,-32768,-32768,-32768, 344, 350, 354, 357,-32768, --32768,-32768, 376, 373, 1695,-32768, 2059, 2059, 2059,-32768, - 400, 2072, 1299, 2083, 1875, 2092, 1485, 459, 432, 432, - 328, 328,-32768,-32768,-32768,-32768,-32768, 383, 169, 379, - 114, 109,-32768, 789,-32768, 393,-32768, 1459,-32768, 538, - 24, 420,-32768,-32768, 222, 875,-32768, 424, 181,-32768, --32768, 101,-32768,-32768, 40,-32768,-32768,-32768, 926, 443, --32768, 297,-32768,-32768,-32768, 485,-32768,-32768, 442,-32768, - 2059,-32768,-32768, 448, 447,-32768,-32768, 447,-32768,-32768, --32768,-32768,-32768, 498,-32768, 1273,-32768, 1837,-32768,-32768, - 352,-32768,-32768,-32768,-32768,-32768, 454,-32768,-32768,-32768, --32768, 261, 411, 308,-32768,-32768, 308,-32768,-32768,-32768, - 1104,-32768, 536, 251,-32768,-32768,-32768, 462, 371, 545, - 1329, 40,-32768,-32768, 40,-32768,-32768, 405, 68, 650, - 498,-32768,-32768, 510, 1837, 1090, 514, 2059,-32768, 473, - 1669,-32768, 103,-32768, 1513, 237, 789,-32768,-32768,-32768, --32768,-32768, 444,-32768, 33, 496, 110,-32768,-32768,-32768, - 1329,-32768,-32768, 1837, 111,-32768, 225, 410, 569, 479, - 731,-32768,-32768,-32768,-32768, 1926,-32768, 26, 1329, 1151, - 480, 411,-32768,-32768, 481,-32768, 250, 304, 235, 177, - 489, 545,-32768, 2016, 1837,-32768,-32768, 68,-32768,-32768, --32768, 812, 484,-32768,-32768,-32768,-32768, 1595, 1837, 1329, --32768, 1212,-32768, 1837, 528,-32768,-32768,-32768,-32768,-32768, - 157, 502,-32768,-32768,-32768, 2016,-32768,-32768, 1645, 546, - 539,-32768,-32768, 540, 542, 1837, 566, 531, 533, 1787, - 52, 599,-32768, 568, 537,-32768, 543, 845,-32768, 598, - 893, 30,-32768,-32768,-32768,-32768,-32768, 1971,-32768,-32768, - 1947, 1329,-32768, 608,-32768,-32768, 1837, 557,-32768, 1837, - 1837, 1539,-32768,-32768,-32768,-32768, 544, 1837, 548,-32768, - 563,-32768,-32768,-32768, 444,-32768, 33, 974,-32768,-32768, --32768,-32768, 1837, 1329, 1837, 1329,-32768, 549, 550, 1837, - 611, 460, 552, 555, 1837,-32768,-32768, 556,-32768, 1837, - 358,-32768, 21, 388,-32768, 230,-32768,-32768, 1645, 564, --32768, 1992,-32768, 635,-32768, 589,-32768,-32768,-32768,-32768, - 2041,-32768, 15,-32768, 251,-32768, 251,-32768,-32768,-32768, - 562, 1329, 603,-32768,-32768, 1837,-32768,-32768, 672, 605, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 609,-32768, - 626, 20, 606,-32768,-32768,-32768,-32768, 1837, 672, 612, - 672, 1837, 625, 39,-32768,-32768, 627,-32768, 362, 629, --32768, 247, 168,-32768,-32768, 630, 362,-32768,-32768, 247, - 689, 703,-32768 -}; - -static const short yypgoto[] = {-32768, --32768,-32768,-32768, 709,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, -7,-32768, -34,-32768, 553, 464,-32768, -18, - 46, 229,-32768, -175, -117, 534,-32768,-32768, 330,-32768, - -9,-32768, 10, 673, 13, 674, 559, -6, -124, -346, - -40, -96, -55,-32768,-32768,-32768, -177,-32768, 313, -301, - 385,-32768,-32768,-32768,-32768, -37, -62, 366, -13, -30, --32768,-32768,-32768,-32768,-32768, 532, 3,-32768,-32768, 530, - 396, 641, 554, -19, -56, 694, -80, -149, 372,-32768, - -173,-32768,-32768,-32768, 416, -259, -122,-32768,-32768,-32768, --32768, -75, -274, -426, -347,-32768, 232,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 234,-32768, -466, - 179,-32768, 178,-32768, 517,-32768, -224,-32768,-32768,-32768, - 445, -176,-32768,-32768,-32768,-32768 -}; - - -#define YYLAST 2145 - - -static const short yytable[] = { 76, - 84, 29, 31, 33, 41, 104, 107, 203, 261, 43, - 47, 19, 19, 48, 20, 20, 224, 276, 114, 197, - 252, 194, 348, 523, 90, 286, 407, 287, 86, 313, - 512, 178, 167, 108, 55, 36, 182, 138, 198, 379, - 334, 42, -93, 427, 133, 134, 86, 94, -1, 259, - 136, 277, 140, 569, 26, 27, 141, 135, 589, 95, - 96, 188, 521, 204, 205, 86, 26, 27, 26, 27, - 26, 27, 26, 27, 427, 180, 181, 599, 114, 413, - 283, 177, 380, 37, 285, 382, 203, 90, 251, 513, - 290, 570, 38, 138, -2, 138, 590, 433, 436, 579, - 318, 311, 498, -170, 431, 36, 320, 432, 218, 179, - 219, 558, 213, 220, 215, 600, 194, 177, 428, 34, - 179, 86, 223, 86, -93, 597, 194, 216, 479, 217, - 436, 250, 194, 573, 282, 259, 256, 297, 578, 297, - 580, 195, 406, 114, 284, 35, 28, 51, 30, 415, - 586, 449, 32, 321, 120, 246, 247, 5, 531, 7, - 83, 54, 322, 171, 169, 9, 10, 11, 257, 258, - 289, 91, 252, 170, 171, 92, 392, 332, 608, 441, - 517, 13, 333, 180, 442, 312, 411, 403, 227, 228, - 229, 412, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 307, 416, 325, 328, - 56, 371, 541, 311, 543, 420, 311, 425, 5, 119, - 7, 176, 126, 317, 36, 320, 9, 10, 11, 114, - 199, 121, -210, 483, 200, 539, 445, 169, 484, 36, - 363, 142, 13, 179, 606, 366, 170, 171, 425, 607, - 143, 324, 327, 206, 291, 167, 94, 92, 330, 48, - 575, 94, 331, 36, 168, 36, 99, 175, 486, 179, - 184, 297, 321, 201, 393, 195, -18, -18, -18, -18, - 209, 322, 171, 210, -18, -18, -18, 326, 338, 95, - 96, 339, -218, -218, 95, 96, 322, 171, 357, 94, - -18, 214, 417, -141, 221, 469, 418, 222, 90, -141, - 385, 326, -172, 100, 393, 426, 110, 111, 112, 225, - 322, 171, 101, 9, 10, 11, 469, 439, 373, 375, - 405, 200, 48, 223, 408, 5, 44, 7, 45, 24, - 25, 386, 226, 9, 10, 11, 426, 94, 357, 180, - -141, 358, 180, 361, -141, -18, 204, 205, 36, 13, - 189, 409, 179, -96, -96, -96, -96, 95, 96, -96, - 59, -96, -96, -96, 5, 44, 7, 45, 158, 159, - 160, 440, 9, 10, 11, 92, 358, -96, -216, -216, - 273, 93, 435, 465, -26, -26, -26, -26, 13, 274, - 396, 358, -26, -26, -26, 280, 37, 36, 99, 46, - 447, 257, 258, 281, 465, 38, 469, 94, -26, 293, - 464, -141, 299, 602, 435, 497, 358, -141, 300, 414, - 301, 610, 571, 302, 572, 554, 203, 467, 308, 200, - 468, 464, -96, 384, 358, 358, 36, 99, 374, 305, - 95, 96, 519, 499, 303, 100, 524, 505, 507, 309, - 446, 48, 310, 528, 101, 556, 534, 533, -141, 92, - 364, 365, -141, -26, 478, 358, 314, 358, 540, 481, - 156, 157, 158, 159, 160, 546, 207, 274, 419, -22, - -22, -22, -22, 536, 100, 553, 319, -22, -22, -22, - 329, 492, 340, 101, 465, 154, 155, 156, 157, 158, - 159, 160, 94, -22, 161, 162, -141, 163, 164, 165, - 166, 343, -141, 129, 131, 344, 346, 358, 347, 189, - 349, 464, -269, -269, -269, -269, 548, 362, 370, 372, - -269, -269, -269, 111, 112, 95, 96, 376, -30, 9, - 10, 11, 399, 593, 400, 410, -269, -249, 437, 358, - 542, 358, 448, -141, 438, 443, 482, -141, -22, 189, - 551, -105, -105, -105, -105, -105, -105, -105, 485, -105, - -105, -105, -105, -105, -31, -105, -105, -105, -105, -105, - -105, -105, -105, -105, -105, -105, -105, -105, 487, 490, - -105, 491, -105, -105, 493, 500, 502, 358, 494, -105, - 495, -92, -105, 508, 503, 518, 520, -105, -105, -105, - 504, 527, 530, -105, -105, 529, 545, 547, -105, 549, - 544, 550, 262, 552, 263, 5, 6, 7, 8, 574, - 561, 264, 563, 9, 10, 11, -105, -105, -105, -105, - 388, -105, -269, -269, -269, -269, -269, -269, -269, 13, - -269, -269, -269, -269, -269, 564, -269, -269, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, 576, - 581, -269, 585, -269, -269, 588, 587, 591, 612, 595, - -269, 161, 162, -269, 163, 164, 165, 166, -269, -269, - -269, 598, 613, 601, -269, -269, 604, 609, -329, -269, - 4, 23, -109, 5, 6, 7, 8, 249, 522, 421, - 109, 9, 10, 11, 444, 278, 122, -269, 402, -269, - -269, 189, -269, -269, -269, 260, 12, 13, -269, -269, - 398, -269, 383, 294, 298, -269, 124, -269, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, 212, -269, - -109, 422, -269, 292, -269, -269, 395, 594, 596, -109, - 559, -269, 560, 315, -269, 369, 0, 0, 0, -269, - -269, -269, 0, 0, 0, -269, -269, 14, 0, 262, - -269, 0, 5, 6, 7, 8, 0, 0, 264, 0, - 9, 10, 11, 0, 0, 0, 0, 0, -269, 424, - -269, -269, 189, -269, -269, -269, 13, 0, 0, -269, - -269, 0, -269, 0, 0, 0, -269, 0, -269, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, 0, - -269, 0, 0, -269, 0, -269, -269, 0, 5, 44, - 7, 45, -269, 0, 0, -269, 9, 10, 11, 0, - -269, -269, -269, 0, 0, -329, -269, -269, 0, 0, - 0, -269, 13, 0, 0, 0, 0, 36, 5, 44, - 7, 45, 0, 0, 0, 0, 9, 10, 11, -269, - -250, -269, -269, 509, -269, -269, -269, 0, 0, 0, - -269, -269, 13, -269, 0, 0, 0, -269, 0, -269, - -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, - 0, -269, 506, 0, -269, 326, -269, -269, 0, 5, - 6, 7, 8, -269, 322, 171, -269, 9, 10, 11, - 0, -269, -269, -269, 0, 0, 0, -269, -269, 0, - 0, 0, -269, 13, 5, 0, 7, 176, 0, 0, - 0, 0, 9, 10, 11, 0, 0, 0, 0, 0, - -269, 0, -269, -269, 537, -269, -279, -279, 13, 0, - 0, -279, -279, 0, -279, 0, 0, 0, -279, 0, - -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, - -279, 169, -279, 0, 0, -279, 0, -279, -279, 0, - 170, 171, 0, 0, -279, 0, 0, -279, 0, 0, - 0, 0, -279, -279, -279, 0, 0, 0, -279, -279, - 0, 0, 137, -279, 57, 5, 0, 7, 83, 58, - 59, 0, 60, 9, 10, 11, 0, 0, 0, 0, - 0, -279, 0, -279, -279, 0, -279, 0, 0, 13, - 61, 0, 0, 62, 0, 63, 64, 0, 0, 0, - 0, 0, 65, 0, 0, 66, 0, 0, 0, 0, - 67, 68, 69, 0, 0, 0, 70, 71, 0, 0, - 353, 72, 354, 27, 0, 0, 0, 58, 59, 0, - 60, 0, 0, 0, 0, 0, 0, 5, 6, 7, - 8, 73, 74, 368, -82, 9, 10, 11, 61, 0, - 0, 62, 0, 63, 64, 0, 0, 0, 0, 0, - 65, 13, 0, 66, 0, 0, 0, 0, 67, 68, - 69, 0, 0, 0, 70, 71, 0, 0, 0, 72, - 355, 353, 0, 354, 27, 0, 0, 0, 58, 59, - 0, 60, 0, 0, 0, 0, 0, 0, 397, 73, - 74, 0, 356, 0, 0, 0, 0, 0, 0, 61, - 0, 0, 62, 0, 63, 64, 0, 0, 0, 0, - 0, 65, 0, 0, 66, 0, 0, 0, 0, 67, - 68, 69, 0, 0, 0, 70, 71, 0, 0, 0, - 72, 434, 353, 0, 354, 27, 0, 0, 0, 58, - 59, 0, 60, 0, 0, 0, 0, 0, 0, -207, - 73, 74, 0, 356, 0, 0, 0, 0, 0, 0, - 61, 0, 0, 62, 0, 63, 64, 0, 0, 0, - 0, 0, 65, 0, 0, 66, 0, 0, 0, 0, - 67, 68, 69, 0, 0, 0, 70, 71, 0, 0, - 0, 72, 434, 353, 0, 354, 27, 0, 0, 0, - 58, 59, 0, 60, 0, 0, 0, 0, 0, 0, - 480, 73, 74, 0, 356, 0, 0, 0, 0, 0, - 0, 61, 0, 0, 62, 0, 63, 64, 0, 0, - 0, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 0, 0, 70, 71, 353, - 0, 57, 72, 355, 0, 0, 58, 59, 0, 60, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 73, 74, 0, 356, 0, 61, 0, 0, - 62, 0, 63, 64, 0, 0, 0, 0, 0, 65, - 0, 0, 66, 0, 0, 0, 0, 67, 68, 69, - 0, 57, 0, 70, 71, 0, 58, 59, 72, 60, - 0, 0, 0, 0, 57, 0, 0, 0, 0, 58, - 59, 0, 60, 0, 0, 0, 0, 61, 73, 74, - 62, 356, 63, 64, 0, 0, 0, 0, 0, 65, - 61, 0, 66, 62, 0, 63, 64, 67, 68, 69, - 0, 0, 65, 70, 71, 66, 0, 0, 72, 0, - 67, 68, 69, 0, 0, 0, 70, 71, 57, 0, - 0, 72, 0, 58, 59, 0, 60, 0, 73, 74, - 0, 57, 187, 0, 0, 0, 58, 59, 0, 60, - 0, 73, 74, 0, 61, 255, 0, 62, 0, 63, - 64, 0, 0, 0, 0, 0, 65, 61, 0, 66, - 62, 0, 63, 64, 67, 68, 69, 0, 0, 65, - 70, 71, 66, 0, 0, 72, 0, 67, 68, 69, - 0, 0, 0, 70, 71, 57, 0, 0, 72, 0, - 58, 59, 0, 60, 0, 73, 74, 0, 0, 288, - 153, 154, 155, 156, 157, 158, 159, 160, 73, 74, - 0, 61, 316, 0, 62, 0, 63, 64, 525, 0, - 0, 0, 0, 65, 0, 0, 66, 0, 0, 0, - 0, 67, 68, 69, 0, 0, 0, 70, 71, 0, - 0, 0, 72, 0, 144, 145, 146, 526, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 73, 74, 0, 0, 404, 354, 450, 6, - 7, 8, 58, 59, 0, 60, 9, 10, 11, 451, - 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 13, 61, 0, 0, 62, 0, 63, 64, - 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, - 0, 0, 0, 67, 68, 69, 0, 354, 27, 70, - 71, 0, 58, 59, 72, 60, 0, 0, 0, 451, - 0, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 61, 73, 74, 62, 223, 63, 64, - 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, - 0, 0, 0, 67, 68, 69, 0, 57, 0, 70, - 71, 0, 58, 59, 72, 60, 146, 0, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 463, 61, 73, 74, 62, 223, 63, 64, - 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, - 0, 0, 0, 67, 68, 69, 0, 0, 0, 70, - 71, 0, 0, 0, 72, 57, 5, 0, 7, 83, - 58, 59, 0, 60, 9, 10, 11, 0, 0, 0, - 0, 0, 0, 0, 73, 74, 0, 306, 0, 0, - 13, 61, 0, 0, 62, 0, 63, 64, 0, 57, - 0, 0, 0, 65, 58, 59, 66, 60, 0, 0, - 0, 67, 68, 69, 0, 0, 0, 70, 71, 0, - 0, 0, 72, 0, 0, 61, 0, 0, 62, 0, - 63, 64, 0, 0, 0, 0, 0, 65, 0, 0, - 66, 0, 73, 74, 0, 67, 68, 69, 0, 57, - 0, 70, 71, 0, 58, 59, 72, 60, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 58, 59, 0, - 60, 0, 0, 0, 496, 61, 73, 74, 62, 0, - 63, 64, 0, 0, 0, 0, 0, 65, 61, 0, - 66, 62, 0, 63, 64, 67, 68, 69, 0, 0, - 65, 70, 71, 66, 0, 0, 72, 0, 67, 68, - 69, 0, 57, 0, 70, 71, 0, 58, 59, 128, - 60, 0, 0, 0, 0, 0, 73, 74, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 61, 73, - 74, 62, 0, 63, 64, 429, 0, 0, 0, 0, - 65, 0, 0, 66, 0, 0, 0, 0, 67, 68, - 69, 0, 0, 0, 70, 71, 515, 0, 0, 130, - 0, 144, 145, 146, 0, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 73, - 74, 0, 144, 145, 146, 0, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 0, 0, 0, 0, 0, 0, 144, 145, 146, 430, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 0, 0, 0, 144, 145, 146, - 516, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 0, 195, 0, 0, 0, - 0, 144, 145, 146, 514, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, - 0, 0, 0, 0, 0, 562, 144, 145, 146, 568, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 144, 145, 146, 0, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 152, 153, 154, 155, - 156, 157, 158, 159, 160 -}; - -static const short yycheck[] = { 34, - 35, 9, 10, 11, 18, 43, 47, 104, 184, 19, - 20, 2, 3, 20, 2, 3, 139, 191, 49, 100, - 170, 97, 297, 490, 38, 203, 373, 204, 35, 254, - 1, 88, 9, 47, 32, 3, 92, 72, 101, 341, - 1, 78, 1, 391, 63, 64, 53, 27, 0, 174, - 69, 10, 72, 39, 3, 4, 75, 65, 39, 60, - 61, 96, 489, 60, 61, 72, 3, 4, 3, 4, - 3, 4, 3, 4, 422, 89, 77, 39, 109, 381, - 77, 88, 342, 51, 202, 345, 183, 101, 169, 60, - 208, 77, 60, 128, 0, 130, 77, 399, 400, 566, - 77, 251, 51, 83, 79, 3, 4, 82, 128, 7, - 130, 538, 122, 132, 124, 77, 192, 124, 393, 60, - 7, 128, 83, 130, 83, 592, 202, 125, 430, 127, - 432, 166, 208, 560, 197, 260, 171, 213, 565, 215, - 567, 31, 367, 174, 200, 60, 83, 83, 83, 39, - 577, 426, 83, 51, 1, 163, 164, 4, 505, 6, - 7, 83, 60, 61, 51, 12, 13, 14, 60, 61, - 205, 78, 322, 60, 61, 82, 350, 77, 605, 3, - 482, 28, 82, 197, 8, 77, 77, 364, 143, 144, - 145, 82, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 225, 385, 265, 266, - 83, 334, 514, 363, 516, 389, 366, 391, 4, 79, - 6, 7, 79, 258, 3, 4, 12, 13, 14, 260, - 78, 78, 79, 77, 82, 510, 414, 51, 82, 3, - 321, 77, 28, 7, 77, 326, 60, 61, 422, 82, - 82, 265, 266, 78, 209, 9, 27, 82, 78, 266, - 562, 27, 82, 3, 77, 3, 4, 77, 446, 7, - 60, 347, 51, 1, 350, 31, 4, 5, 6, 7, - 37, 60, 61, 82, 12, 13, 14, 51, 279, 60, - 61, 279, 78, 79, 60, 61, 60, 61, 306, 27, - 28, 78, 78, 31, 77, 428, 82, 77, 322, 37, - 348, 51, 83, 51, 390, 391, 5, 6, 7, 77, - 60, 61, 60, 12, 13, 14, 449, 78, 338, 339, - 365, 82, 339, 83, 375, 4, 5, 6, 7, 78, - 79, 349, 78, 12, 13, 14, 422, 27, 356, 363, - 78, 306, 366, 308, 82, 83, 60, 61, 3, 28, - 1, 375, 7, 4, 5, 6, 7, 60, 61, 10, - 9, 12, 13, 14, 4, 5, 6, 7, 51, 52, - 53, 78, 12, 13, 14, 82, 341, 28, 78, 79, - 84, 1, 400, 428, 4, 5, 6, 7, 28, 78, - 355, 356, 12, 13, 14, 60, 51, 3, 4, 78, - 418, 60, 61, 37, 449, 60, 539, 27, 28, 79, - 428, 31, 79, 599, 432, 460, 381, 37, 79, 384, - 77, 607, 555, 77, 557, 78, 533, 428, 39, 82, - 428, 449, 83, 39, 399, 400, 3, 4, 78, 77, - 60, 61, 487, 461, 79, 51, 491, 467, 468, 77, - 415, 468, 84, 498, 60, 78, 507, 505, 78, 82, - 60, 61, 82, 83, 429, 430, 84, 432, 513, 434, - 49, 50, 51, 52, 53, 520, 1, 78, 79, 4, - 5, 6, 7, 507, 51, 530, 77, 12, 13, 14, - 77, 456, 60, 60, 539, 47, 48, 49, 50, 51, - 52, 53, 27, 28, 55, 56, 31, 58, 59, 60, - 61, 37, 37, 60, 61, 84, 79, 482, 82, 1, - 33, 539, 4, 5, 6, 7, 77, 84, 3, 78, - 12, 13, 14, 6, 7, 60, 61, 3, 39, 12, - 13, 14, 39, 588, 82, 60, 28, 79, 79, 514, - 515, 516, 79, 78, 84, 77, 39, 82, 83, 1, - 525, 3, 4, 5, 6, 7, 8, 9, 77, 11, - 12, 13, 14, 15, 39, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 60, 60, - 32, 60, 34, 35, 39, 7, 39, 562, 78, 41, - 78, 83, 44, 16, 78, 8, 60, 49, 50, 51, - 78, 78, 60, 55, 56, 78, 77, 17, 60, 78, - 82, 77, 1, 78, 3, 4, 5, 6, 7, 78, - 77, 10, 8, 12, 13, 14, 78, 79, 80, 81, - 1, 83, 3, 4, 5, 6, 7, 8, 9, 28, - 11, 12, 13, 14, 15, 77, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 77, - 9, 32, 78, 34, 35, 60, 78, 82, 0, 78, - 41, 55, 56, 44, 58, 59, 60, 61, 49, 50, - 51, 77, 0, 77, 55, 56, 78, 78, 77, 60, - 1, 3, 3, 4, 5, 6, 7, 165, 490, 390, - 48, 12, 13, 14, 412, 192, 53, 78, 363, 80, - 81, 1, 83, 3, 4, 177, 27, 28, 8, 9, - 356, 11, 347, 212, 215, 15, 53, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 118, 29, - 51, 390, 32, 210, 34, 35, 351, 589, 591, 60, - 539, 41, 539, 257, 44, 331, -1, -1, -1, 49, - 50, 51, -1, -1, -1, 55, 56, 78, -1, 1, - 60, -1, 4, 5, 6, 7, -1, -1, 10, -1, - 12, 13, 14, -1, -1, -1, -1, -1, 78, 79, - 80, 81, 1, 83, 3, 4, 28, -1, -1, 8, - 9, -1, 11, -1, -1, -1, 15, -1, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, - 29, -1, -1, 32, -1, 34, 35, -1, 4, 5, - 6, 7, 41, -1, -1, 44, 12, 13, 14, -1, - 49, 50, 51, -1, -1, 77, 55, 56, -1, -1, - -1, 60, 28, -1, -1, -1, -1, 3, 4, 5, - 6, 7, -1, -1, -1, -1, 12, 13, 14, 78, - 79, 80, 81, 1, 83, 3, 4, -1, -1, -1, - 8, 9, 28, 11, -1, -1, -1, 15, -1, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - -1, 29, 78, -1, 32, 51, 34, 35, -1, 4, - 5, 6, 7, 41, 60, 61, 44, 12, 13, 14, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, 28, 4, -1, 6, 7, -1, -1, - -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, - 78, -1, 80, 81, 1, 83, 3, 4, 28, -1, - -1, 8, 9, -1, 11, -1, -1, -1, 15, -1, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 51, 29, -1, -1, 32, -1, 34, 35, -1, - 60, 61, -1, -1, 41, -1, -1, 44, -1, -1, - -1, -1, 49, 50, 51, -1, -1, -1, 55, 56, - -1, -1, 1, 60, 3, 4, -1, 6, 7, 8, - 9, -1, 11, 12, 13, 14, -1, -1, -1, -1, - -1, 78, -1, 80, 81, -1, 83, -1, -1, 28, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - 1, 60, 3, 4, -1, -1, -1, 8, 9, -1, - 11, -1, -1, -1, -1, -1, -1, 4, 5, 6, - 7, 80, 81, 10, 83, 12, 13, 14, 29, -1, - -1, 32, -1, 34, 35, -1, -1, -1, -1, -1, - 41, 28, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, -1, -1, -1, 60, - 61, 1, -1, 3, 4, -1, -1, -1, 8, 9, - -1, 11, -1, -1, -1, -1, -1, -1, 79, 80, - 81, -1, 83, -1, -1, -1, -1, -1, -1, 29, - -1, -1, 32, -1, 34, 35, -1, -1, -1, -1, - -1, 41, -1, -1, 44, -1, -1, -1, -1, 49, - 50, 51, -1, -1, -1, 55, 56, -1, -1, -1, - 60, 61, 1, -1, 3, 4, -1, -1, -1, 8, - 9, -1, 11, -1, -1, -1, -1, -1, -1, 79, - 80, 81, -1, 83, -1, -1, -1, -1, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, 1, -1, 3, 4, -1, -1, -1, - 8, 9, -1, 11, -1, -1, -1, -1, -1, -1, - 79, 80, 81, -1, 83, -1, -1, -1, -1, -1, - -1, 29, -1, -1, 32, -1, 34, 35, -1, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, 1, - -1, 3, 60, 61, -1, -1, 8, 9, -1, 11, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 80, 81, -1, 83, -1, 29, -1, -1, - 32, -1, 34, 35, -1, -1, -1, -1, -1, 41, - -1, -1, 44, -1, -1, -1, -1, 49, 50, 51, - -1, 3, -1, 55, 56, -1, 8, 9, 60, 11, - -1, -1, -1, -1, 3, -1, -1, -1, -1, 8, - 9, -1, 11, -1, -1, -1, -1, 29, 80, 81, - 32, 83, 34, 35, -1, -1, -1, -1, -1, 41, - 29, -1, 44, 32, -1, 34, 35, 49, 50, 51, - -1, -1, 41, 55, 56, 44, -1, -1, 60, -1, - 49, 50, 51, -1, -1, -1, 55, 56, 3, -1, - -1, 60, -1, 8, 9, -1, 11, -1, 80, 81, - -1, 3, 84, -1, -1, -1, 8, 9, -1, 11, - -1, 80, 81, -1, 29, 84, -1, 32, -1, 34, - 35, -1, -1, -1, -1, -1, 41, 29, -1, 44, - 32, -1, 34, 35, 49, 50, 51, -1, -1, 41, - 55, 56, 44, -1, -1, 60, -1, 49, 50, 51, - -1, -1, -1, 55, 56, 3, -1, -1, 60, -1, - 8, 9, -1, 11, -1, 80, 81, -1, -1, 84, - 46, 47, 48, 49, 50, 51, 52, 53, 80, 81, - -1, 29, 84, -1, 32, -1, 34, 35, 10, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, -1, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 80, 81, -1, -1, 84, 3, 4, 5, - 6, 7, 8, 9, -1, 11, 12, 13, 14, 15, - -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, 3, 4, 55, - 56, -1, 8, 9, 60, 11, -1, -1, -1, 15, - -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 78, 29, 80, 81, 32, 83, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, 3, -1, 55, - 56, -1, 8, 9, 60, 11, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 78, 29, 80, 81, 32, 83, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, -1, -1, 55, - 56, -1, -1, -1, 60, 3, 4, -1, 6, 7, - 8, 9, -1, 11, 12, 13, 14, -1, -1, -1, - -1, -1, -1, -1, 80, 81, -1, 83, -1, -1, - 28, 29, -1, -1, 32, -1, 34, 35, -1, 3, - -1, -1, -1, 41, 8, 9, 44, 11, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, -1, -1, 29, -1, -1, 32, -1, - 34, 35, -1, -1, -1, -1, -1, 41, -1, -1, - 44, -1, 80, 81, -1, 49, 50, 51, -1, 3, - -1, 55, 56, -1, 8, 9, 60, 11, -1, -1, - -1, -1, 3, -1, -1, -1, -1, 8, 9, -1, - 11, -1, -1, -1, 78, 29, 80, 81, 32, -1, - 34, 35, -1, -1, -1, -1, -1, 41, 29, -1, - 44, 32, -1, 34, 35, 49, 50, 51, -1, -1, - 41, 55, 56, 44, -1, -1, 60, -1, 49, 50, - 51, -1, 3, -1, 55, 56, -1, 8, 9, 60, - 11, -1, -1, -1, -1, -1, 80, 81, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 29, 80, - 81, 32, -1, 34, 35, 10, -1, -1, -1, -1, - 41, -1, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, 10, -1, -1, 60, - -1, 36, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 80, - 81, -1, 36, 37, 38, -1, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - -1, -1, -1, -1, -1, -1, 36, 37, 38, 84, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, -1, -1, -1, 36, 37, 38, - 84, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, -1, 31, -1, -1, -1, - -1, 36, 37, 38, 84, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, - -1, -1, -1, -1, -1, 84, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 36, 37, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 45, 46, 47, 48, - 49, 50, 51, 52, 53 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman - - This program 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 1, or (at your option) - any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) -#include -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#include -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -#include - #pragma alloca -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#define YYLEX yylex(&yylval, &yylloc) -#else -#define YYLEX yylex(&yylval) -#endif -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (from, to, count) - char *from; - char *to; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (char *from, char *to, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 169 "bison.simple" -int -yyparse() -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), -#ifdef YYLSP_NEEDED - &yyls1, size * sizeof (*yylsp), -#endif - &yystacksize); - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symboles being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 219 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids an empty source file"); - ; - break;} -case 2: -#line 223 "c-parse.y" -{ - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! global_bindings_p ()) - poplevel (0, 0, 0); - ; - break;} -case 3: -#line 236 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 5: -#line 237 "c-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 9: -#line 244 "c-parse.y" -{ STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - assemble_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 10: -#line 255 "c-parse.y" -{ if (pedantic) - error ("ANSI C forbids data definition with no type or storage class"); - else if (!flag_traditional) - warning ("data definition has no type or storage class"); ; - break;} -case 11: -#line 260 "c-parse.y" -{; - break;} -case 12: -#line 262 "c-parse.y" -{; - break;} -case 13: -#line 264 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 14: -#line 266 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 17: -#line 270 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C does not allow extra `;' outside of a function"); ; - break;} -case 18: -#line 276 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 19: -#line 280 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 20: -#line 282 "c-parse.y" -{ finish_function (0); ; - break;} -case 21: -#line 284 "c-parse.y" -{ ; - break;} -case 22: -#line 286 "c-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 23: -#line 290 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 24: -#line 292 "c-parse.y" -{ finish_function (0); ; - break;} -case 25: -#line 294 "c-parse.y" -{ ; - break;} -case 26: -#line 296 "c-parse.y" -{ if (! start_function (NULL_TREE, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 27: -#line 300 "c-parse.y" -{ store_parm_decls (); ; - break;} -case 28: -#line 302 "c-parse.y" -{ finish_function (0); ; - break;} -case 29: -#line 304 "c-parse.y" -{ ; - break;} -case 32: -#line 313 "c-parse.y" -{ yyval.code = ADDR_EXPR; ; - break;} -case 33: -#line 315 "c-parse.y" -{ yyval.code = NEGATE_EXPR; ; - break;} -case 34: -#line 317 "c-parse.y" -{ yyval.code = CONVERT_EXPR; ; - break;} -case 35: -#line 319 "c-parse.y" -{ yyval.code = PREINCREMENT_EXPR; ; - break;} -case 36: -#line 321 "c-parse.y" -{ yyval.code = PREDECREMENT_EXPR; ; - break;} -case 37: -#line 323 "c-parse.y" -{ yyval.code = BIT_NOT_EXPR; ; - break;} -case 38: -#line 325 "c-parse.y" -{ yyval.code = TRUTH_NOT_EXPR; ; - break;} -case 39: -#line 329 "c-parse.y" -{ yyval.ttype = build_compound_expr (yyvsp[0].ttype); ; - break;} -case 40: -#line 334 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 42: -#line 340 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 43: -#line 342 "c-parse.y" -{ chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 45: -#line 348 "c-parse.y" -{ yyval.ttype = build_indirect_ref (yyvsp[0].ttype, "unary *"); ; - break;} -case 46: -#line 351 "c-parse.y" -{ yyvsp[0].itype = pedantic; - pedantic = 0; ; - break;} -case 47: -#line 354 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - pedantic = yyvsp[-2].itype; ; - break;} -case 48: -#line 357 "c-parse.y" -{ yyval.ttype = build_unary_op (yyvsp[-1].code, yyvsp[0].ttype, 0); - overflow_warning (yyval.ttype); ; - break;} -case 49: -#line 361 "c-parse.y" -{ tree label = lookup_label (yyvsp[0].ttype); - if (label == 0) - yyval.ttype = null_pointer_node; - else - { - TREE_USED (label) = 1; - yyval.ttype = build1 (ADDR_EXPR, ptr_type_node, label); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 50: -#line 387 "c-parse.y" -{ if (TREE_CODE (yyvsp[0].ttype) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (yyvsp[0].ttype, 1))) - error ("`sizeof' applied to a bit-field"); - yyval.ttype = c_sizeof (TREE_TYPE (yyvsp[0].ttype)); ; - break;} -case 51: -#line 392 "c-parse.y" -{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 52: -#line 394 "c-parse.y" -{ yyval.ttype = c_alignof_expr (yyvsp[0].ttype); ; - break;} -case 53: -#line 396 "c-parse.y" -{ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 54: -#line 398 "c-parse.y" -{ yyval.ttype = build_unary_op (REALPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 55: -#line 400 "c-parse.y" -{ yyval.ttype = build_unary_op (IMAGPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 57: -#line 406 "c-parse.y" -{ tree type = groktypename (yyvsp[-2].ttype); - yyval.ttype = build_c_cast (type, yyvsp[0].ttype); ; - break;} -case 58: -#line 409 "c-parse.y" -{ tree type = groktypename (yyvsp[-5].ttype); - char *name; - if (pedantic) - pedwarn ("ANSI C forbids constructor expressions"); - if (TYPE_NAME (type) != 0) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - else - name = ""; - yyval.ttype = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)), - NULL_PTR, 0, 0, name); - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) - { - int failure = complete_array_type (type, yyval.ttype, 1); - if (failure) - abort (); - } - ; - break;} -case 60: -#line 436 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 61: -#line 438 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 62: -#line 440 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 63: -#line 442 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 64: -#line 444 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 65: -#line 446 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 66: -#line 448 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 67: -#line 450 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 68: -#line 452 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 69: -#line 454 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 70: -#line 456 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 71: -#line 458 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 72: -#line 460 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ANDIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 73: -#line 462 "c-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ORIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 74: -#line 464 "c-parse.y" -{ yyval.ttype = build_conditional_expr (yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 75: -#line 466 "c-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, NOP_EXPR, yyvsp[0].ttype); - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, MODIFY_EXPR); ; - break;} -case 76: -#line 469 "c-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, yyvsp[-1].code, yyvsp[0].ttype); - /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, ERROR_MARK); ; - break;} -case 77: -#line 476 "c-parse.y" -{ - tree context; - - yyval.ttype = lastiddecl; - if (!yyval.ttype || yyval.ttype == error_mark_node) - { - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - { - /* Ordinary implicit function declaration. */ - yyval.ttype = implicitly_declare (yyvsp[0].ttype); - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - } - else if (current_function_decl == 0) - { - error ("`%s' undeclared here (not in a function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = error_mark_node; - } - else - { - { - if (IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) != current_function_decl) - { - error ("`%s' undeclared (first use this function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - yyval.ttype = error_mark_node; - /* Prevent repeated error messages. */ - IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) = error_mark_node; - IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) = current_function_decl; - } - } - } - else if (TREE_TYPE (yyval.ttype) == error_mark_node) - yyval.ttype = error_mark_node; - else if (C_DECL_ANTICIPATED (yyval.ttype)) - { - /* The first time we see a build-in function used, - if it has not been declared. */ - C_DECL_ANTICIPATED (yyval.ttype) = 0; - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - /* Omit the implicit declaration we - would ordinarily do, so we don't lose - the actual built in type. - But print a diagnostic for the mismatch. */ - if (TREE_CODE (yyval.ttype) != FUNCTION_DECL) - error ("`%s' implicitly declared as function", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE (yyval.ttype))) - != TYPE_MODE (integer_type_node)) - && (TREE_TYPE (TREE_TYPE (yyval.ttype)) - != void_type_node)) - pedwarn ("type mismatch in implicit declaration for built-in function `%s'", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - /* If it really returns void, change that to int. */ - if (TREE_TYPE (TREE_TYPE (yyval.ttype)) == void_type_node) - TREE_TYPE (yyval.ttype) - = build_function_type (integer_type_node, - TYPE_ARG_TYPES (TREE_TYPE (yyval.ttype))); - } - else - pedwarn ("built-in function `%s' used without declaration", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - - /* Do what we would ordinarily do when a fn is used. */ - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - else - { - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - - if (TREE_CODE (yyval.ttype) == CONST_DECL) - { - yyval.ttype = DECL_INITIAL (yyval.ttype); - /* This is to prevent an enum whose value is 0 - from being considered a null pointer constant. */ - yyval.ttype = build1 (NOP_EXPR, TREE_TYPE (yyval.ttype), yyval.ttype); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 79: -#line 577 "c-parse.y" -{ yyval.ttype = combine_strings (yyvsp[0].ttype); ; - break;} -case 80: -#line 579 "c-parse.y" -{ char class = TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype)); - if (class == 'e' || class == '1' - || class == '2' || class == '<') - C_SET_EXP_ORIGINAL_CODE (yyvsp[-1].ttype, ERROR_MARK); - yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 81: -#line 585 "c-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 82: -#line 587 "c-parse.y" -{ if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - /* We must force a BLOCK for this level - so that, if it is not expanded later, - there is a way to turn off the entire subtree of blocks - that are contained in it. */ - keep_next_level (); - push_iterator_stack (); - push_label_level (); - yyval.ttype = expand_start_stmt_expr (); ; - break;} -case 83: -#line 601 "c-parse.y" -{ tree rtl_exp; - if (pedantic) - pedwarn ("ANSI C forbids braced-groups within expressions"); - pop_iterator_stack (); - pop_label_level (); - rtl_exp = expand_end_stmt_expr (yyvsp[-2].ttype); - /* The statements have side effects, so the group does. */ - TREE_SIDE_EFFECTS (rtl_exp) = 1; - - /* Make a BIND_EXPR for the BLOCK already made. */ - yyval.ttype = build (BIND_EXPR, TREE_TYPE (rtl_exp), - NULL_TREE, rtl_exp, yyvsp[-1].ttype); - /* Remove the block from the tree at this point. - It gets put back at the proper place - when the BIND_EXPR is expanded. */ - delete_block (yyvsp[-1].ttype); - ; - break;} -case 84: -#line 619 "c-parse.y" -{ yyval.ttype = build_function_call (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 85: -#line 621 "c-parse.y" -{ yyval.ttype = build_array_ref (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 86: -#line 623 "c-parse.y" -{ - yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 87: -#line 627 "c-parse.y" -{ - tree expr = build_indirect_ref (yyvsp[-2].ttype, "->"); - - yyval.ttype = build_component_ref (expr, yyvsp[0].ttype); - ; - break;} -case 88: -#line 633 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTINCREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 89: -#line 635 "c-parse.y" -{ yyval.ttype = build_unary_op (POSTDECREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 91: -#line 642 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 94: -#line 651 "c-parse.y" -{ c_mark_varargs (); - if (pedantic) - pedwarn ("ANSI C does not permit use of `varargs.h'"); ; - break;} -case 95: -#line 661 "c-parse.y" -{ ; - break;} -case 100: -#line 673 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 101: -#line 677 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 102: -#line 681 "c-parse.y" -{ shadow_tag_warned (yyvsp[-1].ttype, 1); - pedwarn ("empty declaration"); ; - break;} -case 103: -#line 684 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 104: -#line 693 "c-parse.y" -{ ; - break;} -case 109: -#line 708 "c-parse.y" -{ yyval.itype = suspend_momentary (); - pending_xref_error (); - declspec_stack = tree_cons (NULL_TREE, current_declspecs, - declspec_stack); - current_declspecs = yyvsp[0].ttype; ; - break;} -case 110: -#line 717 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 111: -#line 721 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 112: -#line 725 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 113: -#line 729 "c-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 114: -#line 733 "c-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 115: -#line 735 "c-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 116: -#line 744 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 117: -#line 746 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 118: -#line 750 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 119: -#line 752 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 120: -#line 754 "c-parse.y" -{ if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 121: -#line 766 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 122: -#line 769 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 123: -#line 771 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 124: -#line 774 "c-parse.y" -{ if (extra_warnings && TREE_STATIC (yyvsp[-1].ttype)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = TREE_STATIC (yyvsp[-1].ttype); ; - break;} -case 125: -#line 788 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 126: -#line 790 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 127: -#line 794 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 128: -#line 796 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 131: -#line 806 "c-parse.y" -{ /* For a typedef name, record the meaning, not the name. - In case of `foo foo, bar;'. */ - yyval.ttype = lookup_name (yyvsp[0].ttype); ; - break;} -case 132: -#line 810 "c-parse.y" -{ yyval.ttype = TREE_TYPE (yyvsp[-1].ttype); ; - break;} -case 133: -#line 812 "c-parse.y" -{ yyval.ttype = groktypename (yyvsp[-1].ttype); ; - break;} -case 141: -#line 834 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 142: -#line 836 "c-parse.y" -{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype); - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 143: -#line 843 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 144: -#line 846 "c-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 145: -#line 849 "c-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 146: -#line 856 "c-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 147: -#line 859 "c-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 148: -#line 862 "c-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 149: -#line 870 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 150: -#line 872 "c-parse.y" -{ yyval.ttype = yyvsp[-2].ttype; ; - break;} -case 151: -#line 877 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 152: -#line 879 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 153: -#line 884 "c-parse.y" -{ if (strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "packed")) - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = yyvsp[0].ttype; ; - break;} -case 154: -#line 889 "c-parse.y" -{ /* If not "mode (m)", then issue warning. */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "mode") != 0) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 155: -#line 899 "c-parse.y" -{ /* if not "aligned(n)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "aligned") != 0 - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 156: -#line 910 "c-parse.y" -{ /* if not "format(...)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-7].ttype), "format") != 0 - || TREE_CODE (yyvsp[-3].ttype) != INTEGER_CST - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-7].ttype)); - yyval.ttype = yyvsp[-7].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-7].ttype, - tree_cons (yyvsp[-5].ttype, - tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE), - NULL_TREE), - NULL_TREE); ; - break;} -case 158: -#line 930 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - if (pedantic) - pedwarn ("ANSI C forbids empty initializer braces"); ; - break;} -case 159: -#line 934 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-1].ttype)); ; - break;} -case 160: -#line 936 "c-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)); ; - break;} -case 161: -#line 938 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 162: -#line 945 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 163: -#line 947 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 164: -#line 952 "c-parse.y" -{ yyval.ttype = build_tree_list (tree_cons (yyvsp[-4].ttype, NULL_TREE, - build_tree_list (yyvsp[-2].ttype, NULL_TREE)), - yyvsp[0].ttype); ; - break;} -case 165: -#line 956 "c-parse.y" -{ yyval.ttype = tree_cons (tree_cons (yyvsp[-4].ttype, NULL_TREE, - build_tree_list (yyvsp[-2].ttype, NULL_TREE)), - yyvsp[0].ttype, - yyvsp[-7].ttype); ; - break;} -case 166: -#line 961 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 167: -#line 963 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyvsp[-5].ttype); ; - break;} -case 168: -#line 965 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 169: -#line 967 "c-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 170: -#line 972 "c-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 171: -#line 987 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 172: -#line 993 "c-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 173: -#line 1008 "c-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 176: -#line 1024 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 177: -#line 1026 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 178: -#line 1031 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 179: -#line 1033 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 180: -#line 1035 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 182: -#line 1046 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 183: -#line 1051 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 184: -#line 1053 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 185: -#line 1055 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 187: -#line 1064 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 188: -#line 1069 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 189: -#line 1071 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 190: -#line 1073 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 191: -#line 1075 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 193: -#line 1081 "c-parse.y" -{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype); - /* Start scope of tag before parsing components. */ - ; - break;} -case 194: -#line 1085 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); - /* Really define the structure. */ - ; - break;} -case 195: -#line 1089 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 196: -#line 1092 "c-parse.y" -{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ; - break;} -case 197: -#line 1094 "c-parse.y" -{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ; - break;} -case 198: -#line 1096 "c-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 199: -#line 1098 "c-parse.y" -{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 200: -#line 1101 "c-parse.y" -{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ; - break;} -case 201: -#line 1103 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (yyvsp[-1].ttype); ; - break;} -case 202: -#line 1106 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 203: -#line 1109 "c-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (NULL_TREE); ; - break;} -case 204: -#line 1112 "c-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 205: -#line 1115 "c-parse.y" -{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ; - break;} -case 209: -#line 1126 "c-parse.y" -{ if (pedantic) pedwarn ("comma at end of enumerator list"); ; - break;} -case 210: -#line 1131 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 211: -#line 1133 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - pedwarn ("no semicolon at end of struct or union"); ; - break;} -case 212: -#line 1138 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 213: -#line 1140 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 214: -#line 1142 "c-parse.y" -{ if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); ; - break;} -case 215: -#line 1157 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 216: -#line 1162 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 217: -#line 1167 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 218: -#line 1172 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 219: -#line 1177 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 221: -#line 1183 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 222: -#line 1188 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-3].filename, yyvsp[-2].lineno, yyvsp[-1].ttype, current_declspecs, NULL_TREE); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 223: -#line 1192 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-5].filename, yyvsp[-4].lineno, yyvsp[-3].ttype, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 224: -#line 1195 "c-parse.y" -{ yyval.ttype = grokfield (yyvsp[-4].filename, yyvsp[-3].lineno, NULL_TREE, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 226: -#line 1207 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 227: -#line 1213 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 228: -#line 1215 "c-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 229: -#line 1220 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 230: -#line 1222 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 231: -#line 1227 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 233: -#line 1233 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 234: -#line 1235 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 235: -#line 1240 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 236: -#line 1242 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 237: -#line 1247 "c-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 238: -#line 1250 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 239: -#line 1252 "c-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 240: -#line 1254 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 241: -#line 1256 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 242: -#line 1258 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 243: -#line 1260 "c-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 244: -#line 1262 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 245: -#line 1264 "c-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ; - break;} -case 252: -#line 1286 "c-parse.y" -{ emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - ; - break;} -case 254: -#line 1299 "c-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids label declarations"); ; - break;} -case 257: -#line 1310 "c-parse.y" -{ tree link; - for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - ; - break;} -case 258: -#line 1324 "c-parse.y" -{; - break;} -case 260: -#line 1329 "c-parse.y" -{ yyval.ttype = convert (void_type_node, integer_zero_node); ; - break;} -case 261: -#line 1331 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), 1, 0); - yyval.ttype = poplevel (1, 1, 0); - pop_momentary (); ; - break;} -case 262: -#line 1336 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - pop_momentary (); ; - break;} -case 263: -#line 1341 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - pop_momentary (); ; - break;} -case 266: -#line 1358 "c-parse.y" -{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0); - yyvsp[-3].itype = stmt_count; - if_stmt_file = yyvsp[-5].filename; - if_stmt_line = yyvsp[-4].lineno; - position_after_white_space (); ; - break;} -case 267: -#line 1371 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - expand_start_loop_continue_elsewhere (1); - position_after_white_space (); ; - break;} -case 268: -#line 1378 "c-parse.y" -{ expand_loop_continue_here (); ; - break;} -case 269: -#line 1382 "c-parse.y" -{ yyval.filename = input_filename; ; - break;} -case 270: -#line 1386 "c-parse.y" -{ yyval.lineno = lineno; ; - break;} -case 271: -#line 1391 "c-parse.y" -{ ; - break;} -case 272: -#line 1396 "c-parse.y" -{ ; - break;} -case 273: -#line 1401 "c-parse.y" -{ ; - break;} -case 275: -#line 1407 "c-parse.y" -{ int next; - position_after_white_space (); - next = getc (finput); - ungetc (next, finput); - if (pedantic && next == '}') - pedwarn ("ANSI C forbids label at end of compound statement"); - ; - break;} -case 276: -#line 1419 "c-parse.y" -{ stmt_count++; ; - break;} -case 278: -#line 1422 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - iterator_expand (yyvsp[-1].ttype); - clear_momentary (); ; - break;} -case 279: -#line 1427 "c-parse.y" -{ expand_start_else (); - yyvsp[-1].itype = stmt_count; - position_after_white_space (); ; - break;} -case 280: -#line 1431 "c-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[-3].itype) - warning ("empty body in an else-statement"); ; - break;} -case 281: -#line 1435 "c-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[0].itype) - warning_with_file_and_line (if_stmt_file, if_stmt_line, - "empty body in an if-statement"); ; - break;} -case 282: -#line 1443 "c-parse.y" -{ expand_end_cond (); ; - break;} -case 283: -#line 1445 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* The emit_nop used to come before emit_line_note, - but that made the nop seem like part of the preceding line. - And that was confusing when the preceding line was - inside of an if statement and was not really executed. - I think it ought to work to put the nop after the line number. - We will see. --rms, July 15, 1991. */ - emit_nop (); ; - break;} -case 284: -#line 1455 "c-parse.y" -{ /* Don't start the loop till we have succeeded - in parsing the end test. This is to make sure - that we end every loop we start. */ - expand_start_loop (1); - emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-1].ttype)); - position_after_white_space (); ; - break;} -case 285: -#line 1464 "c-parse.y" -{ expand_end_loop (); ; - break;} -case 286: -#line 1467 "c-parse.y" -{ emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-2].ttype)); - expand_end_loop (); - clear_momentary (); ; - break;} -case 287: -#line 1474 "c-parse.y" -{ expand_end_loop (); - clear_momentary (); ; - break;} -case 288: -#line 1478 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - if (yyvsp[-1].ttype) c_expand_expr_stmt (yyvsp[-1].ttype); - /* Next step is to call expand_start_loop_continue_elsewhere, - but wait till after we parse the entire for (...). - Otherwise, invalid input might cause us to call that - fn without calling expand_end_loop. */ - ; - break;} -case 289: -#line 1490 "c-parse.y" -{ yyvsp[0].lineno = lineno; - yyval.filename = input_filename; ; - break;} -case 290: -#line 1493 "c-parse.y" -{ - /* Start the loop. Doing this after parsing - all the expressions ensures we will end the loop. */ - expand_start_loop_continue_elsewhere (1); - /* Emit the end-test, with a line number. */ - emit_line_note (yyvsp[-2].filename, yyvsp[-3].lineno); - if (yyvsp[-4].ttype) - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-4].ttype)); - /* Don't let the tree nodes for $9 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - yyvsp[-3].lineno = lineno; - yyvsp[-2].filename = input_filename; - position_after_white_space (); ; - break;} -case 291: -#line 1509 "c-parse.y" -{ /* Emit the increment expression, with a line number. */ - emit_line_note (yyvsp[-4].filename, yyvsp[-5].lineno); - expand_loop_continue_here (); - if (yyvsp[-3].ttype) - c_expand_expr_stmt (yyvsp[-3].ttype); - pop_momentary (); - expand_end_loop (); ; - break;} -case 292: -#line 1517 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - c_expand_start_case (yyvsp[-1].ttype); - /* Don't let the tree nodes for $3 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - position_after_white_space (); ; - break;} -case 293: -#line 1525 "c-parse.y" -{ expand_end_case (yyvsp[-3].ttype); - pop_momentary (); ; - break;} -case 294: -#line 1528 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if ( ! expand_exit_something ()) - error ("break statement not within loop or switch"); ; - break;} -case 295: -#line 1533 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if (! expand_continue_loop (NULL_PTR)) - error ("continue statement not within a loop"); ; - break;} -case 296: -#line 1538 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - c_expand_return (NULL_TREE); ; - break;} -case 297: -#line 1542 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - c_expand_return (yyvsp[-1].ttype); ; - break;} -case 298: -#line 1546 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-7].filename, yyvsp[-6].lineno); - STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - expand_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 299: -#line 1557 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-9].filename, yyvsp[-8].lineno); - c_expand_asm_operands (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE, - yyvsp[-6].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 300: -#line 1564 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-11].filename, yyvsp[-10].lineno); - c_expand_asm_operands (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, - yyvsp[-8].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 301: -#line 1572 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-13].filename, yyvsp[-12].lineno); - c_expand_asm_operands (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, - yyvsp[-10].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 302: -#line 1578 "c-parse.y" -{ tree decl; - stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - decl = lookup_label (yyvsp[-1].ttype); - if (decl != 0) - { - TREE_USED (decl) = 1; - expand_goto (decl); - } - ; - break;} -case 303: -#line 1589 "c-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_computed_goto (convert (ptr_type_node, yyvsp[-1].ttype)); ; - break;} -case 306: -#line 1602 "c-parse.y" -{ - /* The value returned by this action is */ - /* 1 if everything is OK */ - /* 0 in case of error or already bound iterator */ - - yyval.itype = 0; - if (TREE_CODE (yyvsp[-1].ttype) != VAR_DECL) - error ("invalid `for (ITERATOR)' syntax"); - if (! ITERATOR_P (yyvsp[-1].ttype)) - error ("`%s' is not an iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else if (ITERATOR_BOUND_P (yyvsp[-1].ttype)) - error ("`for (%s)' inside expansion of same iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else - { - yyval.itype = 1; - iterator_for_loop_start (yyvsp[-1].ttype); - } - ; - break;} -case 307: -#line 1623 "c-parse.y" -{ - if (yyvsp[-1].itype) - iterator_for_loop_end (yyvsp[-3].ttype); - ; - break;} -case 308: -#line 1655 "c-parse.y" -{ register tree value = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value != error_mark_node) - { - tree duplicate; - int success = pushcase (value, label, &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 309: -#line 1679 "c-parse.y" -{ register tree value1 = check_case_value (yyvsp[-3].ttype); - register tree value2 = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value1 != error_mark_node && value2 != error_mark_node) - { - tree duplicate; - int success = pushcase_range (value1, value2, label, - &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 4) - warning ("empty case range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 310: -#line 1707 "c-parse.y" -{ - tree duplicate; - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - int success = pushcase (NULL_TREE, label, &duplicate); - stmt_count++; - if (success == 1) - error ("default label not within a switch statement"); - else if (success == 2) - { - error ("multiple default labels in one switch"); - error_with_decl (duplicate, "this is the first default label"); - } - position_after_white_space (); ; - break;} -case 311: -#line 1722 "c-parse.y" -{ tree label = define_label (input_filename, lineno, yyvsp[-1].ttype); - stmt_count++; - emit_nop (); - if (label) - expand_label (label); - position_after_white_space (); ; - break;} -case 312: -#line 1734 "c-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 313: -#line 1736 "c-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 314: -#line 1741 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 316: -#line 1748 "c-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 319: -#line 1755 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 320: -#line 1760 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 321: -#line 1765 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ; - break;} -case 322: -#line 1767 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ; - break;} -case 323: -#line 1773 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (0); ; - break;} -case 324: -#line 1777 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 326: -#line 1785 "c-parse.y" -{ tree parm; - if (pedantic) - pedwarn ("ANSI C forbids forward parameter declarations"); - /* Mark the forward decls as such. */ - for (parm = getdecls (); parm; parm = TREE_CHAIN (parm)) - TREE_ASM_WRITTEN (parm) = 1; - clear_parm_order (); ; - break;} -case 327: -#line 1793 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 328: -#line 1795 "c-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ; - break;} -case 329: -#line 1801 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 330: -#line 1803 "c-parse.y" -{ yyval.ttype = get_parm_info (0); - if (pedantic) - pedwarn ("ANSI C requires a named argument before `...'"); - ; - break;} -case 331: -#line 1808 "c-parse.y" -{ yyval.ttype = get_parm_info (1); ; - break;} -case 332: -#line 1810 "c-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 333: -#line 1815 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 334: -#line 1817 "c-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 335: -#line 1824 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 336: -#line 1826 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 337: -#line 1828 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 338: -#line 1830 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 339: -#line 1832 "c-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 340: -#line 1839 "c-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (1); ; - break;} -case 341: -#line 1843 "c-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 343: -#line 1851 "c-parse.y" -{ tree t; - for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == NULL_TREE) - error ("`...' in old-style identifier list"); - yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 344: -#line 1861 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 345: -#line 1863 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 346: -#line 1869 "c-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 347: -#line 1871 "c-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 440 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} -#line 1874 "c-parse.y" - diff --git a/gnu/usr.bin/gcc2/cc1/c-pragma.c b/gnu/usr.bin/gcc2/cc1/c-pragma.c deleted file mode 100644 index 2ff1ae701f8..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-pragma.c +++ /dev/null @@ -1,202 +0,0 @@ -/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. - Copyright (C) 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-pragma.c,v 1.1.1.1 1995/10/18 08:39:28 deraadt Exp $"; -#endif /* not lint */ - -#include -#include "config.h" -#include "tree.h" - -#ifdef HANDLE_SYSV_PRAGMA - -/* Support #pragma weak by default if WEAK_ASM_OP is defined. */ -#if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (SET_ASM_OP) -#define HANDLE_PRAGMA_WEAK 1 -#endif - -/* When structure field packing is in effect, this variable is the - number of bits to use as the maximum alignment. When packing is not - in effect, this is zero. */ - -extern int maximum_field_alignment; - -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; - -/* Handle one token of a pragma directive. TOKEN is the - current token, and STRING is its printable form. */ - -void -handle_pragma_token (string, token) - char *string; - tree token; -{ - static enum pragma_state - { - ps_start, - ps_done, - ps_bad, - ps_weak, - ps_name, - ps_equals, - ps_value, - ps_pack, - ps_left, - ps_align, - ps_right - } state = ps_start, type; - static char *name; - static char *value; - static int align; - - if (string == 0) - { - if (type == ps_pack) - { - if (state == ps_right) - maximum_field_alignment = align * 8; - else - warning ("malformed `#pragma pack'"); - } - else if (type == ps_weak) - { -#ifdef HANDLE_PRAGMA_WEAK - if (HANDLE_PRAGMA_WEAK) - { - if (state == ps_name || state == ps_value) - { - fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP); - ASM_OUTPUT_LABELREF (asm_out_file, name); - fputc ('\n', asm_out_file); - if (state == ps_value) - { - fprintf (asm_out_file, "\t%s\t", SET_ASM_OP); - ASM_OUTPUT_LABELREF (asm_out_file, name); - fputc (',', asm_out_file); - ASM_OUTPUT_LABELREF (asm_out_file, value); - fputc ('\n', asm_out_file); - } - } - else if (! (state == ps_done || state == ps_start)) - warning ("malformed `#pragma weak'"); - } -#endif /* HANDLE_PRAMA_WEAK */ - } - - type = state = ps_start; - return; - } - - switch (state) - { - case ps_start: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0) - type = state = ps_pack; - else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0) - type = state = ps_weak; - else - type = state = ps_done; - } - else - type = state = ps_done; - break; - - case ps_weak: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - name = IDENTIFIER_POINTER (token); - state = ps_name; - } - else - state = ps_bad; - break; - - case ps_name: - state = (strcmp (string, "=") ? ps_bad : ps_equals); - break; - - case ps_equals: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - value = IDENTIFIER_POINTER (token); - state = ps_value; - } - else - state = ps_bad; - break; - - case ps_value: - state = ps_bad; - break; - - case ps_pack: - if (strcmp (string, "(") == 0) - state = ps_left; - else - state = ps_bad; - break; - - case ps_left: - if (token && TREE_CODE (token) == INTEGER_CST - && TREE_INT_CST_HIGH (token) == 0) - switch (TREE_INT_CST_LOW (token)) - { - case 1: - case 2: - case 4: - align = TREE_INT_CST_LOW (token); - state = ps_align; - break; - - default: - state = ps_bad; - } - else if (! token && strcmp (string, ")") == 0) - { - align = 0; - state = ps_right; - } - else - state = ps_bad; - break; - - case ps_align: - if (strcmp (string, ")") == 0) - state = ps_right; - else - state = ps_bad; - break; - - case ps_right: - state = ps_bad; - break; - - case ps_bad: - case ps_done: - break; - - default: - abort (); - } -} -#endif /* HANDLE_SYSV_PRAGMA */ diff --git a/gnu/usr.bin/gcc2/cc1/c-typeck.c b/gnu/usr.bin/gcc2/cc1/c-typeck.c deleted file mode 100644 index 07c2b3f76f3..00000000000 --- a/gnu/usr.bin/gcc2/cc1/c-typeck.c +++ /dev/null @@ -1,5837 +0,0 @@ -/* Build expressions with type checking for C compiler. - Copyright (C) 1987, 1988, 1989, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: c-typeck.c,v 1.1.1.1 1995/10/18 08:39:28 deraadt Exp $"; -#endif /* not lint */ - -/* This file is part of the C front end. - It contains routines to build C expressions given their operands, - including computing the types of the result, C-specific error checks, - and some optimization. - - There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, - and to process initializations in declarations (since they work - like a strange sort of assignment). */ - -#include "config.h" -#include -#include "tree.h" -#include "c-tree.h" -#include "flags.h" - -/* Nonzero if we've already printed a "partly bracketed initializer" - message within this initializer. */ -static int partial_bracket_mentioned = 0; - -extern char *index (); -extern char *rindex (); - -int mark_addressable (); -static tree convert_for_assignment (); -static void warn_for_assignment (); -static int function_types_compatible_p (); -static int type_lists_compatible_p (); -int self_promoting_args_p (); -static int self_promoting_type_p (); -static int comp_target_types (); -static tree pointer_int_sum (); -static tree pointer_diff (); -static tree convert_sequence (); -static tree unary_complex_lvalue (); -static tree process_init_constructor (); -static tree convert_arguments (); -static char *get_spelling (); -tree digest_init (); -static void pedantic_lvalue_warning (); -tree truthvalue_conversion (); -void incomplete_type_error (); -void readonly_warning (); -static tree internal_build_compound_expr (); - - -/* Do `exp = require_complete_type (exp);' to make sure exp - does not have an incomplete type. (That includes void types.) */ - -tree -require_complete_type (value) - tree value; -{ - tree type = TREE_TYPE (value); - - /* First, detect a valid value with a complete type. */ - if (TYPE_SIZE (type) != 0 - && type != void_type_node) - return value; - - incomplete_type_error (value, type); - return error_mark_node; -} - -/* Print an error message for invalid use of an incomplete type. - VALUE is the expression that was used (or 0 if that isn't known) - and TYPE is the type that was invalid. */ - -void -incomplete_type_error (value, type) - tree value; - tree type; -{ - char *errmsg; - - /* Avoid duplicate error message. */ - if (TREE_CODE (type) == ERROR_MARK) - return; - - if (value != 0 && (TREE_CODE (value) == VAR_DECL - || TREE_CODE (value) == PARM_DECL)) - error ("`%s' has an incomplete type", - IDENTIFIER_POINTER (DECL_NAME (value))); - else - { - retry: - /* We must print an error message. Be clever about what it says. */ - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - errmsg = "invalid use of undefined type `struct %s'"; - break; - - case UNION_TYPE: - errmsg = "invalid use of undefined type `union %s'"; - break; - - case ENUMERAL_TYPE: - errmsg = "invalid use of undefined type `enum %s'"; - break; - - case VOID_TYPE: - error ("invalid use of void expression"); - return; - - case ARRAY_TYPE: - if (TYPE_DOMAIN (type)) - { - type = TREE_TYPE (type); - goto retry; - } - error ("invalid use of array with unspecified bounds"); - return; - - default: - abort (); - } - - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error ("invalid use of incomplete typedef `%s'", - IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - } -} - -/* Return a variant of TYPE which has all the type qualifiers of LIKE - as well as those of TYPE. */ - -static tree -qualify_type (type, like) - tree type, like; -{ - int constflag = TYPE_READONLY (type) || TYPE_READONLY (like); - int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like); - return c_build_type_variant (type, constflag, volflag); -} - -/* Return the common type of two types. - We assume that comptypes has already been done and returned 1; - if that isn't so, this may crash. In particular, we assume that qualifiers - match. - - This is the type for the result of most arithmetic operations - if the operands have the given two types. */ - -tree -common_type (t1, t2) - tree t1, t2; -{ - register enum tree_code code1; - register enum tree_code code2; - - /* Save time if the two types are the same. */ - - if (t1 == t2) return t1; - - /* If one type is nonsense, use the other. */ - if (t1 == error_mark_node) - return t2; - if (t2 == error_mark_node) - return t1; - - /* Treat an enum type as the unsigned integer type of the same width. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - - code1 = TREE_CODE (t1); - code2 = TREE_CODE (t2); - - /* If one type is complex, form the common type - of the non-complex components, - then make that complex. */ - if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - tree subtype1, subtype2, subtype; - if (code1 == COMPLEX_TYPE) - subtype1 = TREE_TYPE (t1); - else - subtype1 = t1; - if (code2 == COMPLEX_TYPE) - subtype2 = TREE_TYPE (t2); - else - subtype2 = t2; - subtype = common_type (subtype1, subtype2); - return build_complex_type (subtype); - } - - switch (code1) - { - case INTEGER_TYPE: - case REAL_TYPE: - /* If only one is real, use it as the result. */ - - if (code1 == REAL_TYPE && code2 != REAL_TYPE) - return t1; - - if (code2 == REAL_TYPE && code1 != REAL_TYPE) - return t2; - - /* Both real or both integers; use the one with greater precision. */ - - if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) - return t1; - else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) - return t2; - - /* Same precision. Prefer longs to ints even when same size. */ - - if (t1 == long_unsigned_type_node - || t2 == long_unsigned_type_node) - return long_unsigned_type_node; - - if (t1 == long_integer_type_node - || t2 == long_integer_type_node) - { - /* But preserve unsignedness from the other type, - since long cannot hold all the values of an unsigned int. */ - if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) - return long_unsigned_type_node; - return long_integer_type_node; - } - - /* Otherwise prefer the unsigned one. */ - - if (TREE_UNSIGNED (t1)) - return t1; - else return t2; - - case POINTER_TYPE: - /* For two pointers, do this recursively on the target type, - and combine the qualifiers of the two types' targets. */ - /* This code was turned off; I don't know why. - But ANSI C specifies doing this with the qualifiers. - So I turned it on again. */ - { - tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), - TYPE_MAIN_VARIANT (TREE_TYPE (t2))); - int constp - = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2)); - int volatilep - = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2)); - return build_pointer_type (c_build_type_variant (target, constp, volatilep)); - } -#if 0 - return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); -#endif - - case ARRAY_TYPE: - { - tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - /* Save space: see if the result is identical to one of the args. */ - if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) - return t1; - if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) - return t2; - /* Merge the element types, and have a size if either arg has one. */ - return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); - } - - case FUNCTION_TYPE: - /* Function types: prefer the one that specified arg types. - If both do, merge the arg types. Also merge the return types. */ - { - tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - tree p1 = TYPE_ARG_TYPES (t1); - tree p2 = TYPE_ARG_TYPES (t2); - int len; - tree newargs, n; - int i; - - /* Save space: see if the result is identical to one of the args. */ - if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2)) - return t1; - if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) - return t2; - - /* Simple way if one arg fails to specify argument types. */ - if (TYPE_ARG_TYPES (t1) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t2)); - if (TYPE_ARG_TYPES (t2) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t1)); - - /* If both args specify argument types, we must merge the two - lists, argument by argument. */ - - len = list_length (p1); - newargs = 0; - - for (i = 0; i < len; i++) - newargs = tree_cons (NULL_TREE, NULL_TREE, newargs); - - n = newargs; - - for (; p1; - p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n)) - { - /* A null type means arg type is not specified. - Take whatever the other function type has. */ - if (TREE_VALUE (p1) == 0) - { - TREE_VALUE (n) = TREE_VALUE (p2); - goto parm_done; - } - if (TREE_VALUE (p2) == 0) - { - TREE_VALUE (n) = TREE_VALUE (p1); - goto parm_done; - } - - /* Given wait (union {union wait *u; int *i} *) - and wait (union wait *), - prefer union wait * as type of parm. */ - if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE - && TREE_VALUE (p1) != TREE_VALUE (p2)) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (p1)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2))) - { - TREE_VALUE (n) = TREE_VALUE (p2); - if (pedantic) - pedwarn ("function types not truly compatible in ANSI C"); - goto parm_done; - } - } - if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE - && TREE_VALUE (p2) != TREE_VALUE (p1)) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (p2)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1))) - { - TREE_VALUE (n) = TREE_VALUE (p1); - if (pedantic) - pedwarn ("function types not truly compatible in ANSI C"); - goto parm_done; - } - } - TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); - parm_done: ; - } - - return build_function_type (valtype, newargs); - } - - default: - return t1; - } - -} - -/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment - or various other operations. Return 2 if they are compatible - but a warning may be needed if you use them together. */ - -int -comptypes (type1, type2) - tree type1, type2; -{ - register tree t1 = type1; - register tree t2 = type2; - - /* Suppress errors caused by previously reported errors. */ - - if (t1 == t2 || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK) - return 1; - - /* Treat an enum type as the unsigned integer type of the same width. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - - if (t1 == t2) - return 1; - - /* Different classes of types can't be compatible. */ - - if (TREE_CODE (t1) != TREE_CODE (t2)) return 0; - - /* Qualifiers must match. */ - - if (TYPE_READONLY (t1) != TYPE_READONLY (t2)) - return 0; - if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) - return 0; - - /* Allow for two different type nodes which have essentially the same - definition. Note that we already checked for equality of the type - type qualifiers (just above). */ - - if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return 1; - - switch (TREE_CODE (t1)) - { - case POINTER_TYPE: - return (TREE_TYPE (t1) == TREE_TYPE (t2) - ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); - - case FUNCTION_TYPE: - return function_types_compatible_p (t1, t2); - - case ARRAY_TYPE: - { - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - tree d1 = TYPE_DOMAIN (t1); - tree d2 = TYPE_DOMAIN (t2); - - /* Target types must match incl. qualifiers. */ - if (TREE_TYPE (t1) != TREE_TYPE (t2) - && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))) - return 0; - - /* Sizes must match unless one is missing or variable. */ - if (d1 == 0 || d2 == 0 || d1 == d2 - || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) - return val; - - return (((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) - && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) - && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))) - ? val : 0); - } - - case RECORD_TYPE: - if (maybe_objc_comptypes (t1, t2, 0) == 1) - return 1; - } - return 0; -} - -/* Return 1 if TTL and TTR are pointers to types that are equivalent, - ignoring their qualifiers. */ - -static int -comp_target_types (ttl, ttr) - tree ttl, ttr; -{ - int val; - - /* Give maybe_objc_comptypes a crack at letting these types through. */ - if (val = maybe_objc_comptypes (ttl, ttr, 1) >= 0) - return val; - - val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), - TYPE_MAIN_VARIANT (TREE_TYPE (ttr))); - - if (val == 2 && pedantic) - pedwarn ("types are not quite compatible"); - return val; -} - -/* Subroutines of `comptypes'. */ - -/* Return 1 if two function types F1 and F2 are compatible. - If either type specifies no argument types, - the other must specify a fixed number of self-promoting arg types. - Otherwise, if one type specifies only the number of arguments, - the other must specify that number of self-promoting arg types. - Otherwise, the argument types must match. */ - -static int -function_types_compatible_p (f1, f2) - tree f1, f2; -{ - tree args1, args2; - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int val1; - - if (!(TREE_TYPE (f1) == TREE_TYPE (f2) - || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2))))) - return 0; - - args1 = TYPE_ARG_TYPES (f1); - args2 = TYPE_ARG_TYPES (f2); - - /* An unspecified parmlist matches any specified parmlist - whose argument types don't need default promotions. */ - - if (args1 == 0) - { - if (!self_promoting_args_p (args2)) - return 0; - /* If one of these types comes from a non-prototype fn definition, - compare that with the other type's arglist. - If they don't match, ask for a warning (but no error). */ - if (TYPE_ACTUAL_ARG_TYPES (f1) - && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1))) - val = 2; - return val; - } - if (args2 == 0) - { - if (!self_promoting_args_p (args1)) - return 0; - if (TYPE_ACTUAL_ARG_TYPES (f2) - && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2))) - val = 2; - return val; - } - - /* Both types have argument lists: compare them and propagate results. */ - val1 = type_lists_compatible_p (args1, args2); - return val1 != 1 ? val1 : val; -} - -/* Check two lists of types for compatibility, - returning 0 for incompatible, 1 for compatible, - or 2 for compatible with warning. */ - -static int -type_lists_compatible_p (args1, args2) - tree args1, args2; -{ - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int newval; - - while (1) - { - if (args1 == 0 && args2 == 0) - return val; - /* If one list is shorter than the other, - they fail to match. */ - if (args1 == 0 || args2 == 0) - return 0; - /* A null pointer instead of a type - means there is supposed to be an argument - but nothing is specified about what type it has. - So match anything that self-promotes. */ - if (TREE_VALUE (args1) == 0) - { - if (! self_promoting_type_p (TREE_VALUE (args2))) - return 0; - } - else if (TREE_VALUE (args2) == 0) - { - if (! self_promoting_type_p (TREE_VALUE (args1))) - return 0; - } - else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2)))) - { - /* Allow wait (union {union wait *u; int *i} *) - and wait (union wait *) to be compatible. */ - if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE - && TYPE_NAME (TREE_VALUE (args1)) == 0 - && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST - && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)), - TYPE_SIZE (TREE_VALUE (args2)))) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (args1)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2))) - break; - if (memb == 0) - return 0; - } - else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE - && TYPE_NAME (TREE_VALUE (args2)) == 0 - && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST - && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)), - TYPE_SIZE (TREE_VALUE (args1)))) - { - tree memb; - for (memb = TYPE_FIELDS (TREE_VALUE (args2)); - memb; memb = TREE_CHAIN (memb)) - if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1))) - break; - if (memb == 0) - return 0; - } - else - return 0; - } - - /* comptypes said ok, but record if it said to warn. */ - if (newval > val) - val = newval; - - args1 = TREE_CHAIN (args1); - args2 = TREE_CHAIN (args2); - } -} - -/* Return 1 if PARMS specifies a fixed number of parameters - and none of their types is affected by default promotions. */ - -int -self_promoting_args_p (parms) - tree parms; -{ - register tree t; - for (t = parms; t; t = TREE_CHAIN (t)) - { - register tree type = TREE_VALUE (t); - - if (TREE_CHAIN (t) == 0 && type != void_type_node) - return 0; - - if (type == 0) - return 0; - - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - return 0; - } - return 1; -} - -/* Return 1 if TYPE is not affected by default promotions. */ - -static int -self_promoting_type_p (type) - tree type; -{ - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - return 0; - - return 1; -} - -/* Return an unsigned type the same as TYPE in other respects. */ - -tree -unsigned_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == signed_char_type_node || type1 == char_type_node) - return unsigned_char_type_node; - if (type1 == integer_type_node) - return unsigned_type_node; - if (type1 == short_integer_type_node) - return short_unsigned_type_node; - if (type1 == long_integer_type_node) - return long_unsigned_type_node; - if (type1 == long_long_integer_type_node) - return long_long_unsigned_type_node; - return type; -} - -/* Return a signed type the same as TYPE in other respects. */ - -tree -signed_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == unsigned_char_type_node || type1 == char_type_node) - return signed_char_type_node; - if (type1 == unsigned_type_node) - return integer_type_node; - if (type1 == short_unsigned_type_node) - return short_integer_type_node; - if (type1 == long_unsigned_type_node) - return long_integer_type_node; - if (type1 == long_long_unsigned_type_node) - return long_long_integer_type_node; - return type; -} - -/* Return a type the same as TYPE except unsigned or - signed according to UNSIGNEDP. */ - -tree -signed_or_unsigned_type (unsignedp, type) - int unsignedp; - tree type; -{ - if (TREE_CODE (type) != INTEGER_TYPE) - return type; - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - return type; -} - -/* Compute the value of the `sizeof' operator. */ - -tree -c_sizeof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a function type"); - return size_int (1); - } - if (code == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a void type"); - return size_int (1); - } - if (code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - { - error ("sizeof applied to an incomplete type"); - return size_int (0); - } - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - /* size_binop does not put the constant in range, so do it now. */ - if (TREE_CODE (t) == INTEGER_CST) - TREE_CONSTANT_OVERFLOW (t) |= force_fit_type (t, 0); - return t; -} - -tree -c_sizeof_nowarn (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE - || code == VOID_TYPE - || code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - return size_int (0); - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - force_fit_type (t, 0); - return t; -} - -/* Compute the size to increment a pointer by. */ - -tree -c_size_in_bytes (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE) - return size_int (1); - if (code == VOID_TYPE) - return size_int (1); - if (code == ERROR_MARK) - return size_int (1); - if (TYPE_SIZE (type) == 0) - { - error ("arithmetic on pointer to an incomplete type"); - return size_int (1); - } - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - force_fit_type (t, 0); - return t; -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of TYPE, measured in bytes. */ - -tree -c_alignof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - - if (code == FUNCTION_TYPE) - return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); - - if (code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); - - return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of EXPR, measured in bytes. For VAR_DECL's and - FIELD_DECL's return DECL_ALIGN (which can be set from an - "aligned" __attribute__ specification). */ - -tree -c_alignof_expr (expr) - tree expr; -{ - if (TREE_CODE (expr) == VAR_DECL) - return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT); - - if (TREE_CODE (expr) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) - { - error ("`__alignof' applied to a bit-field"); - return size_int (1); - } - else if (TREE_CODE (expr) == COMPONENT_REF - && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) - return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT); - - if (TREE_CODE (expr) == INDIRECT_REF) - { - tree t = TREE_OPERAND (expr, 0); - tree best = t; - int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - - while (TREE_CODE (t) == NOP_EXPR - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) - { - int thisalign; - - t = TREE_OPERAND (t, 0); - thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - if (thisalign > bestalign) - best = t, bestalign = thisalign; - } - return c_alignof (TREE_TYPE (TREE_TYPE (best))); - } - else - return c_alignof (TREE_TYPE (expr)); -} -/* Return either DECL or its known constant value (if it has one). */ - -static tree -decl_constant_value (decl) - tree decl; -{ - if (! TREE_PUBLIC (decl) - /* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. */ - && current_function_decl != 0 - && ! pedantic - && ! TREE_THIS_VOLATILE (decl) - && DECL_INITIAL (decl) != 0 - && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK - /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ - && TREE_CONSTANT (DECL_INITIAL (decl)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR - && DECL_MODE (decl) != BLKmode) - return DECL_INITIAL (decl); - return decl; -} - -/* Perform default promotions for C data used in expressions. - Arrays and functions are converted to pointers; - enumeral types or short or char, to int. - In addition, manifest constants symbols are replaced by their values. */ - -tree -default_conversion (exp) - tree exp; -{ - register tree type = TREE_TYPE (exp); - register enum tree_code code = TREE_CODE (type); - - /* Constants can be used directly unless they're not loadable. */ - if (TREE_CODE (exp) == CONST_DECL) - exp = DECL_INITIAL (exp); - /* Replace a nonvolatile const static variable with its value. */ - else if (optimize - && TREE_CODE (exp) == VAR_DECL - && TREE_READONLY (exp) - /* But not for iterators! */ - && !ITERATOR_P (exp) - && DECL_MODE (exp) != BLKmode) - { - exp = decl_constant_value (exp); - type = TREE_TYPE (exp); - } - - /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as - an lvalue. */ - /* Do not use STRIP_NOPS here! It will remove conversions from pointer - to integer and cause infinite recursion. */ - while (TREE_CODE (exp) == NON_LVALUE_EXPR - || (TREE_CODE (exp) == NOP_EXPR - && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp))) - exp = TREE_OPERAND (exp, 0); - - /* Normally convert enums to int, - but convert wide enums to something wider. */ - if (code == ENUMERAL_TYPE) - { - type = type_for_size (MAX (TYPE_PRECISION (type), - TYPE_PRECISION (integer_type_node)), - (flag_traditional && TREE_UNSIGNED (type))); - return convert (type, exp); - } - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - { - /* Traditionally, unsignedness is preserved in default promotions. - Also preserve unsignedness if not really getting any wider. */ - if (TREE_UNSIGNED (type) - && (flag_traditional - || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) - return convert (unsigned_type_node, exp); - return convert (integer_type_node, exp); - } - if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node) - return convert (double_type_node, exp); - if (code == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == FUNCTION_TYPE) - { - return build_unary_op (ADDR_EXPR, exp, 0); - } - if (code == ARRAY_TYPE) - { - register tree adr; - tree restype = TREE_TYPE (type); - tree ptrtype; - - if (TREE_CODE (exp) == INDIRECT_REF) - return convert (TYPE_POINTER_TO (restype), - TREE_OPERAND (exp, 0)); - - if (TREE_CODE (exp) == COMPOUND_EXPR) - { - tree op1 = default_conversion (TREE_OPERAND (exp, 1)); - return build (COMPOUND_EXPR, TREE_TYPE (op1), - TREE_OPERAND (exp, 0), op1); - } - - if (!lvalue_p (exp) - && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) - { - error ("invalid use of non-lvalue array"); - return error_mark_node; - } - - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - restype = c_build_type_variant (restype, TYPE_READONLY (type), - TYPE_VOLATILE (type)); - - ptrtype = build_pointer_type (restype); - - if (TREE_CODE (exp) == VAR_DECL) - { - /* ??? This is not really quite correct - in that the type of the operand of ADDR_EXPR - is not the target type of the type of the ADDR_EXPR itself. - Question is, can this lossage be avoided? */ - adr = build1 (ADDR_EXPR, ptrtype, exp); - if (mark_addressable (exp) == 0) - return error_mark_node; - TREE_CONSTANT (adr) = staticp (exp); - TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ - return adr; - } - /* This way is better for a COMPONENT_REF since it can - simplify the offset for a component. */ - adr = build_unary_op (ADDR_EXPR, exp, 1); - return convert (ptrtype, adr); - } - return exp; -} - -/* Make an expression to refer to the COMPONENT field of - structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */ - -tree -build_component_ref (datum, component) - tree datum, component; -{ - register tree type = TREE_TYPE (datum); - register enum tree_code code = TREE_CODE (type); - register tree field = NULL; - register tree ref; - - /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it - unless we are not to support things not strictly ANSI. */ - switch (TREE_CODE (datum)) - { - case COMPOUND_EXPR: - { - tree value = build_component_ref (TREE_OPERAND (datum, 1), component); - return build (COMPOUND_EXPR, TREE_TYPE (value), - TREE_OPERAND (datum, 0), value); - } - case COND_EXPR: - return build_conditional_expr - (TREE_OPERAND (datum, 0), - build_component_ref (TREE_OPERAND (datum, 1), component), - build_component_ref (TREE_OPERAND (datum, 2), component)); - } - - /* See if there is a field or component with name COMPONENT. */ - - if (code == RECORD_TYPE || code == UNION_TYPE) - { - if (TYPE_SIZE (type) == 0) - { - incomplete_type_error (NULL_TREE, type); - return error_mark_node; - } - - /* Look up component name in the structure type definition. - - If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers - to the field elements. Use a binary search on this array to quickly - find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC - will always be set for structures which have many elements. */ - - if (TYPE_LANG_SPECIFIC (type)) - { - int bot, top, half; - tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; - - field = TYPE_FIELDS (type); - bot = 0; - top = TYPE_LANG_SPECIFIC (type)->len; - while (top - bot > 1) - { - int cmp; - - half = (top - bot + 1) >> 1; - field = field_array[bot+half]; - cmp = (long)DECL_NAME (field) - (long)component; - if (cmp == 0) - break; - if (cmp < 0) - bot += half; - else - top = bot + half; - } - - if (DECL_NAME (field_array[bot]) == component) - field = field_array[bot]; - else if (DECL_NAME (field) != component) - field = 0; - } - else - { - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - { - if (DECL_NAME (field) == component) - break; - } - } - - if (!field) - { - error (code == RECORD_TYPE - ? "structure has no member named `%s'" - : "union has no member named `%s'", - IDENTIFIER_POINTER (component)); - return error_mark_node; - } - if (TREE_TYPE (field) == error_mark_node) - return error_mark_node; - - ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); - - if (TREE_READONLY (datum) || TREE_READONLY (field)) - TREE_READONLY (ref) = 1; - if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field)) - TREE_THIS_VOLATILE (ref) = 1; - - return ref; - } - else if (code != ERROR_MARK) - error ("request for member `%s' in something not a structure or union", - IDENTIFIER_POINTER (component)); - - return error_mark_node; -} - -/* Given an expression PTR for a pointer, return an expression - for the value pointed to. - ERRORSTRING is the name of the operator to appear in error messages. */ - -tree -build_indirect_ref (ptr, errorstring) - tree ptr; - char *errorstring; -{ - register tree pointer = default_conversion (ptr); - register tree type = TREE_TYPE (pointer); - - if (TREE_CODE (type) == POINTER_TYPE) - { - if (TREE_CODE (pointer) == ADDR_EXPR - && !flag_volatile - && (TREE_TYPE (TREE_OPERAND (pointer, 0)) - == TREE_TYPE (type))) - return TREE_OPERAND (pointer, 0); - else - { - tree t = TREE_TYPE (type); - register tree ref = build1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (t), pointer); - - if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE) - { - error ("dereferencing pointer to incomplete type"); - return error_mark_node; - } - if (TREE_CODE (t) == VOID_TYPE) - warning ("dereferencing `void *' pointer"); - - /* We *must* set TREE_READONLY when dereferencing a pointer to const, - so that we get the proper error message if the result is used - to assign to. Also, &* is supposed to be a no-op. - And ANSI C seems to specify that the type of the result - should be the const type. */ - /* A de-reference of a pointer to const is not a const. It is valid - to change it via some other pointer. */ - TREE_READONLY (ref) = TYPE_READONLY (t); - TREE_SIDE_EFFECTS (ref) - = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; - TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t) || flag_volatile; - return ref; - } - } - else if (TREE_CODE (pointer) != ERROR_MARK) - error ("invalid type argument of `%s'", errorstring); - return error_mark_node; -} - -/* This handles expressions of the form "a[i]", which denotes - an array reference. - - This is logically equivalent in C to *(a+i), but we may do it differently. - If A is a variable or a member, we generate a primitive ARRAY_REF. - This avoids forcing the array out of registers, and can work on - arrays that are not lvalues (for example, members of structures returned - by functions). */ - -tree -build_array_ref (array, index) - tree array, index; -{ - if (index == 0) - { - error ("subscript missing in array reference"); - return error_mark_node; - } - - if (TREE_TYPE (array) == error_mark_node - || TREE_TYPE (index) == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE - && TREE_CODE (array) != INDIRECT_REF) - { - tree rval, type; - - /* Subscripting with type char is likely to lose - on a machine where chars are signed. - So warn on any machine, but optionally. - Don't warn for unsigned char since that type is safe. - Don't warn for signed char because anyone who uses that - must have done so deliberately. */ - if (warn_char_subscripts - && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) - warning ("array subscript has type `char'"); - - /* Apply default promotions *after* noticing character types. */ - index = default_conversion (index); - - /* Require integer *after* promotion, for sake of enums. */ - if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - /* An array that is indexed by a non-constant - cannot be stored in a register; we must be able to do - address arithmetic on its address. - Likewise an array of elements of variable size. */ - if (TREE_CODE (index) != INTEGER_CST - || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0 - && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) - { - if (mark_addressable (array) == 0) - return error_mark_node; - } - - if (pedantic && !lvalue_p (array)) - { - if (DECL_REGISTER (array)) - pedwarn ("ANSI C forbids subscripting `register' array"); - else - pedwarn ("ANSI C forbids subscripting non-lvalue array"); - } - - if (pedantic) - { - tree foo = array; - while (TREE_CODE (foo) == COMPONENT_REF) - foo = TREE_OPERAND (foo, 0); - if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) - pedwarn ("ANSI C forbids subscripting non-lvalue array"); - } - - type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array))); - rval = build (ARRAY_REF, type, array, index); - /* Array ref is const/volatile if the array elements are - or if the array is. */ - TREE_READONLY (rval) - |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) - | TREE_READONLY (array)); - TREE_SIDE_EFFECTS (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - | TREE_SIDE_EFFECTS (array)); - TREE_THIS_VOLATILE (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - /* This was added by rms on 16 Nov 91. - It fixes vol struct foo *a; a->elts[1] - in an inline function. - Hope it doesn't break something else. */ - | TREE_THIS_VOLATILE (array)); - return require_complete_type (fold (rval)); - } - - { - tree ar = default_conversion (array); - tree ind = default_conversion (index); - - /* Put the integer in IND to simplify error checking. */ - if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE) - { - tree temp = ar; - ar = ind; - ind = temp; - } - - if (ar == error_mark_node) - return ar; - - if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE) - { - error ("subscripted value is neither array nor pointer"); - return error_mark_node; - } - if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0), - "array indexing"); - } -} - -/* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against PARAMS. */ - -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - -#define T_I &integer_type_node -#define T_L &long_integer_type_node -#define T_LL &long_long_integer_type_node -#define T_S &short_integer_type_node -#define T_UI &unsigned_type_node -#define T_UL &long_unsigned_type_node -#define T_ULL &long_long_unsigned_type_node -#define T_US &short_unsigned_type_node -#define T_F &float_type_node -#define T_D &double_type_node -#define T_LD &long_double_type_node -#define T_C &char_type_node -#define T_V &void_type_node -#define T_W &wchar_type_node - -typedef struct -{ - char *format_chars; - int pointer_count; - /* Type of argument if no length modifier is used. */ - tree *nolen; - /* Type of argument if length modifier for shortening is used. - If NULL, then this modifier is not allowed. */ - tree *hlen; - /* Type of argument if length modifier `l' is used. - If NULL, then this modifier is not allowed. */ - tree *llen; - /* Type of argument if length modifier `q' is used. - If NULL, then this modifier is not allowed. */ - tree *qlen; - /* Type of argument if length modifier `L' is used. - If NULL, then this modifier is not allowed. */ - tree *bigllen; - /* List of other modifier characters allowed with these options. */ - char *flag_chars; -} format_char_info; - -static format_char_info print_table[] - = { - { "di", 0, T_I, T_I, T_L, T_LL, NULL, "-wp0 +" }, - { "oxX", 0, T_UI, T_UI, T_UL, T_ULL, NULL, "-wp0#" }, - { "u", 0, T_UI, T_UI, T_UL, T_ULL, NULL, "-wp0" }, - { "feEgG", 0, T_D, NULL, NULL, NULL, T_LD, "-wp0 +#" }, - { "c", 0, T_I, NULL, T_W, NULL, NULL, "-w" }, - { "C", 0, T_W, NULL, NULL, NULL, NULL, "-w" }, - { "s", 1, T_C, NULL, T_W, NULL, NULL, "-wp" }, - { "S", 1, T_W, NULL, NULL, NULL, NULL, "-wp" }, - { "p", 1, T_V, NULL, NULL, NULL, NULL, "-" }, - { "n", 1, T_I, T_S, T_L, T_LL, NULL, "" }, - { NULL } - }; - -static format_char_info scan_table[] - = { - { "di", 1, T_I, T_S, T_L, T_LL, NULL, "*" }, - { "ouxX", 1, T_UI, T_US, T_UL, T_ULL, NULL, "*" }, - { "efgEG", 1, T_F, NULL, T_D, NULL, T_LD, "*" }, - { "sc", 1, T_C, NULL, T_W, NULL, NULL, "*" }, - { "[", 1, T_C, NULL, NULL, NULL, NULL, "*" }, - { "C", 1, T_W, NULL, NULL, NULL, NULL, "*" }, - { "S", 1, T_W, NULL, NULL, NULL, NULL, "*" }, - { "p", 2, T_V, NULL, NULL, NULL, NULL, "*" }, - { "n", 1, T_I, T_S, T_L, T_LL, NULL, "" }, - { NULL } - }; - -typedef struct -{ - tree function_ident; /* identifier such as "printf" */ - int is_scan; /* TRUE if *scanf */ - int format_num; /* number of format argument */ - int first_arg_num; /* number of first arg (zero for varargs) */ -} function_info; - -static unsigned int function_info_entries = 0; -static function_info *function_info_table = NULL; - -/* Record information for argument format checking. FUNCTION_IDENT is - the identifier node for the name of the function to check (its decl - need not exist yet). IS_SCAN is true for scanf-type format checking; - false indicates printf-style format checking. FORMAT_NUM is the number - of the argument which is the format control string (starting from 1). - FIRST_ARG_NUM is the number of the first actual argument to check - against teh format string, or zero if no checking is not be done - (e.g. for varargs such as vfprintf). */ - -void -record_format_info (function_ident, is_scan, format_num, first_arg_num) - tree function_ident; - int is_scan; - int format_num; - int first_arg_num; -{ - function_info *info; - - function_info_entries++; - if (function_info_table) - function_info_table - = (function_info *) xrealloc (function_info_table, - function_info_entries * sizeof (function_info)); - else - function_info_table = (function_info *) xmalloc (sizeof (function_info)); - - info = &function_info_table[function_info_entries - 1]; - - info->function_ident = function_ident; - info->is_scan = is_scan; - info->format_num = format_num; - info->first_arg_num = first_arg_num; -} - -/* Initialize the table of functions to perform format checking on. - The ANSI functions are always checked (whether is - included or not), since it is common to call printf without - including . There shouldn't be a problem with this, - since ANSI reserves these function names whether you include the - header file or not. In any case, the checking is harmless. */ - -void -init_format_info_table () -{ - record_format_info (get_identifier ("printf"), 0, 1, 2); - record_format_info (get_identifier ("fprintf"), 0, 2, 3); - record_format_info (get_identifier ("sprintf"), 0, 2, 3); - record_format_info (get_identifier ("scanf"), 1, 1, 2); - record_format_info (get_identifier ("fscanf"), 1, 2, 3); - record_format_info (get_identifier ("sscanf"), 1, 2, 3); - record_format_info (get_identifier ("vprintf"), 0, 1, 0); - record_format_info (get_identifier ("vfprintf"), 0, 2, 0); - record_format_info (get_identifier ("vsprintf"), 0, 2, 0); -} - -static char tfaff[] = "too few arguments for format"; - -/* Check the argument list of a call to printf, scanf, etc. - INFO points to the element of function_info_table. - PARAMS is the list of argument values. */ - -static void -check_format (info, params) - function_info *info; - tree params; -{ - int i; - int arg_num; - int suppressed, wide, precise; - int length_char; - int format_char; - int format_length; - tree format_tree; - tree cur_param; - tree cur_type; - tree wanted_type; - char *format_chars; - format_char_info *fci; - static char message[132]; - char flag_chars[8]; - - /* Skip to format argument. If the argument isn't available, there's - no work for us to do; prototype checking will catch the problem. */ - for (arg_num = 1; ; ++arg_num) - { - if (params == 0) - return; - if (arg_num == info->format_num) - break; - params = TREE_CHAIN (params); - } - format_tree = TREE_VALUE (params); - params = TREE_CHAIN (params); - if (format_tree == 0) - return; - /* We can only check the format if it's a string constant. */ - while (TREE_CODE (format_tree) == NOP_EXPR) - format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */ - if (format_tree == null_pointer_node) - { - warning ("null format string"); - return; - } - if (TREE_CODE (format_tree) != ADDR_EXPR) - return; - format_tree = TREE_OPERAND (format_tree, 0); - if (TREE_CODE (format_tree) != STRING_CST) - return; - format_chars = TREE_STRING_POINTER (format_tree); - format_length = TREE_STRING_LENGTH (format_tree); - if (format_length <= 1) - warning ("zero-length format string"); - if (format_chars[--format_length] != 0) - { - warning ("unterminated format string"); - return; - } - /* Skip to first argument to check. */ - while (arg_num + 1 < info->first_arg_num) - { - if (params == 0) - return; - params = TREE_CHAIN (params); - ++arg_num; - } - while (1) - { - if (*format_chars == 0) - { - if (format_chars - TREE_STRING_POINTER (format_tree) != format_length) - warning ("embedded `\\0' in format"); - if (info->first_arg_num != 0 && params != 0) - warning ("too many arguments for format"); - return; - } - if (*format_chars++ != '%') - continue; - if (*format_chars == 0) - { - warning ("spurious trailing `%%' in format"); - continue; - } - if (*format_chars == '%') - { - ++format_chars; - continue; - } - flag_chars[0] = 0; - suppressed = wide = precise = FALSE; - if (info->is_scan) - { - suppressed = *format_chars == '*'; - if (suppressed) - ++format_chars; - while (ISDIGIT (*format_chars)) - ++format_chars; - } - else - { - while (*format_chars != 0 && index (" +#0-", *format_chars) != 0) - { - if (index (flag_chars, *format_chars) != 0) - { - sprintf (message, "repeated `%c' flag in format", - *format_chars); - warning (message); - } - i = strlen (flag_chars); - flag_chars[i++] = *format_chars++; - flag_chars[i] = 0; - } - /* "If the space and + flags both appear, - the space flag will be ignored." */ - if (index (flag_chars, ' ') != 0 - && index (flag_chars, '+') != 0) - warning ("use of both ` ' and `+' flags in format"); - /* "If the 0 and - flags both appear, - the 0 flag will be ignored." */ - if (index (flag_chars, '0') != 0 - && index (flag_chars, '-') != 0) - warning ("use of both `0' and `-' flags in format"); - if (*format_chars == '*') - { - wide = TRUE; - /* "...a field width...may be indicated by an asterisk. - In this case, an int argument supplies the field width..." */ - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - if (info->first_arg_num != 0) - { - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - /* size_t is generally not valid here. - It will work on most machines, because size_t and int - have the same mode. But might as well warn anyway, - since it will fail on other machines. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - { - wide = TRUE; - ++format_chars; - } - } - if (*format_chars == '.') - { - precise = TRUE; - ++format_chars; - if (*format_chars != '*' && !ISDIGIT (*format_chars)) - warning ("`.' not followed by `*' or digit in format"); - /* "...a...precision...may be indicated by an asterisk. - In this case, an int argument supplies the...precision." */ - if (*format_chars == '*') - { - if (info->first_arg_num != 0) - { - ++format_chars; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param)) - != integer_type_node) - { - sprintf (message, - "field width is not type int (arg %d)", - arg_num); - warning (message); - } - } - } - else - { - while (ISDIGIT (*format_chars)) - ++format_chars; - } - } - } - if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'q' || - *format_chars == 'L') - length_char = *format_chars++; - else - length_char = 0; - if (suppressed && length_char != 0) - { - sprintf (message, - "use of `*' and `%c' together in format", - length_char); - warning (message); - } - format_char = *format_chars; - if (format_char == 0) - { - warning ("conversion lacks type at end of format"); - continue; - } - format_chars++; - fci = info->is_scan ? scan_table : print_table; - while (1) - { - if (fci->format_chars == 0 - || index (fci->format_chars, format_char) != 0) - break; - ++fci; - } - if (fci->format_chars == 0) - { - if (format_char >= 040 && format_char < 0177) - sprintf (message, - "unknown conversion type character `%c' in format", - format_char); - else - sprintf (message, - "unknown conversion type character 0x%x in format", - format_char); - warning (message); - continue; - } - if (wide && index (fci->flag_chars, 'w') == 0) - { - sprintf (message, "width used with `%c' format", - format_char); - warning (message); - } - if (precise && index (fci->flag_chars, 'p') == 0) - { - sprintf (message, "precision used with `%c' format", - format_char); - warning (message); - } - if (suppressed) - { - if (index (fci->flag_chars, '*') == 0) - { - sprintf (message, - "suppression of `%c' conversion in format", - format_char); - warning (message); - } - continue; - } - for (i = 0; flag_chars[i] != 0; ++i) - { - if (index (fci->flag_chars, flag_chars[i]) == 0) - { - sprintf (message, "flag `%c' used with type `%c'", - flag_chars[i], format_char); - warning (message); - } - } - if (precise && index (flag_chars, '0') != 0 - && (format_char == 'd' || format_char == 'i' - || format_char == 'o' || format_char == 'u' - || format_char == 'x' || format_char == 'x')) - { - sprintf (message, - "precision and `0' flag not both allowed with `%c' format", - format_char); - warning (message); - } - switch (length_char) - { - default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break; - case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break; - case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break; - case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break; - case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break; - } - if (wanted_type == 0) - { - sprintf (message, - "use of `%c' length character with `%c' type character", - length_char, format_char); - warning (message); - } - - /* - ** XXX -- should kvetch about stuff such as - ** { - ** const int i; - ** - ** scanf ("%d", &i); - ** } - */ - - /* Finally. . .check type of argument against desired type! */ - if (info->first_arg_num == 0) - continue; - if (params == 0) - { - warning (tfaff); - return; - } - cur_param = TREE_VALUE (params); - params = TREE_CHAIN (params); - ++arg_num; - cur_type = TREE_TYPE (cur_param); - - /* Check the types of any additional pointer arguments - that precede the "real" argument. */ - for (i = 0; i < fci->pointer_count; ++i) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - { - cur_type = TREE_TYPE (cur_type); - continue; - } - sprintf (message, - "format argument is not a %s (arg %d)", - ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"), - arg_num); - warning (message); - break; - } - - /* Check the type of the "real" argument, if there's a type we want. */ - if (i == fci->pointer_count && wanted_type != 0 - && wanted_type != TYPE_MAIN_VARIANT (cur_type) - /* If we want `void *', allow any pointer type. - (Anything else would already have got a warning.) */ - && ! (wanted_type == void_type_node - && fci->pointer_count > 0) - /* Don't warn about differences merely in signedness. */ - && !(TREE_CODE (wanted_type) == INTEGER_TYPE - && TREE_CODE (cur_type) == INTEGER_TYPE - && TYPE_PRECISION (wanted_type) == TYPE_PRECISION (cur_type))) - { - register char *this; - register char *that; - - this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type))); - that = 0; - if (TREE_CODE (cur_type) != ERROR_MARK - && TYPE_NAME (cur_type) != 0 - && TREE_CODE (cur_type) != INTEGER_TYPE - && !(TREE_CODE (cur_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE)) - { - if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (cur_type)) != 0) - that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type))); - else - that = IDENTIFIER_POINTER (TYPE_NAME (cur_type)); - } - - /* A nameless type can't possibly match what the format wants. - So there will be a warning for it. - Make up a string to describe vaguely what it is. */ - if (that == 0) - { - if (TREE_CODE (cur_type) == POINTER_TYPE) - that = "pointer"; - else - that = "different type"; - } - - if (strcmp (this, that) != 0) - { - sprintf (message, "%s format, %s arg (arg %d)", - this, that, arg_num); - warning (message); - } - } - } -} - -/* Build a function call to function FUNCTION with parameters PARAMS. - PARAMS is a list--a chain of TREE_LIST nodes--in which the - TREE_VALUE of each node is a parameter-expression. - FUNCTION's data type may be a function type or a pointer-to-function. */ - -tree -build_function_call (function, params) - tree function, params; -{ - register tree fntype, fundecl; - register tree coerced_params; - tree name = NULL_TREE; - - /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (function); - - /* Convert anything with function type to a pointer-to-function. */ - if (TREE_CODE (function) == FUNCTION_DECL) - { - name = DECL_NAME (function); - /* Differs from default_conversion by not setting TREE_ADDRESSABLE - (because calling an inline function does not mean the function - needs to be separately compiled). */ - fntype = build_type_variant (TREE_TYPE (function), - TREE_READONLY (function), - TREE_THIS_VOLATILE (function)); - fundecl = function; - function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); - } - else - function = default_conversion (function); - - fntype = TREE_TYPE (function); - - if (TREE_CODE (fntype) == ERROR_MARK) - return error_mark_node; - - if (!(TREE_CODE (fntype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) - { - error ("called object is not a function"); - return error_mark_node; - } - - /* fntype now gets the type of function pointed to. */ - fntype = TREE_TYPE (fntype); - - /* Convert the parameters to the types declared in the - function prototype, or apply default promotions. */ - - coerced_params - = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl); - - /* Check for errors in format strings. */ - if (warn_format && name != 0) - { - unsigned int i; - - /* See if this function is a format function. */ - for (i = 0; i < function_info_entries; i++) - if (function_info_table[i].function_ident == name) - { - register char *message; - - /* If so, check it. */ - check_format (&function_info_table[i], coerced_params); - break; - } - } - - /* Recognize certain built-in functions so we can make tree-codes - other than CALL_EXPR. We do this when it enables fold-const.c - to do something useful. */ - - if (TREE_CODE (function) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL - && DECL_BUILT_IN (TREE_OPERAND (function, 0))) - switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0))) - { - case BUILT_IN_ABS: - case BUILT_IN_LABS: - case BUILT_IN_FABS: - if (coerced_params == 0) - return integer_zero_node; - return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0); - } - - { - register tree result - = build (CALL_EXPR, TREE_TYPE (fntype), - function, coerced_params, NULL_TREE); - - TREE_SIDE_EFFECTS (result) = 1; - if (TREE_TYPE (result) == void_type_node) - return result; - return require_complete_type (result); - } -} - -/* Convert the argument expressions in the list VALUES - to the types in the list TYPELIST. The result is a list of converted - argument expressions. - - If TYPELIST is exhausted, or when an element has NULL as its type, - perform the default conversions. - - PARMLIST is the chain of parm decls for the function being called. - It may be 0, if that info is not available. - It is used only for generating error messages. - - NAME is an IDENTIFIER_NODE or 0. It is used only for error messages. - - This is also where warnings about wrong number of args are generated. - - Both VALUES and the returned value are chains of TREE_LIST nodes - with the elements of the list in the TREE_VALUE slots of those nodes. */ - -static tree -convert_arguments (typelist, values, name, fundecl) - tree typelist, values, name, fundecl; -{ - register tree typetail, valtail; - register tree result = NULL; - int parmnum; - - /* Scan the given expressions and types, producing individual - converted arguments and pushing them on RESULT in reverse order. */ - - for (valtail = values, typetail = typelist, parmnum = 0; - valtail; - valtail = TREE_CHAIN (valtail), parmnum++) - { - register tree type = typetail ? TREE_VALUE (typetail) : 0; - register tree val = TREE_VALUE (valtail); - - if (type == void_type_node) - { - if (name) - error ("too many arguments to function `%s'", - IDENTIFIER_POINTER (name)); - else - error ("too many arguments to function"); - break; - } - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here! We do not want an enumerator with value 0 - to convert automatically to a pointer. */ - if (TREE_CODE (val) == NON_LVALUE_EXPR) - val = TREE_OPERAND (val, 0); - - if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE) - val = default_conversion (val); - - val = require_complete_type (val); - - if (type != 0) - { - /* Formal parm type is specified by a function prototype. */ - tree parmval; - - if (TYPE_SIZE (type) == 0) - { - error ("type of formal parameter %d is incomplete", parmnum + 1); - parmval = val; - } - else - { - tree parmname; -#ifdef PROMOTE_PROTOTYPES - /* Rather than truncating and then reextending, - convert directly to int, if that's the type we will want. */ - if (! flag_traditional - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - type = integer_type_node; -#endif - -#if 0 /* This turns out not to win--there's no way to write a prototype - for a function whose arg type is a union with no tag. */ - /* Nameless union automatically casts the types it contains. */ - if (TREE_CODE (type) == UNION_TYPE && TYPE_NAME (type) == 0) - { - tree field; - - for (field = TYPE_FIELDS (type); field; - field = TREE_CHAIN (field)) - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), - TYPE_MAIN_VARIANT (TREE_TYPE (val)))) - break; - - if (field) - val = build1 (CONVERT_EXPR, type, val); - } -#endif - - /* Optionally warn about conversions that - differ from the default conversions. */ - if (warn_conversion) - { - int formal_prec = TYPE_PRECISION (type); - - if (TREE_CODE (type) != REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) - warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) != REAL_TYPE) - warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) - { - /* Warn if any argument is passed as `float', - since without a prototype it would be `double'. */ - if (formal_prec == TYPE_PRECISION (float_type_node)) - warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1); - } - /* Detect integer changing in width or signedness. */ - else if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TREE_CODE (TREE_TYPE (val)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE)) - { - tree would_have_been = default_conversion (val); - tree type1 = TREE_TYPE (would_have_been); - - if (TREE_CODE (type) == ENUMERAL_TYPE - && type == TREE_TYPE (val)) - /* No warning if function asks for enum - and the actual arg is that enum type. */ - ; - else if (formal_prec != TYPE_PRECISION (type1)) - warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1); - else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1)) - ; - /* Don't complain if the formal parameter type - is an enum, because we can't tell now whether - the value was an enum--even the same enum. */ - else if (TREE_CODE (type) == ENUMERAL_TYPE) - ; - else if (TREE_CODE (val) == INTEGER_CST - && int_fits_type_p (val, type)) - /* Change in signedness doesn't matter - if a constant value is unaffected. */ - ; - else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE - && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type) - && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type)) - /* Change in signedness doesn't matter - if an enum value is unaffected. */ - ; - else if (TREE_UNSIGNED (type)) - warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1); - else - warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1); - } - } - - parmval = convert_for_assignment (type, val, - (char *)0, /* arg passing */ - fundecl, name, parmnum + 1); - -#ifdef PROMOTE_PROTOTYPES - if (TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - parmval = default_conversion (parmval); -#endif - } - result = tree_cons (NULL_TREE, parmval, result); - } - else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (val)) - < TYPE_PRECISION (double_type_node))) - /* Convert `float' to `double'. */ - result = tree_cons (NULL_TREE, convert (double_type_node, val), result); - else - /* Convert `short' and `char' to full-size `int'. */ - result = tree_cons (NULL_TREE, default_conversion (val), result); - - if (typetail) - typetail = TREE_CHAIN (typetail); - } - - if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) - { - if (name) - error ("too few arguments to function `%s'", - IDENTIFIER_POINTER (name)); - else - error ("too few arguments to function"); - } - - return nreverse (result); -} - -/* This is the entry point used by the parser - for binary operators in the input. - In addition to constructing the expression, - we check for operands that were written with other binary operators - in a way that is likely to confuse the user. */ - -tree -parser_build_binary_op (code, arg1, arg2) - enum tree_code code; - tree arg1, arg2; -{ - tree result = build_binary_op (code, arg1, arg2, 1); - - char class; - char class1 = TREE_CODE_CLASS (TREE_CODE (arg1)); - char class2 = TREE_CODE_CLASS (TREE_CODE (arg2)); - enum tree_code code1 = ERROR_MARK; - enum tree_code code2 = ERROR_MARK; - - if (class1 == 'e' || class1 == '1' - || class1 == '2' || class1 == '<') - code1 = C_EXP_ORIGINAL_CODE (arg1); - if (class2 == 'e' || class2 == '1' - || class2 == '2' || class2 == '<') - code2 = C_EXP_ORIGINAL_CODE (arg2); - - /* Check for cases such as x+y< TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) - { - final_type = result_type; - op1 = TREE_OPERAND (op1, 0); - result_type = TREE_TYPE (op1); - } - if (TREE_CODE (op1) == INTEGER_CST - && TREE_CODE (op0) == NOP_EXPR - && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - { - final_type = result_type; - op0 = TREE_OPERAND (op0, 0); - result_type = TREE_TYPE (op0); - } - break; - - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - shorten = 1; - break; - - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE - || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE - || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) - { - /* Result of these operations is always an int, - but that does not mean the operands should be - converted to ints! */ - result_type = integer_type_node; - op0 = truthvalue_conversion (op0); - op1 = truthvalue_conversion (op1); - converted = 1; - } - break; - - /* Shift operations: result has same type as first operand; - always convert second operand to int. - Also set SHORT_SHIFT if shifting rightward. */ - - case RSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("right shift count is negative"); - else - { - if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1)) - short_shift = 1; - if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("right shift count >= width of type"); - } - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case LSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("left shift count is negative"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("left shift count >= width of type"); - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case RROTATE_EXPR: - case LROTATE_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("shift count is negative"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("shift count >= width of type"); - } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ - result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - } - break; - - case EQ_EXPR: - case NE_EXPR: - /* Result of comparison is always int, - but don't convert the args to int! */ - result_type = integer_type_node; - converted = 1; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - register tree tt0 = TREE_TYPE (type0); - register tree tt1 = TREE_TYPE (type1); - /* Anything compares with void *. void * compares with anything. - Otherwise, the targets must be the same. */ - if (comp_target_types (type0, type1)) - ; - else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) - { - if (pedantic && !integer_zerop (op0) - && TREE_CODE (tt1) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); - } - else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) - { - if (pedantic && !integer_zerop (op1) - && TREE_CODE (tt0) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); - } - else - pedwarn ("comparison of distinct pointer types lacks a cast"); - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - op1 = null_pointer_node; - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - op0 = null_pointer_node; - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op1 = convert (TREE_TYPE (op0), op1); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op0 = convert (TREE_TYPE (op1), op0); - } - else - /* If args are not valid, clear out RESULT_TYPE - to cause an error message later. */ - result_type = 0; - break; - - case MAX_EXPR: - case MIN_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - shorten = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (! comp_target_types (type0, type1)) - pedwarn ("comparison of distinct pointer types lacks a cast"); - else if (pedantic - && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); - result_type = common_type (type0, type1); - } - break; - - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (! comp_target_types (type0, type1)) - pedwarn ("comparison of distinct pointer types lacks a cast"); - else if (pedantic - && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); - result_type = integer_type_node; - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - { - result_type = integer_type_node; - op1 = null_pointer_node; - if (! flag_traditional) - pedwarn ("ordered comparison of pointer with integer zero"); - } - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - { - result_type = integer_type_node; - op0 = null_pointer_node; - if (pedantic) - pedwarn ("ordered comparison of pointer with integer zero"); - } - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = integer_type_node; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op1 = convert (TREE_TYPE (op0), op1); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = integer_type_node; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); - op0 = convert (TREE_TYPE (op1), op0); - } - converted = 1; - break; - } - - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && - (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) - { - int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); - - if (shorten || common || short_compare) - result_type = common_type (type0, type1); - - /* For certain operations (which identify themselves by shorten != 0) - if both args were extended from the same smaller type, - do the arithmetic in that type and then extend. - - shorten !=0 and !=1 indicates a bitwise operation. - For them, this optimization is safe only if - both args are zero-extended or both are sign-extended. - Otherwise, we might change the result. - Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. */ - - if (shorten && none_complex) - { - int unsigned0, unsigned1; - tree arg0 = get_narrower (op0, &unsigned0); - tree arg1 = get_narrower (op1, &unsigned1); - /* UNS is 1 if the operation to be done is an unsigned one. */ - int uns = TREE_UNSIGNED (result_type); - tree type; - - final_type = result_type; - - /* Handle the case that OP0 (or OP1) does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if ((TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && TREE_TYPE (op0) != final_type) - unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0)); - if ((TYPE_PRECISION (TREE_TYPE (op1)) - == TYPE_PRECISION (TREE_TYPE (arg1))) - && TREE_TYPE (op1) != final_type) - unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1)); - - /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ - - /* For bitwise operations, signedness of nominal type - does not matter. Consider only how operands were extended. */ - if (shorten == -1) - uns = unsigned0; - - /* Note that in all three cases below we refrain from optimizing - an unsigned operation on sign-extended args. - That would not be valid. */ - - /* Both args variable: if both extended in same way - from same width, do it in that width. - Do it unsigned if args were zero-extended. */ - if ((TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && unsigned0 == unsigned1 - && (unsigned0 || !uns)) - result_type - = signed_or_unsigned_type (unsigned0, - common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); - else if (TREE_CODE (arg0) == INTEGER_CST - && (unsigned1 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1)), - int_fits_type_p (arg0, type))) - result_type = type; - else if (TREE_CODE (arg1) == INTEGER_CST - && (unsigned0 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0)), - int_fits_type_p (arg1, type))) - result_type = type; - } - - /* Shifts can be shortened if shifting right. */ - - if (short_shift) - { - int unsigned_arg; - tree arg0 = get_narrower (op0, &unsigned_arg); - - final_type = result_type; - - if (arg0 == op0 && final_type == TREE_TYPE (op0)) - unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0)); - - if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) - /* If arg is sign-extended and then unsigned-shifted, - we can simulate this with a signed shift in arg's type - only if the extended result is at least twice as wide - as the arg. Otherwise, the shift could use up all the - ones made by sign-extension and bring in zeros. - We can't optimize that case at all, but in most machines - it never happens because available widths are 2**N. */ - && (!TREE_UNSIGNED (final_type) - || unsigned_arg - || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type))) - { - /* Do an unsigned shift if the operand was zero-extended. */ - result_type - = signed_or_unsigned_type (unsigned_arg, - TREE_TYPE (arg0)); - /* Convert value-to-be-shifted to that type. */ - if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); - converted = 1; - } - } - - /* Comparison operations are shortened too but differently. - They identify themselves by setting short_compare = 1. */ - - if (short_compare && none_complex) - { - /* Don't write &op0, etc., because that would prevent op0 - from being kept in a register. - Instead, make copies of the our local variables and - pass the copies by reference, then copy them back afterward. */ - tree xop0 = op0, xop1 = op1, xresult_type = result_type; - enum tree_code xresultcode = resultcode; - tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); - if (val != 0) - return val; - op0 = xop0, op1 = xop1, result_type = xresult_type; - resultcode = xresultcode; - - if (extra_warnings) - { - tree op0_type = TREE_TYPE (orig_op0); - tree op1_type = TREE_TYPE (orig_op1); - int op0_unsigned = TREE_UNSIGNED (op0_type); - int op1_unsigned = TREE_UNSIGNED (op1_type); - - /* Give warnings for comparisons between signed and unsigned - quantities that will fail. Do not warn if the signed quantity - is an unsuffixed integer literal (or some static constant - expression involving such literals) and it is positive. - Do not warn if the width of the unsigned quantity is less - than that of the signed quantity, since in this case all - values of the unsigned quantity fit in the signed quantity. - Do not warn if the signed type is the same size as the - result_type since sign extension does not cause trouble in - this case. */ - /* Do the checking based on the original operand trees, so that - casts will be considered, but default promotions won't be. */ - if (op0_unsigned != op1_unsigned - && ((op0_unsigned - && TYPE_PRECISION (op0_type) >= TYPE_PRECISION (op1_type) - && TYPE_PRECISION (op0_type) < TYPE_PRECISION (result_type) - && (TREE_CODE (op1) != INTEGER_CST - || (TREE_CODE (op1) == INTEGER_CST - && INT_CST_LT (op1, integer_zero_node)))) - || - (op1_unsigned - && TYPE_PRECISION (op1_type) >= TYPE_PRECISION (op0_type) - && TYPE_PRECISION (op1_type) < TYPE_PRECISION (result_type) - && (TREE_CODE (op0) != INTEGER_CST - || (TREE_CODE (op0) == INTEGER_CST - && INT_CST_LT (op0, integer_zero_node)))))) - warning ("comparison between signed and unsigned"); - } - } - } - - /* At this point, RESULT_TYPE must be nonzero to avoid an error message. - If CONVERTED is zero, both args will be converted to type RESULT_TYPE. - Then the expression will be built. - It will be given type FINAL_TYPE if that is nonzero; - otherwise, it will be given type RESULT_TYPE. */ - - if (!result_type) - { - binary_op_error (code); - return error_mark_node; - } - - if (! converted) - { - if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); - if (TREE_TYPE (op1) != result_type) - op1 = convert (result_type, op1); - } - - { - register tree result = build (resultcode, result_type, op0, op1); - register tree folded; - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - if (final_type != 0) - return convert (final_type, folded); - return folded; - } -} - -/* Return a tree for the sum or difference (RESULTCODE says which) - of pointer PTROP and integer INTOP. */ - -static tree -pointer_int_sum (resultcode, ptrop, intop) - enum tree_code resultcode; - register tree ptrop, intop; -{ - tree size_exp; - - register tree result; - register tree folded; - - /* The result is a pointer of the same type that is being added. */ - - register tree result_type = TREE_TYPE (ptrop); - - if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("pointer of type `void *' used in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("pointer to a function used in arithmetic"); - size_exp = integer_one_node; - } - else - size_exp = c_size_in_bytes (TREE_TYPE (result_type)); - - /* If what we are about to multiply by the size of the elements - contains a constant term, apply distributive law - and multiply that constant term separately. - This helps produce common subexpressions. */ - - if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) - && ! TREE_CONSTANT (intop) - && TREE_CONSTANT (TREE_OPERAND (intop, 1)) - && TREE_CONSTANT (size_exp) - /* If the constant comes from pointer subtraction, - skip this optimization--it would cause an error. */ - && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE) - { - enum tree_code subcode = resultcode; - tree int_type = TREE_TYPE (intop); - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - /* Convert both subexpression types to the type of intop, - because weird cases involving pointer arithmetic - can result in a sum or difference with different type args. */ - ptrop = build_binary_op (subcode, ptrop, - convert (int_type, TREE_OPERAND (intop, 1)), 1); - intop = convert (int_type, TREE_OPERAND (intop, 0)); - } - - /* Convert the integer argument to a type the same size as a pointer - so the multiply won't overflow spuriously. */ - - if (TYPE_PRECISION (TREE_TYPE (intop)) != POINTER_SIZE) - intop = convert (type_for_size (POINTER_SIZE, 0), intop); - - /* Replace the integer argument - with a suitable product by the object size. */ - - intop = build_binary_op (MULT_EXPR, intop, size_exp, 1); - - /* Create the sum or difference. */ - - result = build (resultcode, result_type, ptrop, intop); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop); - return folded; -} - -/* Return a tree for the difference of pointers OP0 and OP1. - The resulting tree has type int. */ - -static tree -pointer_diff (op0, op1) - register tree op0, op1; -{ - register tree result, folded; - tree restype = ptrdiff_type_node; - - tree target_type = TREE_TYPE (TREE_TYPE (op0)); - - if (pedantic || warn_pointer_arith) - { - if (TREE_CODE (target_type) == VOID_TYPE) - pedwarn ("pointer of type `void *' used in subtraction"); - if (TREE_CODE (target_type) == FUNCTION_TYPE) - pedwarn ("pointer to a function used in subtraction"); - } - - /* First do the subtraction as integers; - then drop through to build the divide operator. */ - - op0 = build_binary_op (MINUS_EXPR, convert (restype, op0), - convert (restype, op1), 1); - /* This generates an error if op1 is pointer to incomplete type. */ - if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) - error ("arithmetic on pointer to an incomplete type"); - /* This generates an error if op0 is pointer to incomplete type. */ - op1 = c_size_in_bytes (target_type); - - /* Divide by the size, in easiest possible way. */ - - result = build (EXACT_DIV_EXPR, restype, op0, op1); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - return folded; -} - -/* Construct and perhaps optimize a tree representation - for a unary operation. CODE, a tree_code, specifies the operation - and XARG is the operand. NOCONVERT nonzero suppresses - the default promotions (such as from short to int). */ - -tree -build_unary_op (code, xarg, noconvert) - enum tree_code code; - tree xarg; - int noconvert; -{ - /* No default_conversion here. It causes trouble for ADDR_EXPR. */ - register tree arg = xarg; - register tree argtype = 0; - register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg)); - char *errstring = NULL; - tree val; - - if (typecode == ERROR_MARK) - return error_mark_node; - if (typecode == ENUMERAL_TYPE) - typecode = INTEGER_TYPE; - - switch (code) - { - case CONVERT_EXPR: - /* This is used for unary plus, because a CONVERT_EXPR - is enough to prevent anybody from looking inside for - associativity, but won't generate any code. */ - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary plus"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case NEGATE_EXPR: - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary minus"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case BIT_NOT_EXPR: - if (typecode != INTEGER_TYPE) - errstring = "wrong type argument to bit-complement"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case ABS_EXPR: - if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to abs"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case TRUTH_NOT_EXPR: - if (typecode != INTEGER_TYPE - && typecode != REAL_TYPE && typecode != POINTER_TYPE - && typecode != COMPLEX_TYPE - /* These will convert to a pointer. */ - && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) - { - errstring = "wrong type argument to unary exclamation mark"; - break; - } - arg = truthvalue_conversion (arg); - return invert_truthvalue (arg); - - case NOP_EXPR: - break; - - case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return arg; - - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return convert (TREE_TYPE (arg), integer_zero_node); - - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - - /* Increment or decrement the real part of the value, - and don't change the imaginary part. */ - if (typecode == COMPLEX_TYPE) - { - tree real, imag; - - arg = stabilize_reference (arg); - real = build_unary_op (REALPART_EXPR, arg, 1); - imag = build_unary_op (IMAGPART_EXPR, arg, 1); - return build (COMPLEX_EXPR, TREE_TYPE (arg), - build_unary_op (code, real, 1), imag); - } - - /* Report invalid types. */ - - if (typecode != POINTER_TYPE - && typecode != INTEGER_TYPE && typecode != REAL_TYPE) - { - if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - errstring ="wrong type argument to increment"; - else - errstring ="wrong type argument to decrement"; - break; - } - - { - register tree inc; - tree result_type = TREE_TYPE (arg); - - arg = get_unwidened (arg, 0); - argtype = TREE_TYPE (arg); - - /* Compute the increment. */ - - if (typecode == POINTER_TYPE) - { - /* If pointer target is an undefined struct, - we just cannot know how to do the arithmetic. */ - if (TYPE_SIZE (TREE_TYPE (result_type)) == 0) - error ("%s of pointer to unknown structure", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - else if ((pedantic || warn_pointer_arith) - && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) - pedwarn ("wrong type argument to %s", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - inc = c_sizeof_nowarn (TREE_TYPE (result_type)); - } - else - inc = integer_one_node; - - inc = convert (argtype, inc); - - /* Handle incrementing a cast-expression. */ - - while (1) - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - pedantic_lvalue_warning (CONVERT_EXPR); - /* If the real type has the same machine representation - as the type it is cast to, we can make better output - by adding directly to the inside of the cast. */ - if ((TREE_CODE (TREE_TYPE (arg)) - == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))) - && (TYPE_MODE (TREE_TYPE (arg)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0))))) - arg = TREE_OPERAND (arg, 0); - else - { - tree incremented, modify, value; - arg = stabilize_reference (arg); - if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) - value = arg; - else - value = save_expr (arg); - incremented = build (((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? PLUS_EXPR : MINUS_EXPR), - argtype, value, inc); - TREE_SIDE_EFFECTS (incremented) = 1; - modify = build_modify_expr (arg, NOP_EXPR, incremented); - value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); - TREE_USED (value) = 1; - return value; - } - break; - - default: - goto give_up; - } - give_up: - - /* Complain about anything else that is not a true lvalue. */ - if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"))) - return error_mark_node; - - /* Report a read-only lvalue. */ - if (TREE_READONLY (arg)) - readonly_warning (arg, - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); - - val = build (code, TREE_TYPE (arg), arg, inc); - TREE_SIDE_EFFECTS (val) = 1; - val = convert (result_type, val); - if (TREE_CODE (val) != code) - TREE_NO_UNUSED_WARNING (val) = 1; - return val; - } - - case ADDR_EXPR: - /* Note that this operation never does default_conversion - regardless of NOCONVERT. */ - - /* Let &* cancel out to simplify resulting code. */ - if (TREE_CODE (arg) == INDIRECT_REF) - { - /* Don't let this be an lvalue. */ - if (lvalue_p (TREE_OPERAND (arg, 0))) - return non_lvalue (TREE_OPERAND (arg, 0)); - return TREE_OPERAND (arg, 0); - } - - /* For &x[y], return x+y */ - if (TREE_CODE (arg) == ARRAY_REF) - { - if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) - return error_mark_node; - return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), - TREE_OPERAND (arg, 1), 1); - } - - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - -#if 0 /* Turned off because inconsistent; - float f; *&(int)f = 3.4 stores in int format - whereas (int)f = 3.4 stores in float format. */ - /* Address of a cast is just a cast of the address - of the operand of the cast. */ - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (pedantic) - pedwarn ("ANSI C forbids the address of a cast expression"); - return convert (build_pointer_type (TREE_TYPE (arg)), - build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), - 0)); - } -#endif - - /* Allow the address of a constructor if all the elements - are constant. */ - if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)) - ; - /* Anything not already handled and not a true memory reference - is an error. */ - else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'")) - return error_mark_node; - - /* Ordinary case; arg is a COMPONENT_REF or a decl. */ - argtype = TREE_TYPE (arg); - /* If the lvalue is const or volatile, - merge that into the type that the address will point to. */ - if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd' - || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') - { - if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) - argtype = c_build_type_variant (argtype, - TREE_READONLY (arg), - TREE_THIS_VOLATILE (arg)); - } - - argtype = build_pointer_type (argtype); - - if (mark_addressable (arg) == 0) - return error_mark_node; - - { - tree addr; - - if (TREE_CODE (arg) == COMPONENT_REF) - { - tree field = TREE_OPERAND (arg, 1); - - addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); - - if (DECL_BIT_FIELD (field)) - { - error ("attempt to take address of bit-field structure member `%s'", - IDENTIFIER_POINTER (DECL_NAME (field))); - return error_mark_node; - } - - addr = convert (argtype, addr); - - if (! integer_zerop (DECL_FIELD_BITPOS (field))) - { - tree offset - = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); - int flag = TREE_CONSTANT (addr); - addr = fold (build (PLUS_EXPR, argtype, - addr, convert (argtype, offset))); - TREE_CONSTANT (addr) = flag; - } - } - else - addr = build1 (code, argtype, arg); - - /* Address of a static or external variable or - file-scope function counts as a constant. */ - if (staticp (arg) - && ! (TREE_CODE (arg) == FUNCTION_DECL - && DECL_CONTEXT (arg) != 0)) - TREE_CONSTANT (addr) = 1; - return addr; - } - } - - if (!errstring) - { - if (argtype == 0) - argtype = TREE_TYPE (arg); - return fold (build1 (code, argtype, arg)); - } - - error (errstring); - return error_mark_node; -} - -#if 0 -/* If CONVERSIONS is a conversion expression or a nested sequence of such, - convert ARG with the same conversions in the same order - and return the result. */ - -static tree -convert_sequence (conversions, arg) - tree conversions; - tree arg; -{ - switch (TREE_CODE (conversions)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - return convert (TREE_TYPE (conversions), - convert_sequence (TREE_OPERAND (conversions, 0), - arg)); - - default: - return arg; - } -} -#endif /* 0 */ - -/* Return nonzero if REF is an lvalue valid for this language. - Lvalues can be assigned, unless their type has TYPE_READONLY. - Lvalues can have their address taken, unless they have DECL_REGISTER. */ - -int -lvalue_p (ref) - tree ref; -{ - register enum tree_code code = TREE_CODE (ref); - - switch (code) - { - case REALPART_EXPR: - case IMAGPART_EXPR: - case COMPONENT_REF: - return lvalue_p (TREE_OPERAND (ref, 0)); - - case STRING_CST: - return 1; - - case INDIRECT_REF: - case ARRAY_REF: - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - case ERROR_MARK: - if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) - return 1; - break; - } - return 0; -} - -/* Return nonzero if REF is an lvalue valid for this language; - otherwise, print an error message and return zero. */ - -int -lvalue_or_else (ref, string) - tree ref; - char *string; -{ - int win = lvalue_p (ref); - if (! win) - error ("invalid lvalue in %s", string); - return win; -} - -/* Apply unary lvalue-demanding operator CODE to the expression ARG - for certain kinds of expressions which are not really lvalues - but which we can accept as lvalues. - - If ARG is not a kind of expression we can handle, return zero. */ - -static tree -unary_complex_lvalue (code, arg) - enum tree_code code; - tree arg; -{ - /* Handle (a, b) used as an "lvalue". */ - if (TREE_CODE (arg) == COMPOUND_EXPR) - { - tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); - pedantic_lvalue_warning (COMPOUND_EXPR); - return build (COMPOUND_EXPR, TREE_TYPE (real_result), - TREE_OPERAND (arg, 0), real_result); - } - - /* Handle (a ? b : c) used as an "lvalue". */ - if (TREE_CODE (arg) == COND_EXPR) - { - pedantic_lvalue_warning (COND_EXPR); - return (build_conditional_expr - (TREE_OPERAND (arg, 0), - build_unary_op (code, TREE_OPERAND (arg, 1), 0), - build_unary_op (code, TREE_OPERAND (arg, 2), 0))); - } - - return 0; -} - -/* If pedantic, warn about improper lvalue. CODE is either COND_EXPR - COMPOUND_EXPR, or CONVERT_EXPR (for casts). */ - -static void -pedantic_lvalue_warning (code) - enum tree_code code; -{ - if (pedantic) - pedwarn ("ANSI C forbids use of %s expressions as lvalues", - code == COND_EXPR ? "conditional" - : code == COMPOUND_EXPR ? "compound" : "cast"); -} - -/* Warn about storing in something that is `const'. */ - -void -readonly_warning (arg, string) - tree arg; - char *string; -{ - char buf[80]; - strcpy (buf, string); - - /* Forbid assignments to iterators. */ - if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg)) - { - strcat (buf, " of iterator `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } - - if (TREE_CODE (arg) == COMPONENT_REF) - { - if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) - readonly_warning (TREE_OPERAND (arg, 0), string); - else - { - strcat (buf, " of read-only member `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); - } - } - else if (TREE_CODE (arg) == VAR_DECL) - { - strcat (buf, " of read-only variable `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } - else - { - pedwarn ("%s of read-only location", buf); - } -} - -/* Mark EXP saying that we need to be able to take the - address of it; it should not be allocated in a register. - Value is 1 if successful. */ - -int -mark_addressable (exp) - tree exp; -{ - register tree x = exp; - while (1) - switch (TREE_CODE (x)) - { - case ADDR_EXPR: - case COMPONENT_REF: - case ARRAY_REF: - x = TREE_OPERAND (x, 0); - break; - - case CONSTRUCTOR: - TREE_ADDRESSABLE (x) = 1; - return 1; - - case VAR_DECL: - case CONST_DECL: - case PARM_DECL: - case RESULT_DECL: - if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) - && DECL_NONLOCAL (x)) - { - if (TREE_PUBLIC (x)) - { - error ("global register variable `%s' used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; - } - pedwarn ("register variable `%s' used in nested function", - IDENTIFIER_POINTER (DECL_NAME (x))); - } - else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) - { - if (TREE_PUBLIC (x)) - { - error ("address of global register variable `%s' requested", - IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; - } - pedwarn ("address of register variable `%s' requested", - IDENTIFIER_POINTER (DECL_NAME (x))); - } - put_var_into_stack (x); - - /* drops in */ - case FUNCTION_DECL: - TREE_ADDRESSABLE (x) = 1; -#if 0 /* poplevel deals with this now. */ - if (DECL_CONTEXT (x) == 0) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; -#endif - - default: - return 1; - } -} - -/* Build and return a conditional expression IFEXP ? OP1 : OP2. */ - -tree -build_conditional_expr (ifexp, op1, op2) - tree ifexp, op1, op2; -{ - register tree type1; - register tree type2; - register enum tree_code code1; - register enum tree_code code2; - register tree result_type = NULL; - - /* If second operand is omitted, it is the same as the first one; - make sure it is calculated only once. */ - if (op1 == 0) - { - if (pedantic) - pedwarn ("ANSI C forbids omitting the middle term of a ?: expression"); - ifexp = op1 = save_expr (ifexp); - } - - ifexp = truthvalue_conversion (default_conversion (ifexp)); - -#if 0 /* Produces wrong result if within sizeof. */ - /* Don't promote the operands separately if they promote - the same way. Return the unpromoted type and let the combined - value get promoted if necessary. */ - - if (TREE_TYPE (op1) == TREE_TYPE (op2) - && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE - && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE) - { - if (TREE_CODE (ifexp) == INTEGER_CST) - return (integer_zerop (ifexp) ? op2 : op1); - - return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); - } -#endif - - /* Promote both alternatives. */ - - if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE) - op1 = default_conversion (op1); - if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE) - op2 = default_conversion (op2); - - if (TREE_CODE (ifexp) == ERROR_MARK - || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK - || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK) - return error_mark_node; - - type1 = TREE_TYPE (op1); - code1 = TREE_CODE (type1); - type2 = TREE_TYPE (op2); - code2 = TREE_CODE (type2); - - /* Quickly detect the usual case where op1 and op2 have the same type - after promotion. */ - if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) - { - if (type1 == type2) - result_type = type1; - else - result_type = TYPE_MAIN_VARIANT (type1); - } - else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE) - && (code2 == INTEGER_TYPE || code2 == REAL_TYPE)) - { - result_type = common_type (type1, type2); - } - else if (code1 == VOID_TYPE || code2 == VOID_TYPE) - { - if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) - pedwarn ("ANSI C forbids conditional expr with only one void side"); - result_type = void_type_node; - } - else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) - { - if (comp_target_types (type1, type2)) - result_type = common_type (type1, type2); - else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node) - result_type = qualify_type (type2, type1); - else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node) - result_type = qualify_type (type1, type2); - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) - { - if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type1, type2); - } - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node) - { - if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type2, type1); - } - else - { - pedwarn ("pointer type mismatch in conditional expression"); - result_type = build_pointer_type (void_type_node); - } - } - else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) - { - if (! integer_zerop (op2)) - pedwarn ("pointer/integer type mismatch in conditional expression"); - else - { - op2 = null_pointer_node; -#if 0 /* The spec seems to say this is permitted. */ - if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); -#endif - } - result_type = type1; - } - else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - if (!integer_zerop (op1)) - pedwarn ("pointer/integer type mismatch in conditional expression"); - else - { - op1 = null_pointer_node; -#if 0 /* The spec seems to say this is permitted. */ - if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE) - pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); -#endif - } - result_type = type2; - } - - if (!result_type) - { - if (flag_cond_mismatch) - result_type = void_type_node; - else - { - error ("type mismatch in conditional expression"); - return error_mark_node; - } - } - - /* Merge const and volatile flags of the incoming types. */ - result_type - = build_type_variant (result_type, - TREE_READONLY (op1) || TREE_READONLY (op2), - TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); - - if (result_type != TREE_TYPE (op1)) - op1 = convert_and_check (result_type, op1); - if (result_type != TREE_TYPE (op2)) - op2 = convert_and_check (result_type, op2); - -#if 0 - if (code1 == RECORD_TYPE || code1 == UNION_TYPE) - { - result_type = TREE_TYPE (op1); - if (TREE_CONSTANT (ifexp)) - return (integer_zerop (ifexp) ? op2 : op1); - - if (TYPE_MODE (result_type) == BLKmode) - { - register tree tempvar - = build_decl (VAR_DECL, NULL_TREE, result_type); - register tree xop1 = build_modify_expr (tempvar, op1); - register tree xop2 = build_modify_expr (tempvar, op2); - register tree result = fold (build (COND_EXPR, result_type, - ifexp, xop1, xop2)); - - layout_decl (tempvar, TYPE_ALIGN (result_type)); - /* No way to handle variable-sized objects here. - I fear that the entire handling of BLKmode conditional exprs - needs to be redone. */ - if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST) - abort (); - DECL_RTL (tempvar) - = assign_stack_local (DECL_MODE (tempvar), - (TREE_INT_CST_LOW (DECL_SIZE (tempvar)) - + BITS_PER_UNIT - 1) - / BITS_PER_UNIT, - 0); - - TREE_SIDE_EFFECTS (result) - = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1) - | TREE_SIDE_EFFECTS (op2); - return build (COMPOUND_EXPR, result_type, result, tempvar); - } - } -#endif /* 0 */ - - if (TREE_CODE (ifexp) == INTEGER_CST) - return integer_zerop (ifexp) ? op2 : op1; - - return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); -} - -/* Given a list of expressions, return a compound expression - that performs them all and returns the value of the last of them. */ - -tree -build_compound_expr (list) - tree list; -{ - return internal_build_compound_expr (list, TRUE); -} - -static tree -internal_build_compound_expr (list, first_p) - tree list; - int first_p; -{ - register tree rest; - - if (TREE_CHAIN (list) == 0) - { -#if 0 /* If something inside inhibited lvalueness, we should not override. */ - /* Consider (x, y+0), which is not an lvalue since y+0 is not. */ - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (list) == NON_LVALUE_EXPR) - list = TREE_OPERAND (list, 0); -#endif - - /* Don't let (0, 0) be null pointer constant. */ - if (!first_p && integer_zerop (TREE_VALUE (list))) - return non_lvalue (TREE_VALUE (list)); - return TREE_VALUE (list); - } - - if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0) - { - /* Convert arrays to pointers when there really is a comma operator. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE) - TREE_VALUE (TREE_CHAIN (list)) - = default_conversion (TREE_VALUE (TREE_CHAIN (list))); - } - - rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE); - - /* When pedantic, a compound expression can be neither an lvalue - nor an integer constant expression. */ - if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic) - return rest; - - return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest); -} - -/* Build an expression representing a cast to type TYPE of expression EXPR. */ - -tree -build_c_cast (type, expr) - register tree type; - tree expr; -{ - register tree value = expr; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - type = TYPE_MAIN_VARIANT (type); - -#if 0 - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (value) == NON_LVALUE_EXPR) - value = TREE_OPERAND (value, 0); -#endif - - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("cast specifies array type"); - return error_mark_node; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("cast specifies function type"); - return error_mark_node; - } - - if (type == TREE_TYPE (value)) - { - if (pedantic) - { - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - pedwarn ("ANSI C forbids casting nonscalar to the same type"); - } - } - else if (TREE_CODE (type) == UNION_TYPE) - { - tree field; - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), - TYPE_MAIN_VARIANT (TREE_TYPE (value)))) - break; - - if (field) - { - char *name; - tree nvalue; - - if (pedantic) - pedwarn ("ANSI C forbids casts to union type"); - if (TYPE_NAME (type) != 0) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - else - name = ""; - return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, - build_tree_list (field, value)), - NULL_PTR, 0, 0, name); - } - error ("cast to union type from type not present in union"); - return error_mark_node; - } - else - { - tree otype; - - /* If casting to void, avoid the error that would come - from default_conversion in the case of a non-lvalue array. */ - if (type == void_type_node) - return build1 (CONVERT_EXPR, type, value); - - /* Convert functions and arrays to pointers, - but don't convert any other types. */ - if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE) - value = default_conversion (value); - otype = TREE_TYPE (value); - - /* Optionally warn about potentially worrisome casts. */ - - if (warn_cast_qual - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE) - { - if (TYPE_VOLATILE (TREE_TYPE (otype)) - && ! TYPE_VOLATILE (TREE_TYPE (type))) - pedwarn ("cast discards `volatile' from pointer target type"); - if (TYPE_READONLY (TREE_TYPE (otype)) - && ! TYPE_READONLY (TREE_TYPE (type))) - pedwarn ("cast discards `const' from pointer target type"); - } - - /* Warn about possible alignment problems. */ - if (STRICT_ALIGNMENT && warn_cast_align - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE - && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) - warning ("cast increases required alignment of target type"); - - if (TREE_CODE (type) == INTEGER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) - && !TREE_CONSTANT (value)) - warning ("cast from pointer to integer of different size"); - - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == INTEGER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) -#if 0 - /* Don't warn about converting 0 to pointer, - provided the 0 was explicit--not cast or made by folding. */ - && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)) -#endif - /* Don't warn about converting any constant. */ - && !TREE_CONSTANT (value)) - warning ("cast to pointer from integer of different size"); - - value = convert (type, value); - - /* Ignore any integer overflow caused by the cast. */ - if (TREE_CODE (value) == INTEGER_CST) - TREE_CONSTANT_OVERFLOW (value) = 0; - } - - if (value == expr && pedantic) - { - /* If pedantic, don't let a cast be an lvalue. */ - return non_lvalue (value); - } - return value; -} - -/* Build an assignment expression of lvalue LHS from value RHS. - MODIFYCODE is the code for a binary operator that we use - to combine the old value of LHS with RHS to get the new value. - Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */ - -tree -build_modify_expr (lhs, modifycode, rhs) - tree lhs, rhs; - enum tree_code modifycode; -{ - register tree result; - tree newrhs; - tree lhstype = TREE_TYPE (lhs); - tree olhstype = lhstype; - - /* Types that aren't fully specified cannot be used in assignments. */ - lhs = require_complete_type (lhs); - - /* Avoid duplicate error messages from operands that had errors. */ - if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) - return error_mark_node; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (rhs) == NON_LVALUE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - newrhs = rhs; - - /* Handle control structure constructs used as "lvalues". */ - - switch (TREE_CODE (lhs)) - { - /* Handle (a, b) used as an "lvalue". */ - case COMPOUND_EXPR: - pedantic_lvalue_warning (COMPOUND_EXPR); - return build (COMPOUND_EXPR, lhstype, - TREE_OPERAND (lhs, 0), - build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs)); - - /* Handle (a ? b : c) used as an "lvalue". */ - case COND_EXPR: - pedantic_lvalue_warning (COND_EXPR); - rhs = save_expr (rhs); - { - /* Produce (a ? (b = rhs) : (c = rhs)) - except that the RHS goes through a save-expr - so the code to compute it is only emitted once. */ - tree cond - = build_conditional_expr (TREE_OPERAND (lhs, 0), - build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs), - build_modify_expr (TREE_OPERAND (lhs, 2), - modifycode, rhs)); - /* Make sure the code to compute the rhs comes out - before the split. */ - return build (COMPOUND_EXPR, TREE_TYPE (lhs), - /* But cast it to void to avoid an "unused" error. */ - convert (void_type_node, rhs), cond); - } - } - - /* If a binary op has been requested, combine the old LHS value with the RHS - producing the value we should actually store into the LHS. */ - - if (modifycode != NOP_EXPR) - { - lhs = stabilize_reference (lhs); - newrhs = build_binary_op (modifycode, lhs, rhs, 1); - } - - /* Handle a cast used as an "lvalue". - We have already performed any binary operator using the value as cast. - Now convert the result to the cast type of the lhs, - and then true type of the lhs and store it there; - then convert result back to the cast type to be the value - of the assignment. */ - - switch (TREE_CODE (lhs)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE) - newrhs = default_conversion (newrhs); - { - tree inner_lhs = TREE_OPERAND (lhs, 0); - tree result; - result = build_modify_expr (inner_lhs, NOP_EXPR, - convert (TREE_TYPE (inner_lhs), - convert (lhstype, newrhs))); - pedantic_lvalue_warning (CONVERT_EXPR); - return convert (TREE_TYPE (lhs), result); - } - } - - /* Now we have handled acceptable kinds of LHS that are not truly lvalues. - Reject anything strange now. */ - - if (!lvalue_or_else (lhs, "assignment")) - return error_mark_node; - - /* Warn about storing in something that is `const'. */ - - if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype) - || ((TREE_CODE (lhstype) == RECORD_TYPE - || TREE_CODE (lhstype) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (lhstype))) - readonly_warning (lhs, "assignment"); - - /* If storing into a structure or union member, - it has probably been given type `int'. - Compute the type that would go with - the actual amount of storage the member occupies. */ - - if (TREE_CODE (lhs) == COMPONENT_REF - && (TREE_CODE (lhstype) == INTEGER_TYPE - || TREE_CODE (lhstype) == REAL_TYPE - || TREE_CODE (lhstype) == ENUMERAL_TYPE)) - lhstype = TREE_TYPE (get_unwidened (lhs, 0)); - - /* If storing in a field that is in actuality a short or narrower than one, - we must store in the field in its actual type. */ - - if (lhstype != TREE_TYPE (lhs)) - { - lhs = copy_node (lhs); - TREE_TYPE (lhs) = lhstype; - } - - /* Convert new value to destination type. */ - - newrhs = convert_for_assignment (lhstype, newrhs, "assignment", - NULL_TREE, NULL_TREE, 0); - if (TREE_CODE (newrhs) == ERROR_MARK) - return error_mark_node; - - result = build (MODIFY_EXPR, lhstype, lhs, newrhs); - TREE_SIDE_EFFECTS (result) = 1; - - /* If we got the LHS in a different type for storing in, - convert the result back to the nominal type of LHS - so that the value we return always has the same type - as the LHS argument. */ - - if (olhstype == TREE_TYPE (result)) - return result; - return convert_for_assignment (olhstype, result, "assignment", - NULL_TREE, NULL_TREE, 0); -} - -/* Convert value RHS to type TYPE as preparation for an assignment - to an lvalue of type TYPE. - The real work of conversion is done by `convert'. - The purpose of this function is to generate error messages - for assignments that are not allowed in C. - ERRTYPE is a string to use in error messages: - "assignment", "return", etc. If it is null, this is parameter passing - for a function call (and different error messages are output). Otherwise, - it may be a name stored in the spelling stack and interpreted by - get_spelling. - - FUNNAME is the name of the function being called, - as an IDENTIFIER_NODE, or null. - PARMNUM is the number of the argument, for printing in error messages. */ - -static tree -convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) - tree type, rhs; - char *errtype; - tree fundecl, funname; - int parmnum; -{ - register enum tree_code codel = TREE_CODE (type); - register tree rhstype; - register enum tree_code coder; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (rhs) == NON_LVALUE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) - rhs = default_conversion (rhs); - - rhstype = TREE_TYPE (rhs); - coder = TREE_CODE (rhstype); - - if (coder == ERROR_MARK) - return error_mark_node; - - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) - { - overflow_warning (rhs); - /* Check for Objective-C protocols. This will issue a warning if - there are protocol violations. No need to use the return value. */ - maybe_objc_comptypes (type, rhstype, 0); - return rhs; - } - - if (coder == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - /* Arithmetic types all interconvert, and enum is treated like int. */ - if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE - || codel == COMPLEX_TYPE) - && - (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE - || codel == COMPLEX_TYPE)) - /* Don't use convert_and_check here. If the input has type int - and did not overflow, and we are converting it here to a short, - we don't want an error. A warning would be okay, but it's too risky now - to add an option to convert_and_check to get just warnings. */ - return convert (type, rhs); - /* Conversion to a union from its member types. */ - else if (codel == UNION_TYPE) - { - tree memb_types; - for (memb_types = TYPE_FIELDS (type); memb_types; - memb_types = TREE_CHAIN (memb_types)) - { - if (comptypes (TREE_TYPE (memb_types), TREE_TYPE (rhs))) - { - if (pedantic - && !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl))) - pedwarn ("ANSI C prohibits argument conversion to union type"); - return build1 (NOP_EXPR, type, rhs); - } - else if (coder == POINTER_TYPE - && TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE) - { - tree memb_type = TREE_TYPE (memb_types); - register tree ttl = TREE_TYPE (memb_type); - register tree ttr = TREE_TYPE (rhstype); - - /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of the rhs. */ - if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || comp_target_types (memb_type, rhstype)) - { - /* Const and volatile mean something different for function types, - so the usual warnings are not appropriate. */ - if (TREE_CODE (ttr) != FUNCTION_TYPE - || TREE_CODE (ttl) != FUNCTION_TYPE) - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, parmnum); - if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, parmnum); - } - else - { - /* Because const and volatile on functions are restrictions - that say the function will not do certain things, - it is okay to use a const or volatile function - where an ordinary one is wanted, but not vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, parmnum); - } - if (pedantic - && !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl))) - pedwarn ("ANSI C prohibits argument conversion to union type"); - return build1 (NOP_EXPR, type, rhs); - } - } - } - } - /* Conversions among pointers */ - else if (codel == POINTER_TYPE && coder == POINTER_TYPE) - { - register tree ttl = TREE_TYPE (type); - register tree ttr = TREE_TYPE (rhstype); - - /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of the rhs. */ - if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || comp_target_types (type, rhstype)) - { - if (pedantic - && ((TYPE_MAIN_VARIANT (ttl) == void_type_node - && TREE_CODE (ttr) == FUNCTION_TYPE) - || - (TYPE_MAIN_VARIANT (ttr) == void_type_node - && !integer_zerop (rhs) - && TREE_CODE (ttl) == FUNCTION_TYPE))) - warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", - get_spelling (errtype), funname, parmnum); - /* Const and volatile mean something different for function types, - so the usual warnings are not appropriate. */ - else if (TREE_CODE (ttr) != FUNCTION_TYPE - || TREE_CODE (ttl) != FUNCTION_TYPE) - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, parmnum); - if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, parmnum); - } - else - { - /* Because const and volatile on functions are restrictions - that say the function will not do certain things, - it is okay to use a const or volatile function - where an ordinary one is wanted, but not vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, parmnum); - } - } - else if (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr))) - { - if (pedantic) - warn_for_assignment ("pointer targets in %s differ in signedness", - get_spelling (errtype), funname, parmnum); - } - else - warn_for_assignment ("%s from incompatible pointer type", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) - { - /* An explicit constant 0 can convert to a pointer, - but not a 0 that results from casting or folding. */ - if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))) - { - warn_for_assignment ("%s makes pointer from integer without a cast", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - return null_pointer_node; - } - else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) - { - warn_for_assignment ("%s makes integer from pointer without a cast", - get_spelling (errtype), funname, parmnum); - return convert (type, rhs); - } - - if (!errtype) - { - if (funname) - { - tree selector = maybe_building_objc_message_expr (); - - if (selector && parmnum > 2) - error ("incompatible type for argument %d of `%s'", - parmnum - 2, IDENTIFIER_POINTER (selector)); - else - error ("incompatible type for argument %d of `%s'", - parmnum, IDENTIFIER_POINTER (funname)); - } - else - error ("incompatible type for argument %d of indirect function call", - parmnum); - } - else - error ("incompatible types in %s", get_spelling (errtype)); - - return error_mark_node; -} - -/* Print a warning using MSG. - It gets OPNAME as its one parameter. - If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". - FUNCTION and ARGNUM are handled specially if we are building an - Objective-C selector. */ - -static void -warn_for_assignment (msg, opname, function, argnum) - char *msg; - char *opname; - tree function; - int argnum; -{ - static char argstring[] = "passing arg %d of `%s'"; - static char argnofun[] = "passing arg %d"; - - if (opname == 0) - { - tree selector = maybe_building_objc_message_expr (); - - if (selector && argnum > 2) - { - function = selector; - argnum -= 2; - } - if (function) - { - /* Function name is known; supply it. */ - opname = (char *) alloca (IDENTIFIER_LENGTH (function) - + sizeof (argstring) + 25 /*%d*/ + 1); - sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function)); - } - else - { - /* Function name unknown (call through ptr); just give arg number. */ - opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1); - sprintf (opname, argnofun, argnum); - } - } - pedwarn (msg, opname); -} - -/* Return nonzero if VALUE is a valid constant-valued expression - for use in initializing a static variable; one that can be an - element of a "constant" initializer. - - Return null_pointer_node if the value is absolute; - if it is relocatable, return the variable that determines the relocation. - We assume that VALUE has been folded as much as possible; - therefore, we do not need to check for such things as - arithmetic-combinations of integers. */ - -static tree -initializer_constant_valid_p (value, endtype) - tree value; - tree endtype; -{ - switch (TREE_CODE (value)) - { - case CONSTRUCTOR: - return TREE_STATIC (value) ? null_pointer_node : 0; - - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - case COMPLEX_CST: - return null_pointer_node; - - case ADDR_EXPR: - return TREE_OPERAND (value, 0); - - case NON_LVALUE_EXPR: - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - case CONVERT_EXPR: - case NOP_EXPR: - /* Allow conversions between pointer types. */ - if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - /* Allow conversions between real types. */ - if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - /* Allow length-preserving conversions between integer types. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE - && tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - /* Allow conversions between integer types only if explicit value. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) - { - tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - if (inner == null_pointer_node) - return null_pointer_node; - return 0; - } - /* Allow (int) &foo provided int is as wide as a pointer. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE - && ! tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - /* Allow conversions to union types if the value inside is okay. */ - if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - return 0; - - case PLUS_EXPR: - if (TREE_CODE (endtype) == INTEGER_TYPE - && TYPE_PRECISION (endtype) < POINTER_SIZE) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* If either term is absolute, use the other terms relocation. */ - if (valid0 == null_pointer_node) - return valid1; - if (valid1 == null_pointer_node) - return valid0; - return 0; - } - - case MINUS_EXPR: - if (TREE_CODE (endtype) == INTEGER_TYPE - && TYPE_PRECISION (endtype) < POINTER_SIZE) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* Win if second argument is absolute. */ - if (valid1 == null_pointer_node) - return valid0; - /* Win if both arguments have the same relocation. - Then the value is absolute. */ - if (valid0 == valid1) - return null_pointer_node; - return 0; - } - } - - return 0; -} - -/* Perform appropriate conversions on the initial value of a variable, - store it in the declaration DECL, - and print any error messages that are appropriate. - If the init is invalid, store an ERROR_MARK. */ - -void -store_init_value (decl, init) - tree decl, init; -{ - register tree value, type; - - /* If variable's type was invalidly declared, just ignore it. */ - - type = TREE_TYPE (decl); - if (TREE_CODE (type) == ERROR_MARK) - return; - - /* Digest the specified initializer into an expression. */ - - value = digest_init (type, init, NULL_PTR, TREE_STATIC (decl), - TREE_STATIC (decl) || pedantic, - IDENTIFIER_POINTER (DECL_NAME (decl))); - - /* Store the expression if valid; else report error. */ - -#if 0 - /* Note that this is the only place we can detect the error - in a case such as struct foo bar = (struct foo) { x, y }; - where there is one initial value which is a constructor expression. */ - if (value == error_mark_node) - ; - else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value)) - { - error ("initializer for static variable is not constant"); - value = error_mark_node; - } - else if (TREE_STATIC (decl) - && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) - { - error ("initializer for static variable uses complicated arithmetic"); - value = error_mark_node; - } - else - { - if (pedantic && TREE_CODE (value) == CONSTRUCTOR) - { - if (! TREE_CONSTANT (value)) - pedwarn ("aggregate initializer is not constant"); - else if (! TREE_STATIC (value)) - pedwarn ("aggregate initializer uses complicated arithmetic"); - } - } -#endif - - /* ANSI wants warnings about out-of-range constant initializers. */ - constant_expression_warning (value); - - DECL_INITIAL (decl) = value; -} - -/* Methods for storing and printing names for error messages. */ - -/* Implement a spelling stack that allows components of a name to be pushed - and popped. Each element on the stack is this structure. */ - -struct spelling -{ - int kind; - union - { - int i; - char *s; - } u; -}; - -#define SPELLING_STRING 1 -#define SPELLING_MEMBER 2 -#define SPELLING_BOUNDS 3 - -static struct spelling *spelling; /* Next stack element (unused). */ -static struct spelling *spelling_base; /* Spelling stack base. */ -static int spelling_size; /* Size of the spelling stack. */ - -/* Macros to save and restore the spelling stack around push_... functions. - Alternative to SAVE_SPELLING_STACK. */ - -#define SPELLING_DEPTH() (spelling - spelling_base) -#define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth) - -/* Save and restore the spelling stack around arbitrary C code. */ - -#define SAVE_SPELLING_DEPTH(code) \ -{ \ - int __depth = SPELLING_DEPTH (); \ - code; \ - RESTORE_SPELLING_DEPTH (__depth); \ -} - -/* Push an element on the spelling stack with type KIND and assign VALUE - to MEMBER. */ - -#define PUSH_SPELLING(KIND, VALUE, MEMBER) \ -{ \ - int depth = SPELLING_DEPTH (); \ - \ - if (depth >= spelling_size) \ - { \ - spelling_size += 10; \ - if (spelling_base == 0) \ - spelling_base \ - = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling)); \ - else \ - spelling_base \ - = (struct spelling *) xrealloc (spelling_base, \ - spelling_size * sizeof (struct spelling)); \ - RESTORE_SPELLING_DEPTH (depth); \ - } \ - \ - spelling->kind = (KIND); \ - spelling->MEMBER = (VALUE); \ - spelling++; \ -} - -/* Push STRING on the stack. Printed literally. */ - -static void -push_string (string) - char *string; -{ - PUSH_SPELLING (SPELLING_STRING, string, u.s); -} - -/* Push a member name on the stack. Printed as '.' STRING. */ - -static void -push_member_name (string) - char *string; -{ - PUSH_SPELLING (SPELLING_MEMBER, string, u.s); -} - -/* Push an array bounds on the stack. Printed as [BOUNDS]. */ - -static void -push_array_bounds (bounds) - int bounds; -{ - PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i); -} - -/* Compute the maximum size in bytes of the printed spelling. */ - -static int -spelling_length () -{ - register int size = 0; - register struct spelling *p; - - for (p = spelling_base; p < spelling; p++) - { - if (p->kind == SPELLING_BOUNDS) - size += 25; - else - size += strlen (p->u.s) + 1; - } - - return size; -} - -/* Print the spelling to BUFFER and return it. */ - -static char * -print_spelling (buffer) - register char *buffer; -{ - register char *d = buffer; - register char *s; - register struct spelling *p; - - for (p = spelling_base; p < spelling; p++) - if (p->kind == SPELLING_BOUNDS) - { - sprintf (d, "[%d]", p->u.i); - d += strlen (d); - } - else - { - if (p->kind == SPELLING_MEMBER) - *d++ = '.'; - for (s = p->u.s; *d = *s++; d++) - ; - } - *d++ = '\0'; - return buffer; -} - -/* Provide a means to pass component names derived from the spelling stack. */ - -char initialization_message; - -/* Interpret the spelling of the given ERRTYPE message. */ - -static char * -get_spelling (errtype) - char *errtype; -{ - static char *buffer; - static int size = -1; - - if (errtype == &initialization_message) - { - /* Avoid counting chars */ - static char message[] = "initialization of `%s'"; - register int needed = sizeof (message) + spelling_length () + 1; - char *temp; - - if (size < 0) - buffer = (char *) xmalloc (size = needed); - if (needed > size) - buffer = (char *) xrealloc (buffer, size = needed); - - temp = (char *) alloca (needed); - sprintf (buffer, message, print_spelling (temp)); - return buffer; - } - - return errtype; -} - -/* Issue an error message for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ - -void -error_init (format, local, ofwhat) - char *format, *local, *ofwhat; -{ - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); - - if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - error (format, buffer); -} - -/* Issue a pedantic warning for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ - -void -pedwarn_init (format, local, ofwhat) - char *format, *local, *ofwhat; -{ - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); - - if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - pedwarn (format, buffer); -} - -/* Keep a pointer to the last free TREE_LIST node as we digest an initializer, - so that we can reuse it. This is set in digest_init, and used in - process_init_constructor. - - We will never keep more than one free TREE_LIST node here. This is for - two main reasons. First, we take elements off the old list and add them - to the new list one at a time, thus there should never be more than - one free TREE_LIST at a time, and thus even if there is, we will never - need more than one. Secondly, to avoid dangling pointers to freed obstacks, - we want to always ensure that we have either a pointer to a valid TREE_LIST - within the current initializer, or else a pointer to null. */ - -static tree free_tree_list = NULL_TREE; - -/* Digest the parser output INIT as an initializer for type TYPE. - Return a C expression of type TYPE to represent the initial value. - - If TAIL is nonzero, it points to a variable holding a list of elements - of which INIT is the first. We update the list stored there by - removing from the head all the elements that we use. - Normally this is only one; we use more than one element only if - TYPE is an aggregate and INIT is not a constructor. - - The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors - if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT - applies only to elements of constructors. - - If OFWHAT is nonnull, it specifies what we are initializing, for error - messages. Examples: variable name, variable.member, array[44]. - If OFWHAT is null, the component name is stored on the spelling stack. - (That is true for all nested calls to digest_init.) */ - -tree -digest_init (type, init, tail, require_constant, constructor_constant, ofwhat) - tree type, init, *tail; - int require_constant, constructor_constant; - char *ofwhat; -{ - enum tree_code code = TREE_CODE (type); - tree element = 0; - tree old_tail_contents; - /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR - tree node which has no TREE_TYPE. */ - int raw_constructor - = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0; - tree inside_init = init; - - /* Make sure there is just one "partially bracketed" message - per top-level initializer or constructor. */ - if (ofwhat != 0) - partial_bracket_mentioned = 0; - - /* By default, assume we use one element from a list. - We correct this later in the cases where it is not true. - - Thus, we update TAIL now to point to the next element, and save the - old value in OLD_TAIL_CONTENTS. If we didn't actually use the first - element, then we will reset TAIL before proceeding. FREE_TREE_LIST - is handled similarly. */ - - if (tail) - { - old_tail_contents = *tail; - *tail = TREE_CHAIN (*tail); - free_tree_list = old_tail_contents; - } - else - free_tree_list = 0; - - if (init == error_mark_node) - return init; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - /* Do not use STRIP_NOPS here. We do not want an enumerator - whose value is 0 to count as a null pointer constant. */ - if (TREE_CODE (init) == NON_LVALUE_EXPR) - inside_init = TREE_OPERAND (init, 0); - - if (inside_init && raw_constructor - && CONSTRUCTOR_ELTS (inside_init) != 0 - && TREE_CHAIN (CONSTRUCTOR_ELTS (inside_init)) == 0) - { - element = TREE_VALUE (CONSTRUCTOR_ELTS (inside_init)); - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (element && TREE_CODE (element) == NON_LVALUE_EXPR) - element = TREE_OPERAND (element, 0); - } - - /* Initialization of an array of chars from a string constant - optionally enclosed in braces. */ - - if (code == ARRAY_TYPE) - { - tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if ((typ1 == char_type_node - || typ1 == signed_char_type_node - || typ1 == unsigned_char_type_node - || typ1 == unsigned_wchar_type_node - || typ1 == signed_wchar_type_node) - && ((inside_init && TREE_CODE (inside_init) == STRING_CST) - || (element && TREE_CODE (element) == STRING_CST))) - { - tree string = element ? element : inside_init; - - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - != char_type_node) - && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) - { - error_init ("char-array%s initialized from wide string", - " `%s'", ofwhat); - return error_mark_node; - } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - == char_type_node) - && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) - { - error_init ("int-array%s initialized from non-wide string", - " `%s'", ofwhat); - return error_mark_node; - } - - TREE_TYPE (string) = type; - if (TYPE_DOMAIN (type) != 0 - && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) - { - register int size = TREE_INT_CST_LOW (TYPE_SIZE (type)); - size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; - /* Subtract 1 (or sizeof (wchar_t)) - because it's ok to ignore the terminating null char - that is counted in the length of the constant. */ - if (size < TREE_STRING_LENGTH (string) - - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) - ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT - : 1)) - pedwarn_init ( - "initializer-string for array of chars%s is too long", - " `%s'", ofwhat); - } - return string; - } - } - - /* Any type except an array can be initialized - from an expression of the same type, optionally with braces. - For an array, this is allowed only for a string constant. */ - - if (inside_init && TREE_TYPE (inside_init) != 0 - && ((TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)) - == TYPE_MAIN_VARIANT (type)) - || (code == ARRAY_TYPE - && comptypes (TREE_TYPE (inside_init), type)) - || (code == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE) - && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), - TREE_TYPE (type))))) - { - if (code == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)) - inside_init = default_conversion (inside_init); - else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", ofwhat); - return error_mark_node; - } - - if (optimize && TREE_READONLY (inside_init) - && TREE_CODE (inside_init) == VAR_DECL) - inside_init = decl_constant_value (inside_init); - - if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - inside_init = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", ofwhat); - inside_init = error_mark_node; - } - - return inside_init; - } - - if (element && (TREE_TYPE (element) == type - || (code == ARRAY_TYPE && TREE_TYPE (element) - && comptypes (TREE_TYPE (element), type)))) - { - if (code == ARRAY_TYPE) - { - error_init ("array%s initialized from non-constant array expression", - " `%s'", ofwhat); - return error_mark_node; - } - if (pedantic && (code == RECORD_TYPE || code == UNION_TYPE)) - pedwarn ("single-expression nonscalar initializer has braces"); - if (optimize && TREE_READONLY (element) && TREE_CODE (element) == VAR_DECL) - element = decl_constant_value (element); - - if (require_constant && ! TREE_CONSTANT (element)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - element = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", ofwhat); - element = error_mark_node; - } - - return element; - } - - /* Check for initializing a union by its first field. - Such an initializer must use braces. */ - - if (code == UNION_TYPE) - { - tree result; - tree field = TYPE_FIELDS (type); - - /* Find the first named field. ANSI decided in September 1990 - that only named fields count here. */ - while (field && DECL_NAME (field) == 0) - field = TREE_CHAIN (field); - - if (field == 0) - { - error_init ("union%s with no named members cannot be initialized", - " `%s'", ofwhat); - return error_mark_node; - } - - if (raw_constructor) - result = process_init_constructor (type, inside_init, NULL_PTR, - require_constant, - constructor_constant, ofwhat); - else if (tail != 0) - { - *tail = old_tail_contents; - free_tree_list = NULL_TREE; - result = process_init_constructor (type, NULL_TREE, tail, - require_constant, - constructor_constant, ofwhat); - } - else - result = 0; - - if (result) - return result; - } - - /* Handle scalar types, including conversions. */ - - if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE - || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) - { - if (raw_constructor) - { - if (element == 0) - { - error_init ( - "initializer for scalar%s requires one element", - " `%s'", ofwhat); - return error_mark_node; - } - else - { - /* Deal with extra levels of {...}. */ - if (TREE_CODE (element) == CONSTRUCTOR - && TREE_TYPE (element) == 0) - { - error_init ( - "initializer for scalar%s requires one element", - " `%s'", ofwhat); - return error_mark_node; - } - inside_init = element; - } - } - -#if 0 /* A non-raw constructor is an actual expression. */ - if (TREE_CODE (inside_init) == CONSTRUCTOR) - { - error_init ("initializer for scalar%s has extra braces", - " `%s'", ofwhat); - return error_mark_node; - } -#endif - - SAVE_SPELLING_DEPTH - ({ - if (ofwhat) - push_string (ofwhat); - if (!raw_constructor) - inside_init = init; - /* Note that convert_for_assignment calls default_conversion - for arrays and functions. We must not call it in the - case where inside_init is a null pointer constant. */ - inside_init - = convert_for_assignment (type, inside_init, - &initialization_message, - NULL_TREE, NULL_TREE, 0); - }); - - if (require_constant && ! TREE_CONSTANT (inside_init)) - { - error_init ("initializer element%s is not constant", - " for `%s'", ofwhat); - inside_init = error_mark_node; - } - else if (require_constant - && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) - { - error_init ("initializer element%s is not computable at load time", - " for `%s'", ofwhat); - inside_init = error_mark_node; - } - - return inside_init; - } - - /* Come here only for records and arrays. */ - - if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - { - error_init ("variable-sized object%s may not be initialized", - " `%s'", ofwhat); - return error_mark_node; - } - - if (code == ARRAY_TYPE || code == RECORD_TYPE) - { - if (raw_constructor) - return process_init_constructor (type, inside_init, - NULL_PTR, constructor_constant, - constructor_constant, ofwhat); - else if (tail != 0) - { - *tail = old_tail_contents; - free_tree_list = NULL_TREE; - return process_init_constructor (type, NULL_TREE, tail, - constructor_constant, - constructor_constant, ofwhat); - } - else if (flag_traditional) - /* Traditionally one can say `char x[100] = 0;'. */ - return process_init_constructor (type, - build_nt (CONSTRUCTOR, NULL_TREE, - tree_cons (NULL_TREE, - inside_init, - NULL_TREE)), - NULL_PTR, constructor_constant, - constructor_constant, ofwhat); - } - - error_init ("invalid initializer%s", " for `%s'", ofwhat); - return error_mark_node; -} - -/* Process a constructor for a variable of type TYPE. - The constructor elements may be specified either with INIT or with ELTS, - only one of which should be non-null. - - If INIT is specified, it is a CONSTRUCTOR node which is specifically - and solely for initializing this datum. - - If ELTS is specified, it is the address of a variable containing - a list of expressions. We take as many elements as we need - from the head of the list and update the list. - - In the resulting constructor, TREE_CONSTANT is set if all elts are - constant, and TREE_STATIC is set if, in addition, all elts are simple enough - constants that the assembler and linker can compute them. - - The argument CONSTANT_VALUE says to print an error if either the - value or any element is not a constant. - - The argument CONSTANT_ELEMENT says to print an error if an element - of an aggregate is not constant. It does not apply to a value - which is not a constructor. - - OFWHAT is a character string describing the object being initialized, - for error messages. It might be "variable" or "variable.member" - or "variable[17].member[5]". - - If OFWHAT is null, the description string is stored on the spelling - stack. That is always true for recursive calls. */ - -static tree -process_init_constructor (type, init, elts, constant_value, constant_element, - ofwhat) - tree type, init, *elts; - int constant_value, constant_element; - char *ofwhat; -{ - register tree tail; - /* List of the elements of the result constructor, - in reverse order. */ - register tree members = NULL; - tree result; - int allconstant = 1; - int allsimple = 1; - int erroneous = 0; - int depth = SPELLING_DEPTH (); - - if (ofwhat) - push_string (ofwhat); - - /* Make TAIL be the list of elements to use for the initialization, - no matter how the data was given to us. */ - - if (elts) - { - if (warn_missing_braces) - { - if (! partial_bracket_mentioned) - warning ("aggregate has a partly bracketed initializer"); - partial_bracket_mentioned = 1; - } - tail = *elts; - } - else - tail = CONSTRUCTOR_ELTS (init); - - /* Gobble as many elements as needed, and make a constructor or initial value - for each element of this aggregate. Chain them together in result. - If there are too few, use 0 for each scalar ultimate component. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree min_index, max_index; - /* These are non-zero only within a range initializer. */ - tree start_index = 0, end_index = 0; - /* Within a range, this is the value for the elts in the range. */ - tree range_val = 0; - /* Do arithmetic using double integers, but don't use fold/build, - because these allocate a new tree object everytime they are called, - thus resulting in gcc using too much memory for large - initializers. */ - union tree_node current_index_node, members_index_node; - tree current_index = ¤t_index_node; - tree members_index = &members_index_node; - TREE_TYPE (current_index) = integer_type_node; - TREE_TYPE (members_index) = integer_type_node; - - /* If we have array bounds, set our bounds from that. Otherwise, - we have a lower bound of zero and an unknown upper bound. */ - if (TYPE_DOMAIN (type)) - { - min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); - max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); - } - else - { - min_index = integer_zero_node; - max_index = 0; - } - - TREE_INT_CST_LOW (members_index) = TREE_INT_CST_LOW (min_index); - TREE_INT_CST_HIGH (members_index) = TREE_INT_CST_HIGH (min_index); - - /* Don't leave the loop based on index if the next item has an explicit - index value that will override it. */ - - for (TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (min_index), - TREE_INT_CST_HIGH (current_index) = TREE_INT_CST_HIGH (min_index); - tail != 0 || end_index; - add_double (TREE_INT_CST_LOW (current_index), - TREE_INT_CST_HIGH (current_index), 1, 0, - &TREE_INT_CST_LOW (current_index), - &TREE_INT_CST_HIGH (current_index))) - { - register tree next1 = 0; - - /* Handle the case where we are inside of a range. - current_index increments through the range, - so just keep reusing the same element of TAIL - until the end of the range. */ - if (end_index != 0) - { - next1 = range_val; - if (!tree_int_cst_lt (current_index, end_index)) - end_index = 0; - } - - /* If this element specifies an index, - move to that index before storing it in the new list. */ - else if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - tree index = TREE_PURPOSE (tail); - - if (index && (TREE_CODE (index) == NON_LVALUE_EXPR - || TREE_CODE (index) == NOP_EXPR)) - index = TREE_OPERAND (index, 0); - - /* Begin a range. */ - if (TREE_CODE (index) == TREE_LIST) - { - start_index = TREE_PURPOSE (index); - end_index = TREE_PURPOSE (TREE_CHAIN (index)); - - /* Expose constants. It Doesn't matter if we change - the mode.*/ - if (end_index - && (TREE_CODE (end_index) == NON_LVALUE_EXPR - || TREE_CODE (end_index) == NOP_EXPR)) - end_index = TREE_OPERAND (end_index, 0); - if (start_index - && (TREE_CODE (start_index) == NON_LVALUE_EXPR - || TREE_CODE (start_index) == NOP_EXPR)) - start_index = TREE_OPERAND (start_index, 0); - - constant_expression_warning (start_index); - constant_expression_warning (end_index); - - if ((TREE_CODE (start_index) == IDENTIFIER_NODE) - || (TREE_CODE (end_index) == IDENTIFIER_NODE)) - error ("field name used as index in array initializer"); - else if ((TREE_CODE (start_index) != INTEGER_CST) - || (TREE_CODE (end_index) != INTEGER_CST)) - error ("non-constant or non-integer array index in initializer"); - else if (tree_int_cst_lt (start_index, min_index) - || (max_index && tree_int_cst_lt (max_index, start_index)) - || tree_int_cst_lt (end_index, min_index) - || (max_index && tree_int_cst_lt (max_index, end_index))) - error ("array index out of range in initializer"); - else if (tree_int_cst_lt (end_index, start_index)) - { - /* If the range is empty, don't initialize any elements, - but do reset current_index for the next initializer - element. */ - warning ("empty array initializer range"); - tail = TREE_CHAIN (tail); - TREE_INT_CST_LOW (current_index) - = TREE_INT_CST_LOW (end_index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (end_index); - continue; - } - else - { - TREE_INT_CST_LOW (current_index) - = TREE_INT_CST_LOW (start_index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (start_index); - win = 1; - /* See if the first element is also the last. */ - if (!tree_int_cst_lt (current_index, end_index)) - end_index = 0; - } - } - else if (TREE_CODE (index) == IDENTIFIER_NODE) - error ("field name used as index in array initializer"); - else if (TREE_CODE (index) != INTEGER_CST) - error ("non-constant array index in initializer"); - else if (tree_int_cst_lt (index, min_index) - || (max_index && tree_int_cst_lt (max_index, index))) - error ("array index out of range in initializer"); - else - { - constant_expression_warning (index); - TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (index); - TREE_INT_CST_HIGH (current_index) - = TREE_INT_CST_HIGH (index); - win = 1; - } - - if (!win) - { - /* If there was an error, end the current range. */ - end_index = 0; - TREE_VALUE (tail) = error_mark_node; - } - } - - if (max_index && tree_int_cst_lt (max_index, current_index)) - break; /* Stop if we've indeed run out of elements. */ - - /* Now digest the value specified. */ - if (next1 != 0) - ; - else if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the element of this array, with "[]" notation. For - error messages, we assume that the index fits within a - host int. */ - SAVE_SPELLING_DEPTH - ({ - push_array_bounds (TREE_INT_CST_LOW (current_index)); - next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TREE_VALUE (tail), &tail1, - /* Both of these are the same because - a value here is an elt overall. */ - constant_element, constant_element, - NULL_PTR); - }); - - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - if (tail == tail1 && TYPE_DOMAIN (type) == 0) - { - error_init ( - "non-empty initializer for array%s of empty elements", - " `%s'", NULL_PTR); - /* Just ignore what we were supposed to use. */ - tail1 = 0; - } - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (end_index != 0) - range_val = next1; - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - - /* Now store NEXT1 in the list, I elements from the *end*. - Make the list longer if necessary. */ - while (! tree_int_cst_lt (current_index, members_index)) - { - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = NULL_TREE; - TREE_VALUE (free_tree_list) = NULL_TREE; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (NULL_TREE, NULL_TREE, members); - add_double (TREE_INT_CST_LOW (members_index), - TREE_INT_CST_HIGH (members_index), 1, 0, - &TREE_INT_CST_LOW (members_index), - &TREE_INT_CST_HIGH (members_index)); - } - - { - tree temp; - union tree_node idx_node; - tree idx = &idx_node; - TREE_TYPE (idx) = integer_type_node; - - temp = members; - for (add_double (TREE_INT_CST_LOW (members_index), - TREE_INT_CST_HIGH (members_index), -1, -1, - &TREE_INT_CST_LOW (idx), - &TREE_INT_CST_HIGH (idx)); - tree_int_cst_lt (current_index, idx); - add_double (TREE_INT_CST_LOW (idx), - TREE_INT_CST_HIGH (idx), -1, -1, - &TREE_INT_CST_LOW (idx), - &TREE_INT_CST_HIGH (idx))) - temp = TREE_CHAIN (temp); - TREE_VALUE (temp) = next1; - } - } - } - if (TREE_CODE (type) == RECORD_TYPE) - { - register tree field; - int members_length = 0; - int i; - - /* Don't leave the loop based on field just yet; see if next item - overrides the expected field first. */ - - for (field = TYPE_FIELDS (type), i = 0; tail; - field = TREE_CHAIN (field), i++) - { - register tree next1; - - /* If this element specifies a field, - move to that field before storing it in the new list. */ - if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - - if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) - error ("index value instead of field name in structure initializer"); - else - { - tree temp; - int j; - for (temp = TYPE_FIELDS (type), j = 0; - temp; - temp = TREE_CHAIN (temp), j++) - if (DECL_NAME (temp) == TREE_PURPOSE (tail)) - break; - if (temp) - field = temp, i = j, win = 1; - else - error ("no field `%s' in structure being initialized", - IDENTIFIER_POINTER (TREE_PURPOSE (tail))); - } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } - - if (field == 0) - break; /* No more fields to init. */ - - if (! DECL_NAME (field)) - { - next1 = integer_zero_node; - } - else if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the name of this member, with a "." for membership. */ - SAVE_SPELLING_DEPTH - ({ - push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1, - constant_element, constant_element, - NULL_PTR); - }); - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - - /* Now store NEXT1 in the list, I elements from the *end*. - Make the list longer if necessary. */ - while (i >= members_length) - { - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = NULL_TREE; - TREE_VALUE (free_tree_list) = NULL_TREE; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (NULL_TREE, NULL_TREE, members); - members_length++; - } - { - tree temp; - int j; - - temp = members; - for (j = members_length - 1; j > i; j--) - temp = TREE_CHAIN (temp); - TREE_VALUE (temp) = next1; - TREE_PURPOSE (temp) = field; - } - } - } - if (TREE_CODE (type) == UNION_TYPE) - { - register tree field = TYPE_FIELDS (type); - register tree next1; - - /* Find the first named field. ANSI decided in September 1990 - that only named fields count here. */ - while (field && DECL_NAME (field) == 0) - field = TREE_CHAIN (field); - - /* For a union, get the initializer for 1 fld. */ - - if (tail == 0) - { - error ("empty initializer for union"); - tail = build_tree_list (0, 0); - } - - /* If this element specifies a field, initialize via that field. */ - if (TREE_PURPOSE (tail) != 0) - { - int win = 0; - - if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL) - /* Handle the case of a call by build_c_cast. */ - field = TREE_PURPOSE (tail), win = 1; - else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) - error ("index value instead of field name in union initializer"); - else - { - tree temp; - for (temp = TYPE_FIELDS (type); - temp; - temp = TREE_CHAIN (temp)) - if (DECL_NAME (temp) == TREE_PURPOSE (tail)) - break; - if (temp) - field = temp, win = 1; - else - error ("no field `%s' in union being initialized", - IDENTIFIER_POINTER (TREE_PURPOSE (tail))); - } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } - - if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - /* Build the name of this member, with a "." for membership. */ - SAVE_SPELLING_DEPTH - ({ - push_member_name (IDENTIFIER_POINTER (DECL_NAME (field))); - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1, - constant_value, constant_element, NULL_PTR); - }); - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - abort (); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - if (free_tree_list) - { - TREE_CHAIN (free_tree_list) = members; - TREE_PURPOSE (free_tree_list) = field; - TREE_VALUE (free_tree_list) = next1; - members = free_tree_list; - free_tree_list = NULL_TREE; - } - else - members = tree_cons (field, next1, members); - } - - /* If arguments were specified as a list, just remove the ones we used. */ - if (elts) - *elts = tail; - /* If arguments were specified as a constructor, - complain unless we used all the elements of the constructor. */ - else if (tail) - { - if (TREE_CODE (type) == UNION_TYPE) - { - pedwarn_init ("excess elements in union initializer%s", - " after `%s'", NULL_PTR); - } - else - { - pedwarn_init ("excess elements in aggregate initializer%s", - " after `%s'", NULL_PTR); - } - } - - /* It might be possible to use SAVE_SPELLING_DEPTH, but I suspect that - some preprocessor somewhere won't accept that much text as an argument. - It's also likely to make debugging difficult. */ - - RESTORE_SPELLING_DEPTH (depth); - - if (erroneous) - return error_mark_node; - - if (elts) - result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); - else - { - result = init; - CONSTRUCTOR_ELTS (result) = nreverse (members); - TREE_TYPE (result) = type; - TREE_CONSTANT (result) = 0; - TREE_STATIC (result) = 0; - } - if (allconstant) TREE_CONSTANT (result) = 1; - if (allconstant && allsimple) TREE_STATIC (result) = 1; - return result; -} - -/* Expand an ASM statement with operands, handling output operands - that are not variables or INDIRECT_REFS by transforming such - cases into cases that expand_asm_operands can handle. - - Arguments are same as for expand_asm_operands. */ - -void -c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) - tree string, outputs, inputs, clobbers; - int vol; - char *filename; - int line; -{ - int noutputs = list_length (outputs); - register int i; - /* o[I] is the place that output number I should be written. */ - register tree *o = (tree *) alloca (noutputs * sizeof (tree)); - register tree tail; - - if (TREE_CODE (string) == ADDR_EXPR) - string = TREE_OPERAND (string, 0); - if (TREE_CODE (string) != STRING_CST) - { - error ("asm template is not a string constant"); - return; - } - - /* Record the contents of OUTPUTS before it is modified. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - o[i] = TREE_VALUE (tail); - - /* Perform default conversions on array and function inputs. */ - /* Don't do this for other types-- - it would screw up operands expected to be in memory. */ - for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++) - if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE) - TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail)); - - /* Generate the ASM_OPERANDS insn; - store into the TREE_VALUEs of OUTPUTS some trees for - where the values were actually stored. */ - expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); - - /* Copy all the intermediate outputs into the specified outputs. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - { - if (o[i] != TREE_VALUE (tail)) - { - expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), - 0, VOIDmode, 0); - free_temp_slots (); - } - /* Detect modification of read-only values. - (Otherwise done by build_modify_expr.) */ - else - { - tree type = TREE_TYPE (o[i]); - if (TYPE_READONLY (type) - || ((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (type))) - readonly_warning (o[i], "modification by `asm'"); - } - } - - /* Those MODIFY_EXPRs could do autoincrements. */ - emit_queue (); -} - -/* Expand a C `return' statement. - RETVAL is the expression for what to return, - or a null pointer for `return;' with no value. */ - -void -c_expand_return (retval) - tree retval; -{ - tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)); - - if (TREE_THIS_VOLATILE (current_function_decl)) - warning ("function declared `volatile' has a `return' statement"); - - if (!retval) - { - current_function_returns_null = 1; - if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) - warning ("`return' with no value, in function returning non-void"); - expand_null_return (); - } - else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) - { - current_function_returns_null = 1; - if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn ("`return' with a value, in function returning void"); - expand_return (retval); - } - else - { - tree t = convert_for_assignment (valtype, retval, "return", - NULL_TREE, NULL_TREE, 0); - tree res = DECL_RESULT (current_function_decl); - t = build (MODIFY_EXPR, TREE_TYPE (res), - res, convert (TREE_TYPE (res), t)); - expand_return (t); - current_function_returns_value = 1; - } -} - -/* Start a C switch statement, testing expression EXP. - Return EXP if it is valid, an error node otherwise. */ - -tree -c_expand_start_case (exp) - tree exp; -{ - register enum tree_code code = TREE_CODE (TREE_TYPE (exp)); - tree type = TREE_TYPE (exp); - - if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK) - { - error ("switch quantity not an integer"); - exp = error_mark_node; - } - else - { - tree index; - type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - - if (warn_traditional - && (type == long_integer_type_node - || type == long_unsigned_type_node)) - pedwarn ("`long' switch expression not converted to `int' in ANSI C"); - - exp = default_conversion (exp); - type = TREE_TYPE (exp); - index = get_unwidened (exp, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TREE_UNSIGNED (TREE_TYPE (exp)) - == TREE_UNSIGNED (TREE_TYPE (index))) - exp = index; - } - - expand_start_case (1, exp, type, "switch statement"); - - return exp; -} diff --git a/gnu/usr.bin/gcc2/cc1obj/Makefile b/gnu/usr.bin/gcc2/cc1obj/Makefile deleted file mode 100644 index 073f50a7365..00000000000 --- a/gnu/usr.bin/gcc2/cc1obj/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:29 deraadt Exp $ - -PROG= cc1obj - -SRCS= objc-parse.c objc-act.c c-lex.c c-pragma.c c-decl.c \ - c-typeck.c c-convert.c c-aux-info.c c-iterate.c - -.PATH: $(.CURDIR)/../cc1 - -.include <../Makefile.cc1> diff --git a/gnu/usr.bin/gcc2/cc1obj/objc-act.c b/gnu/usr.bin/gcc2/cc1obj/objc-act.c deleted file mode 100644 index 7030045b5cc..00000000000 --- a/gnu/usr.bin/gcc2/cc1obj/objc-act.c +++ /dev/null @@ -1,7640 +0,0 @@ -/* Implement classes and message passing for Objective C. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Author: Steve Naroff. - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: objc-act.c,v 1.1.1.1 1995/10/18 08:39:29 deraadt Exp $"; -#endif /* not lint */ - -/* Purpose: This module implements the Objective-C 4.0 language. - - compatibility issues (with the Stepstone translator): - - - does not recognize the following 3.3 constructs. - @requires, @classes, @messages, = (...) - - methods with variable arguments must conform to ANSI standard. - - tagged structure definitions that appear in BOTH the interface - and implementation are not allowed. - - public/private: all instance variables are public within the - context of the implementation...I consider this to be a bug in - the translator. - - statically allocated objects are not supported. the user will - receive an error if this service is requested. - - code generation `options': - - - OBJC_INT_SELECTORS */ - -#include -#include "config.h" -#include "tree.h" -#include "c-tree.h" -#include "c-lex.h" -#include "flags.h" -#include "objc-act.h" -#include "input.h" -#include "function.h" - -/* This is the default way of generating a method name. */ -/* I am not sure it is really correct. - Perhaps there's a danger that it will make name conflicts - if method names contain underscores. -- rms. */ -#ifndef OBJC_GEN_METHOD_LABEL -#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \ - do { \ - char *temp; \ - sprintf ((BUF), "_%s_%s_%s_%s", \ - ((IS_INST) ? "i" : "c"), \ - (CLASS_NAME), \ - ((CAT_NAME)? (CAT_NAME) : ""), \ - (SEL_NAME)); \ - for (temp = (BUF); *temp; temp++) \ - if (*temp == ':') *temp = '_'; \ - } while (0) -#endif - -/* These need specifying. */ -#ifndef OBJC_FORWARDING_STACK_OFFSET -#define OBJC_FORWARDING_STACK_OFFSET 0 -#endif - -#ifndef OBJC_FORWARDING_MIN_OFFSET -#define OBJC_FORWARDING_MIN_OFFSET 0 -#endif - -/* Define the special tree codes that we use. */ - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char *objc_tree_code_type[] = { - "x", -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int objc_tree_code_length[] = { - 0, -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *objc_tree_code_name[] = { - "@@dummy", -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Set up for use of obstacks. */ - -#include "obstack.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* This obstack is used to accumulate the encoding of a data type. */ -static struct obstack util_obstack; -/* This points to the beginning of obstack contents, - so we can free the whole contents. */ -char *util_firstobj; - -/* for encode_method_def */ -#include "rtl.h" -#include "c-parse.h" - -#define OBJC_VERSION 5 -#define PROTOCOL_VERSION 2 - -#define NULLT (tree) 0 - -#define OBJC_ENCODE_INLINE_DEFS 0 -#define OBJC_ENCODE_DONT_INLINE_DEFS 1 - -/*** Private Interface (procedures) ***/ - -/* used by compile_file */ - -static void init_objc PROTO((void)); -static void finish_objc PROTO((void)); - -/* code generation */ - -static void synth_module_prologue PROTO((void)); -static char *build_module_descriptor PROTO((void)); -static tree init_module_descriptor PROTO((void)); -static tree build_objc_method_call PROTO((int, tree, tree, tree, tree, tree)); -static void generate_strings PROTO((void)); -static void build_selector_translation_table PROTO((void)); -static tree build_ivar_chain PROTO((tree, int)); - -static tree build_ivar_template PROTO((void)); -static tree build_method_template PROTO((void)); -static tree build_private_template PROTO((tree)); -static void build_class_template PROTO((void)); -static void build_category_template PROTO((void)); -static tree build_super_template PROTO((void)); -static tree build_category_initializer PROTO((tree, tree, tree, tree, tree)); -static tree build_protocol_initializer PROTO((tree, tree, tree, tree)); - -static void synth_forward_declarations PROTO((void)); -static void generate_ivar_lists PROTO((void)); -static void generate_dispatch_tables PROTO((void)); -static void generate_shared_structures PROTO((void)); -static tree generate_protocol_list PROTO((tree)); -static void generate_forward_declaration_to_string_table PROTO((void)); -static void build_protocol_reference PROTO((tree)); - -static tree init_selector PROTO((int)); -static tree build_keyword_selector PROTO((tree)); -static tree synth_id_with_class_suffix PROTO((char *, tree)); - -/* misc. bookkeeping */ - -typedef struct hashed_entry *hash; -typedef struct hashed_attribute *attr; - -struct hashed_attribute -{ - attr next; - tree value; -}; -struct hashed_entry -{ - attr list; - hash next; - tree key; -}; - -static void hash_init PROTO((void)); -static void hash_enter PROTO((hash *, tree)); -static hash hash_lookup PROTO((hash *, tree)); -static void hash_add_attr PROTO((hash, tree)); -static tree lookup_method PROTO((tree, tree)); -static tree lookup_instance_method_static PROTO((tree, tree)); -static tree lookup_class_method_static PROTO((tree, tree)); -static tree add_class PROTO((tree)); -static void add_category PROTO((tree, tree)); - -enum string_section -{ - class_names, /* class, category, protocol, module names */ - meth_var_names, /* method and variable names */ - meth_var_types /* method and variable type descriptors */ -}; - -static tree add_objc_string PROTO((tree, enum string_section)); -static tree build_objc_string_decl PROTO((tree, enum string_section)); -static tree build_selector_reference_decl PROTO((tree)); - -/* protocol additions */ - -static tree add_protocol PROTO((tree)); -static tree lookup_protocol PROTO((tree)); -static tree lookup_and_install_protocols PROTO((tree)); - -/* type encoding */ - -static void encode_type_qualifiers PROTO((tree)); -static void encode_pointer PROTO((tree, int, int)); -static void encode_array PROTO((tree, int, int)); -static void encode_aggregate PROTO((tree, int, int)); -static void encode_bitfield PROTO((int, int)); -static void encode_type PROTO((tree, int, int)); -static void encode_field_decl PROTO((tree, int, int)); - -static void really_start_method PROTO((tree, tree)); -static int comp_method_with_proto PROTO((tree, tree)); -static int comp_proto_with_proto PROTO((tree, tree)); -static tree get_arg_type_list PROTO((tree, int, int)); -static tree expr_last PROTO((tree)); - -/* utilities for debugging and error diagnostics: */ - -static void warn_with_method PROTO((char *, int, tree)); -static void error_with_ivar PROTO((char *, tree, tree)); -static char *gen_method_decl PROTO((tree, char *)); -static char *gen_declaration PROTO((tree, char *)); -static char *gen_declarator PROTO((tree, char *, char *)); -static int is_complex_decl PROTO((tree)); -static void adorn_decl PROTO((tree, char *)); -static void dump_interface PROTO((FILE *, tree)); - -/* everything else. */ - -static void objc_fatal PROTO((void)); -static tree define_decl PROTO((tree, tree)); -static tree lookup_method_in_protocol_list PROTO((tree, tree, int)); -static tree lookup_protocol_in_reflist PROTO((tree, tree)); -static tree create_builtin_decl PROTO((enum tree_code, tree, char *)); -static tree my_build_string PROTO((int, char *)); -static void build_objc_symtab_template PROTO((void)); -static tree init_def_list PROTO((void)); -static tree init_objc_symtab PROTO((void)); -static void forward_declare_categories PROTO((void)); -static void generate_objc_symtab_decl PROTO((void)); -static tree build_selector PROTO((tree)); -static tree build_msg_pool_reference PROTO((int)); -static tree build_selector_reference PROTO((tree)); -static tree build_class_reference_decl PROTO((tree)); -static void add_class_reference PROTO((tree)); -static tree objc_copy_list PROTO((tree, tree *)); -static tree build_protocol_template PROTO((void)); -static tree build_descriptor_table_initializer PROTO((tree, int *)); -static tree build_method_prototype_list_template PROTO((tree, int)); -static tree build_method_prototype_template PROTO((void)); -static int forwarding_offset PROTO((tree)); -static tree encode_method_prototype PROTO((tree, tree)); -static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree)); -static void generate_method_descriptors PROTO((tree)); -static tree build_tmp_function_decl PROTO((void)); -static void hack_method_prototype PROTO((tree, tree)); -static void generate_protocol_references PROTO((tree)); -static void generate_protocols PROTO((void)); -static void check_ivars PROTO((tree, tree)); -static tree build_ivar_list_template PROTO((tree, int)); -static tree build_method_list_template PROTO((tree, int)); -static tree build_ivar_list_initializer PROTO((tree, int *)); -static tree generate_ivars_list PROTO((tree, char *, int, tree)); -static tree build_dispatch_table_initializer PROTO((tree, int *)); -static tree generate_dispatch_table PROTO((tree, char *, int, tree)); -static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, int, tree, tree, tree)); -static void generate_category PROTO((tree)); -static int is_objc_type_qualifier PROTO((tree)); -static tree adjust_type_for_id_default PROTO((tree)); -static tree check_duplicates PROTO((hash)); -static tree receiver_is_class_object PROTO((tree)); -static int check_methods PROTO((tree, tree, int)); -static int conforms_to_protocol PROTO((tree, tree)); -static void check_protocols PROTO((tree, char *, char *)); -static tree encode_method_def PROTO((tree)); -static void gen_declspecs PROTO((tree, char *, int)); -static void generate_classref_translation_entry PROTO((tree)); -static void handle_class_ref PROTO((tree)); - -/*** Private Interface (data) ***/ - -/* reserved tag definitions: */ - -#define TYPE_ID "id" -#define TAG_OBJECT "objc_object" -#define TAG_CLASS "objc_class" -#define TAG_SUPER "objc_super" -#define TAG_SELECTOR "objc_selector" - -#define UTAG_CLASS "_objc_class" -#define UTAG_IVAR "_objc_ivar" -#define UTAG_IVAR_LIST "_objc_ivar_list" -#define UTAG_METHOD "_objc_method" -#define UTAG_METHOD_LIST "_objc_method_list" -#define UTAG_CATEGORY "_objc_category" -#define UTAG_MODULE "_objc_module" -#define UTAG_SYMTAB "_objc_symtab" -#define UTAG_SUPER "_objc_super" - -#define UTAG_PROTOCOL "_objc_protocol" -#define UTAG_PROTOCOL_LIST "_objc_protocol_list" -#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype" -#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list" - -#define STRING_OBJECT_CLASS_NAME "NXConstantString" -#define PROTOCOL_OBJECT_CLASS_NAME "Protocol" - -static char* TAG_GETCLASS; -static char* TAG_GETMETACLASS; -static char* TAG_MSGSEND; -static char* TAG_MSGSENDSUPER; -static char* TAG_EXECCLASS; - -/* Set by `continue_class' and checked by `is_public'. */ - -#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type)) -#define TYPED_OBJECT(type) \ - (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type)) - -/* Some commonly used instances of "identifier_node". */ - -static tree self_id, ucmd_id; - -static tree self_decl, umsg_decl, umsg_super_decl; -static tree objc_get_class_decl, objc_get_meta_class_decl; - -static tree super_type, selector_type, id_type, objc_class_type; -static tree instance_type, protocol_type; - -/* Type checking macros. */ - -#define IS_ID(TYPE) \ - (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type)) -#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ - (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) -#define IS_SUPER(TYPE) \ - (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type)) - -static tree class_chain = NULLT; -static tree alias_chain = NULLT; -static tree interface_chain = NULLT; -static tree protocol_chain = NULLT; - -/* chains to manage selectors that are referenced and defined in the module */ - -static tree cls_ref_chain = NULLT; /* classes referenced */ -static tree sel_ref_chain = NULLT; /* selectors referenced */ - -/* chains to manage uniquing of strings */ - -static tree class_names_chain = NULLT; -static tree meth_var_names_chain = NULLT; -static tree meth_var_types_chain = NULLT; - -/* hash tables to manage the global pool of method prototypes */ - -static hash *nst_method_hash_list = 0; -static hash *cls_method_hash_list = 0; - -/* backend data declarations */ - -static tree UOBJC_SYMBOLS_decl; -static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl; -static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl; -static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl; -static tree UOBJC_SELECTOR_TABLE_decl; -static tree UOBJC_MODULES_decl; -static tree UOBJC_STRINGS_decl; - -/* The following are used when compiling a class implementation. - implementation_template will normally be an interface, however if - none exists this will be equal to implementation_context...it is - set in start_class. */ - -static tree implementation_context = NULLT, - implementation_template = NULLT; - -struct imp_entry -{ - struct imp_entry *next; - tree imp_context; - tree imp_template; - tree class_decl; /* _OBJC_CLASS_; */ - tree meta_decl; /* _OBJC_METACLASS_; */ -}; - -static void handle_impent PROTO((struct imp_entry *)); - -static struct imp_entry *imp_list = 0; -static int imp_count = 0; /* `@implementation' */ -static int cat_count = 0; /* `@category' */ - -static tree objc_class_template, objc_category_template, uprivate_record; -static tree objc_protocol_template; -static tree ucls_super_ref, uucls_super_ref; - -static tree objc_method_template, objc_ivar_template; -static tree objc_symtab_template, objc_module_template; -static tree objc_super_template, objc_object_reference; - -static tree objc_object_id, objc_class_id, objc_id_id; -static tree constant_string_id; -static tree constant_string_type; -static tree UOBJC_SUPER_decl; - -static tree method_context = NULLT; -static int method_slot = 0; /* used by start_method_def */ - -#define BUFSIZE 1024 - -static char *errbuf; /* a buffer for error diagnostics */ - -/* data imported from tree.c */ - -extern struct obstack permanent_obstack, *current_obstack, *rtl_obstack; - -/* data imported from toplev.c */ - -extern char *dump_base_name; - -/* Generate code for GNU or NeXT runtime environment. */ - -#ifdef NEXT_OBJC_RUNTIME -int flag_next_runtime = 1; -#else -int flag_next_runtime = 0; -#endif - -/* Open and close the file for outputting class declarations, if requested. */ - -int flag_gen_declaration = 0; - -FILE *gen_declaration_file; - -/* Warn if multiple methods are seen for the same selector, but with - different argument types. */ - -int warn_selector = 0; - -/* Warn if methods required by a protocol are not implemented in the - class adopting it. When turned off, methods inherited to that - class are also considered implemented */ - -int flag_warn_protocol = 1; - -/* tells "encode_pointer/encode_aggregate" whether we are generating - type descriptors for instance variables (as opposed to methods). - Type descriptors for instance variables contain more information - than methods (for static typing and embedded structures). This - was added to support features being planned for dbkit2. */ - -static int generating_instance_variables = 0; - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ - ungetc (check_newline (), finput); - - /* If gen_declaration desired, open the output file. */ - if (flag_gen_declaration) - { - int dump_base_name_length = strlen (dump_base_name); - register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); - strcpy (dumpname, dump_base_name); - strcat (dumpname, ".decl"); - gen_declaration_file = fopen (dumpname, "w"); - if (gen_declaration_file == 0) - pfatal_with_name (dumpname); - } - - if (flag_next_runtime) - { - TAG_GETCLASS = "objc_getClass"; - TAG_GETMETACLASS = "objc_getMetaClass"; - TAG_MSGSEND = "objc_msgSend"; - TAG_MSGSENDSUPER = "objc_msgSendSuper"; - TAG_EXECCLASS = "__objc_execClass"; - } - else - { - TAG_GETCLASS = "objc_get_class"; - TAG_GETMETACLASS = "objc_get_meta_class"; - TAG_MSGSEND = "objc_msg_lookup"; - TAG_MSGSENDSUPER = "objc_msg_lookup_super"; - TAG_EXECCLASS = "__objc_exec_class"; - } - - if (doing_objc_thang) - init_objc (); -} - -static void -objc_fatal () -{ - fatal ("Objective-C text in C source file"); -} - -void -objc_finish () -{ - if (doing_objc_thang) - finish_objc (); /* Objective-C finalization */ - - if (gen_declaration_file) - fclose (gen_declaration_file); -} - -void -lang_finish () -{ -} - -char * -lang_identify () -{ - return "objc"; -} - -int -lang_decode_option (p) - char *p; -{ - if (!strcmp (p, "-lang-objc")) - doing_objc_thang = 1; - else if (!strcmp (p, "-gen-decls")) - flag_gen_declaration = 1; - else if (!strcmp (p, "-Wselector")) - warn_selector = 1; - else if (!strcmp (p, "-Wno-selector")) - warn_selector = 0; - else if (!strcmp (p, "-Wprotocol")) - flag_warn_protocol = 1; - else if (!strcmp (p, "-Wno-protocol")) - flag_warn_protocol = 0; - else if (!strcmp (p, "-fgnu-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-next-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-gnu-runtime")) - flag_next_runtime = 1; - else if (!strcmp (p, "-fnext-runtime")) - flag_next_runtime = 1; - else - return c_decode_option (p); - - return 1; -} - -static tree -define_decl (declarator, declspecs) - tree declarator; - tree declspecs; -{ - tree decl = start_decl (declarator, declspecs, 0); - finish_decl (decl, NULLT, NULLT); - return decl; -} - -/* Return 1 if LHS and RHS are compatible types for assignment or - various other operations. Return 0 if they are incompatible, and - return -1 if we choose to not decide. When the operation is - REFLEXIVE, check for compatibility in either direction. - - For statically typed objects, an assignment of the form `a' = `b' - is permitted if: - - `a' is of type "id", - `a' and `b' are the same class type, or - `a' and `b' are of class types A and B such that B is a descendant of A. */ - -int -maybe_objc_comptypes (lhs, rhs, reflexive) - tree lhs, rhs; - int reflexive; -{ - if (doing_objc_thang) - return objc_comptypes (lhs, rhs, reflexive); - return -1; -} - -static tree -lookup_method_in_protocol_list (rproto_list, sel_name, class_meth) - tree rproto_list; - tree sel_name; - int class_meth; -{ - tree rproto, p; - tree fnd = 0; - - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if ((fnd = lookup_method (class_meth - ? PROTOCOL_CLS_METHODS (p) - : PROTOCOL_NST_METHODS (p), sel_name))) - ; - else if (PROTOCOL_LIST (p)) - fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), sel_name, class_meth); - } - else - ; /* an identifier...if we could not find a protocol. */ - - if (fnd) - return fnd; - } - return 0; -} - -static tree -lookup_protocol_in_reflist (rproto_list, lproto) - tree rproto_list; - tree lproto; -{ - tree rproto, p; - - /* make sure the protocol is support by the object on the rhs */ - if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE) - { - tree fnd = 0; - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if (lproto == p) - fnd = lproto; - - else if (PROTOCOL_LIST (p)) - fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto); - } - - if (fnd) - return fnd; - } - } - else - ; /* an identifier...if we could not find a protocol. */ - - return 0; -} - -/* Return 1 if LHS and RHS are compatible types for assignment - or various other operations. Return 0 if they are incompatible, - and return -1 if we choose to not decide. When the operation - is REFLEXIVE, check for compatibility in either direction. */ - -int -objc_comptypes (lhs, rhs, reflexive) - tree lhs; - tree rhs; - int reflexive; -{ - /* new clause for protocols */ - - if (TREE_CODE (lhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE - && TREE_CODE (rhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) - { - int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); - int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); - - if (lhs_is_proto) - { - tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); - tree rproto, rproto_list; - tree p; - - if (rhs_is_proto) - { - rproto_list = TYPE_PROTOCOL_LIST (rhs); - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - if (!rproto) - warning ("object does not conform to the `%s' protocol", - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - else if (TYPED_OBJECT (TREE_TYPE (rhs))) - { - tree rname = TYPE_NAME (TREE_TYPE (rhs)); - tree rinter; - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = 0; - rinter = lookup_interface (rname); - - while (rinter && !rproto) - { - tree cat; - - rproto_list = CLASS_PROTOCOL_LIST (rinter); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - /* NEW!!! */ - /* Check for protocols adopted by categories. */ - cat = CLASS_CATEGORY_LIST (rinter); - while (cat && !rproto) - { - rproto_list = CLASS_PROTOCOL_LIST (cat); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - cat = CLASS_CATEGORY_LIST (cat); - } - - rinter = lookup_interface (CLASS_SUPER_NAME (rinter)); - } - if (!rproto) - warning ("class `%s' does not implement the `%s' protocol", - IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - - return 1; /* may change...based on whether there was any mismatch */ - } - else if (rhs_is_proto) - { - /* lhs is not a protocol...warn if it is statically typed */ - - if (TYPED_OBJECT (TREE_TYPE (lhs))) - return 0; - else - return 1; /* one of the types is a protocol */ - } - else - return -1; /* defer to comptypes */ - } - else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE) - ; /* fall thru...this is the case we have been handling all along */ - else - return -1; /* defer to comptypes */ - - /* End of new protocol support. */ - - /* `id' = ` *', ` *' = `id' */ - - if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) - || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs))) - return 1; - - /* `id' = `Class', `Class' = `id' */ - - else if ((TYPE_NAME (lhs) == objc_object_id - && TYPE_NAME (rhs) == objc_class_id) - || (TYPE_NAME (lhs) == objc_class_id - && TYPE_NAME (rhs) == objc_object_id)) - return 1; - - /* ` *' = ` *' */ - - else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs)) - { - tree lname = TYPE_NAME (lhs); - tree rname = TYPE_NAME (rhs); - tree inter; - - if (lname == rname) - return 1; - - /* If the left hand side is a super class of the right hand side, - allow it. */ - for (inter = lookup_interface (rname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (lname == CLASS_SUPER_NAME (inter)) - return 1; - - /* Allow the reverse when reflexive. */ - if (reflexive) - for (inter = lookup_interface (lname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (rname == CLASS_SUPER_NAME (inter)) - return 1; - - return 0; - } - else - return -1; /* defer to comptypes */ -} - -/* Called from c-decl.c before all calls to rest_of_decl_compilation. */ - -void -objc_check_decl (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == RECORD_TYPE - && TREE_STATIC_TEMPLATE (type) - && type != constant_string_type) - { - error_with_decl (decl, "`%s' cannot be statically allocated"); - fatal ("statically allocated objects not supported"); - } -} - -void -maybe_objc_check_decl (decl) - tree decl; -{ - if (doing_objc_thang) - objc_check_decl (decl); -} - -/* Implement static typing. At this point, we know we have an interface. */ - -tree -get_static_reference (interface, protocols) - tree interface; - tree protocols; -{ - tree type = xref_tag (RECORD_TYPE, interface); - - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - struct obstack *ambient_obstack = current_obstack; - - current_obstack = &permanent_obstack; - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - current_obstack = ambient_obstack; - - /* Look up protocols and install in lang specific list. */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = NULL; - - type = t; - } - - return type; -} - -tree -get_object_reference (protocols) - tree protocols; -{ - tree type_decl = lookup_name (objc_id_id); - tree type; - - if (type_decl && TREE_CODE (type_decl) == TYPE_DECL) - { - type = TREE_TYPE (type_decl); - if (TYPE_MAIN_VARIANT (type) != id_type) - warning ("Unexpected type for `id' (%s)", - gen_declaration (type, errbuf)); - } - else - { - fatal ("Undefined type `id', please import "); - } - - /* This clause creates a new pointer type that is qualified with - the protocol specification...this info is used later to do more - elaborate type checking. */ - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - struct obstack *ambient_obstack = current_obstack; - - current_obstack = &permanent_obstack; - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - current_obstack = ambient_obstack; - - /* look up protocols...and install in lang specific list */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = NULL; - - type = t; - } - return type; -} - -static tree -lookup_and_install_protocols (protocols) - tree protocols; -{ - tree proto; - tree prev = NULL; - tree return_value = protocols; - - for (proto = protocols; proto; proto = TREE_CHAIN (proto)) - { - tree ident = TREE_VALUE (proto); - tree p = lookup_protocol (ident); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (ident)); - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (proto); - else - return_value = TREE_CHAIN (proto); - } - else - { - /* replace identifier with actual protocol node */ - TREE_VALUE (proto) = p; - prev = proto; - } - } - return return_value; -} - -/* Create and push a decl for a built-in external variable or field NAME. - CODE says which. - TYPE is its data type. */ - -static tree -create_builtin_decl (code, type, name) - enum tree_code code; - tree type; - char *name; -{ - tree decl = build_decl (code, get_identifier (name), type); - if (code == VAR_DECL) - { - TREE_STATIC (decl) = 1; - make_decl_rtl (decl, 0, 1); - pushdecl (decl); - } - return decl; -} - -/* purpose: "play" parser, creating/installing representations - of the declarations that are required by Objective-C. - - model: - - type_spec--------->sc_spec - (tree_list) (tree_list) - | | - | | - identifier_node identifier_node */ - -static void -synth_module_prologue () -{ - tree temp_type; - tree super_p; - - /* defined in `objc.h' */ - objc_object_id = get_identifier (TAG_OBJECT); - - objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); - - id_type = build_pointer_type (objc_object_reference); - - objc_id_id = get_identifier (TYPE_ID); - objc_class_id = get_identifier (TAG_CLASS); - - objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id)); - protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (PROTOCOL_OBJECT_CLASS_NAME))); - - /* Declare type of selector-objects that represent an operation name. */ - -#ifdef OBJC_INT_SELECTORS - /* `unsigned int' */ - selector_type = unsigned_type_node; -#else - /* `struct objc_selector *' */ - selector_type - = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); -#endif /* not OBJC_INT_SELECTORS */ - - /* Forward declare type, or else the prototype for msgSendSuper will - complain. */ - - super_p = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))); - - - /* id objc_msgSend (id, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, id_type, - tree_cons (NULLT, selector_type, NULLT))); - - if (! flag_next_runtime) - { - umsg_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_MSGSEND), temp_type); - DECL_EXTERNAL (umsg_decl) = 1; - TREE_PUBLIC (umsg_decl) = 1; - DECL_INLINE (umsg_decl) = 1; - - if (flag_traditional && TAG_MSGSEND[0] != '_') - DECL_BUILT_IN_NONANSI (umsg_decl) = 1; - - make_decl_rtl (umsg_decl, NULL_PTR, 1); - pushdecl (umsg_decl); - } - else - umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0); - - /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, super_p, - tree_cons (NULLT, selector_type, NULLT))); - - umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, - temp_type, NOT_BUILT_IN, 0); - - /* id objc_getClass (const char *); */ - - temp_type = build_function_type (id_type, - tree_cons (NULLT, - const_string_type_node, - tree_cons (NULLT, void_type_node, NULLT))); - - objc_get_class_decl - = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0); - - /* id objc_getMetaClass (const char *); */ - - objc_get_meta_class_decl - = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0); - - /* static SEL _OBJC_SELECTOR_TABLE[]; */ - - if (! flag_next_runtime) - UOBJC_SELECTOR_TABLE_decl - = create_builtin_decl (VAR_DECL, build_array_type (selector_type, NULLT), - "_OBJC_SELECTOR_TABLE"); - - generate_forward_declaration_to_string_table (); - - /* Forward declare constant_string_id and constant_string_type. */ - constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME); - constant_string_type = xref_tag (RECORD_TYPE, constant_string_id); -} - -/* Custom build_string which sets TREE_TYPE! */ - -static tree -my_build_string (len, str) - int len; - char *str; -{ - int wide_flag = 0; - tree a_string = build_string (len, str); - /* Some code from combine_strings, which is local to c-parse.y. */ - if (TREE_TYPE (a_string) == int_array_type_node) - wide_flag = 1; - - TREE_TYPE (a_string) = - build_array_type (wide_flag ? integer_type_node : char_type_node, - build_index_type (build_int_2 (len - 1, 0))); - - TREE_CONSTANT (a_string) = 1; /* puts string in the ".text" segment */ - TREE_STATIC (a_string) = 1; - - return a_string; -} - -/* Return a newly constructed OBJC_STRING_CST node whose value is - the LEN characters at STR. - The TREE_TYPE is not initialized. */ - -tree -build_objc_string (len, str) - int len; - char *str; -{ - tree s = build_string (len, str); - - TREE_SET_CODE (s, OBJC_STRING_CST); - return s; -} - -/* Given a chain of OBJC_STRING_CST's, build a static instance of - NXConstantString which points at the concatenation of those strings. - We place the string object in the __string_objects section of the - __OBJC segment. The Objective-C runtime will initialize the isa - pointers of the string objects to point at the NXConstantString - class object. */ - -tree -build_objc_string_object (strings) - tree strings; -{ - tree string, initlist, constructor; - int length; - - if (!doing_objc_thang) - objc_fatal (); - - if (lookup_interface (constant_string_id) == NULLT) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (constant_string_id)); - return error_mark_node; - } - - add_class_reference (constant_string_id); - - /* combine_strings will work for OBJC_STRING_CST's too. */ - string = combine_strings (strings); - TREE_SET_CODE (string, STRING_CST); - length = TREE_STRING_LENGTH (string) - 1; - - /* & ((NXConstantString) {0, string, length}) */ - - initlist = build_tree_list (NULLT, build_int_2 (0, 0)); - initlist = tree_cons (NULLT, build_unary_op (ADDR_EXPR, string, 1), - initlist); - initlist = tree_cons (NULLT, build_int_2 (length, 0), initlist); - constructor = build (CONSTRUCTOR, constant_string_type, NULLT, - nreverse (initlist)); - TREE_CONSTANT (constructor) = 1; - TREE_STATIC (constructor) = 1; - TREE_READONLY (constructor) = 1; - - return build_unary_op (ADDR_EXPR, constructor, 1); -} - -/* Take care of defining and initializing _OBJC_SYMBOLS. */ - -/* Predefine the following data type: - - struct _objc_symtab - { - long sel_ref_cnt; - SEL *refs; - short cls_def_cnt; - short cat_def_cnt; - void *defs[cls_def_cnt + cat_def_cnt]; - }; */ - -static void -build_objc_symtab_template () -{ - tree field_decl, field_decl_chain, index; - - objc_symtab_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB)); - - /* long sel_ref_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - long_integer_type_node, - "sel_ref_cnt"); - field_decl_chain = field_decl; - - /* SEL *refs; */ - - field_decl = create_builtin_decl (FIELD_DECL, - build_pointer_type (selector_type), - "refs"); - chainon (field_decl_chain, field_decl); - - /* short cls_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cls_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* short cat_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cat_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* void *defs[cls_def_cnt + cat_def_cnt]; */ - - index = build_index_type (build_int_2 (imp_count + cat_count - 1, - imp_count == 0 && cat_count == 0 - ? -1 : 0)); - field_decl = create_builtin_decl (FIELD_DECL, - build_array_type (ptr_type_node, index), - "defs"); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_symtab_template, field_decl_chain); -} - -/* Create the initial value for the `defs' field of _objc_symtab. - This is a CONSTRUCTOR. */ - -static tree -init_def_list () -{ - tree expr, initlist = NULLT; - struct imp_entry *impent; - - if (imp_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - } - - if (cat_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - } - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* Construct the initial value for all of _objc_symtab. */ - -static tree -init_objc_symtab () -{ - tree initlist; - - /* sel_ref_cnt = { ..., 5, ... } */ - - initlist = build_tree_list (NULLT, build_int_2 (0, 0)); - - /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - - if (flag_next_runtime || ! sel_ref_chain) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - initlist = tree_cons (NULLT, UOBJC_SELECTOR_TABLE_decl, initlist); - - /* cls_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULLT, build_int_2 (imp_count, 0), initlist); - - /* cat_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULLT, build_int_2 (cat_count, 0), initlist); - - /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - - if (imp_count || cat_count) - initlist = tree_cons (NULLT, init_def_list (), initlist); - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* Push forward-declarations of all the categories - so that init_def_list can use them in a CONSTRUCTOR. */ - -static void -forward_declare_categories () -{ - struct imp_entry *impent; - tree sav = implementation_context; - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - /* Set an invisible arg to synth_id_with_class_suffix. */ - implementation_context = impent->imp_context; - impent->class_decl - = create_builtin_decl (VAR_DECL, objc_category_template, - IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context))); - } - } - implementation_context = sav; -} - -/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab' - and initialized appropriately. */ - -static void -generate_objc_symtab_decl () -{ - tree sc_spec; - - if (!objc_category_template) - build_category_template (); - - /* forward declare categories */ - if (cat_count) - forward_declare_categories (); - - if (!objc_symtab_template) - build_objc_symtab_template (); - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]); - - UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"), - tree_cons (NULLT, objc_symtab_template, sc_spec), 1); - - end_temporary_allocation (); /* start_decl trying to be smart about inits */ - TREE_USED (UOBJC_SYMBOLS_decl) = 1; - DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1; - finish_decl (UOBJC_SYMBOLS_decl, init_objc_symtab (), NULLT); -} - -static tree -init_module_descriptor () -{ - tree initlist, expr; - - /* version = { 1, ... } */ - - expr = build_int_2 (OBJC_VERSION, 0); - initlist = build_tree_list (NULLT, expr); - - /* size = { ..., sizeof (struct objc_module), ... } */ - - expr = size_in_bytes (objc_module_template); - initlist = tree_cons (NULLT, expr, initlist); - - /* name = { ..., "foo.m", ... } */ - - expr = add_objc_string (get_identifier (input_filename), class_names); - initlist = tree_cons (NULLT, expr, initlist); - - /* symtab = { ..., _OBJC_SYMBOLS, ... } */ - - if (UOBJC_SYMBOLS_decl) - expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0); - else - expr = build_int_2 (0, 0); - initlist = tree_cons (NULLT, expr, initlist); - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* Write out the data structures to describe Objective C classes defined. - If appropriate, compile and output a setup function to initialize them. - Return a string which is the name of a function to call to initialize - the Objective C data structures for this file (and perhaps for other files - also). - - struct objc_module { ... } _OBJC_MODULE = { ... }; - -*/ - -static char * -build_module_descriptor () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_module_template = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE)); - - /* long version; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* long size; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("size"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_symtab *symtab; */ - - decl_specs = get_identifier (UTAG_SYMTAB); - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("symtab")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_module_template, field_decl_chain); - - /* create an instance of "objc_module" */ - - decl_specs = tree_cons (NULLT, objc_module_template, - build_tree_list (NULLT, ridpointers[(int) RID_STATIC])); - - UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"), - decl_specs, 1); - - end_temporary_allocation (); /* start_decl trying to be smart about inits */ - DECL_IGNORED_P (UOBJC_MODULES_decl) = 1; - finish_decl (UOBJC_MODULES_decl, init_module_descriptor (), NULLT); - - /* Mark the decl to avoid "defined but not used" warning. */ - DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1; - - /* Generate a constructor call for the module descriptor. - This code was generated by reading the grammar rules - of c-parse.y; Therefore, it may not be the most efficient - way of generating the requisite code. */ - - if (flag_next_runtime) - return 0; - - { - tree parms, function_decl, decelerator, void_list_node; - tree function_type; - char *buf; - char *global_object_name = 0; - tree t; - - /* Use a global object (which is already required to be unique over - the program) rather than the file name (which imposes extra - constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */ - - /* Find the name of some global object defined in this file. */ - for (t = getdecls (); t; t = TREE_CHAIN (t)) - if (TREE_PUBLIC (t) && !DECL_EXTERNAL (t) && DECL_INITIAL (t) != 0) - { - global_object_name = IDENTIFIER_POINTER (DECL_NAME (t)); - break; - } - - /* If none, use the name of the file. */ - if (!global_object_name) - { - char *p, *q; - global_object_name - = (char *) alloca (strlen (main_input_filename) + 1); - - p = main_input_filename; - q = global_object_name; - - /* Replace any weird characters in the file name. */ - for (; *p; p++) - if (! ((*p >= '0' && *p <= '9') - || (*p >= 'A' && *p <= 'Z') - || (*p >= 'a' && *p <= 'z'))) - *q++ = '_'; - else - *q++ = *p; - *q = 0; - } - - /* Make the constructor name from the name we have found. */ - buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT) - + strlen (global_object_name)); - sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name); - - /* Declare void __objc_execClass (void*); */ - - void_list_node = build_tree_list (NULL_TREE, void_type_node); - function_type - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)); - function_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_EXECCLASS), - function_type); - DECL_EXTERNAL (function_decl) = 1; - TREE_PUBLIC (function_decl) = 1; - pushdecl (function_decl); - rest_of_decl_compilation (function_decl, 0, 0, 0); - - parms - = build_tree_list (NULLT, - build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0)); - decelerator = build_function_call (function_decl, parms); - - /* void _GLOBAL_$I$ () {objc_execClass (&L_OBJC_MODULES);} */ - - start_function (void_list_node, - build_parse_node (CALL_EXPR, get_identifier (buf), - /* This has the format of the output - of get_parm_info. */ - tree_cons (NULL_TREE, NULL_TREE, - void_list_node), - NULL_TREE), - 0); -#if 0 /* This should be turned back on later - for the systems where collect is not needed. */ - /* Make these functions nonglobal - so each file can use the same name. */ - TREE_PUBLIC (current_function_decl) = 0; -#endif - TREE_USED (current_function_decl) = 1; - store_parm_decls (); - - assemble_external (function_decl); - c_expand_expr_stmt (decelerator); - - finish_function (0); - - /* Return the name of the constructor function. */ - return buf; - } -} - -/* extern const char _OBJC_STRINGS[]; */ - -static void -generate_forward_declaration_to_string_table () -{ - tree sc_spec, decl_specs, expr_decl; - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); - - expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT); - - UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs); -} - -/* Output all strings. */ - -static void -generate_strings () -{ - tree sc_spec, decl_specs, expr_decl; - tree chain, string_expr; - tree string, decl; - - for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT); - decl = start_decl (expr_decl, decl_specs, 1); - end_temporary_allocation (); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULLT); - } - - for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT); - decl = start_decl (expr_decl, decl_specs, 1); - end_temporary_allocation (); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULLT); - } - - for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULLT); - decl = start_decl (expr_decl, decl_specs, 1); - end_temporary_allocation (); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULLT); - } -} - -static tree -build_selector_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - struct obstack *save_current_obstack = current_obstack; - struct obstack *save_rtl_obstack = rtl_obstack; - static int idx = 0; - - sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++); - - /* new stuff */ - rtl_obstack = current_obstack = &permanent_obstack; - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, selector_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - - make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */ - pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */ - - current_obstack = save_current_obstack; - rtl_obstack = save_rtl_obstack; - - return decl; -} - -/* Just a handy wrapper for add_objc_string. */ - -static tree -build_selector (ident) - tree ident; -{ - tree expr = add_objc_string (ident, meth_var_names); - - return build_c_cast (selector_type, expr); /* cast! */ -} - -/* Synthesize the following expr: (char *)&_OBJC_STRINGS[] - The cast stops the compiler from issuing the following message: - grok.m: warning: initialization of non-const * pointer from const * - grok.m: warning: initialization between incompatible pointer types. */ - -static tree -build_msg_pool_reference (offset) - int offset; -{ - tree expr = build_int_2 (offset, 0); - tree cast; - - expr = build_array_ref (UOBJC_STRINGS_decl, expr); - expr = build_unary_op (ADDR_EXPR, expr, 0); - - cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]), - build1 (INDIRECT_REF, NULLT, NULLT)); - TREE_TYPE (expr) = groktypename (cast); - return expr; -} - -static tree -init_selector (offset) - int offset; -{ - tree expr = build_msg_pool_reference (offset); - TREE_TYPE (expr) = selector_type; /* cast */ - return expr; -} - -static void -build_selector_translation_table () -{ - tree sc_spec, decl_specs; - tree chain, initlist = NULLT; - int offset = 0; - tree decl, var_decl, name; - - /* The corresponding pop_obstacks is in finish_decl, - called at the end of this function. */ - if (! flag_next_runtime) - push_obstacks_nochange (); - - for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - tree expr; - - expr = build_selector (TREE_VALUE (chain)); - - if (flag_next_runtime) - { - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]); - - /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULLT, selector_type, sc_spec); - - var_decl = name; - - /* the `decl' that is returned from start_decl is the one that we - forward declared in `build_selector_reference' */ - decl = start_decl (var_decl, decl_specs, 1); - } - - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; - - if (flag_next_runtime) - { - end_temporary_allocation (); - finish_decl (decl, expr, NULLT); - } - else - initlist = tree_cons (NULLT, expr, initlist); - } - - if (! flag_next_runtime) - { - /* Cause the variable and its initial value to be actually output. */ - DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0; - TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1; - /* NULL terminate the list and fix the decl for output. */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1; - initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); - finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULLT); - } -} - -/* sel_ref_chain is a list whose "value" fields will be instances of - identifier_node that represent the selector. */ - -static tree -build_selector_reference (ident) - tree ident; -{ - tree *chain = &sel_ref_chain; - tree decl; - int index = 0; - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return (flag_next_runtime - ? TREE_PURPOSE (*chain) - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); - - index++; - chain = &TREE_CHAIN (*chain); - } - - decl = build_selector_reference_decl (ident); - - *chain = perm_tree_cons (decl, ident, NULLT); - - return (flag_next_runtime - ? decl - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); -} - -static tree -build_class_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - struct obstack *save_current_obstack = current_obstack; - struct obstack *save_rtl_obstack = rtl_obstack; - static int idx = 0; - - sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++); - - /* new stuff */ - rtl_obstack = current_obstack = &permanent_obstack; - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, objc_class_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - - make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */ - pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */ - - current_obstack = save_current_obstack; - rtl_obstack = save_rtl_obstack; - - return decl; -} - -/* Create a class reference, but don't create a variable to reference - it. */ - -static void -add_class_reference (ident) - tree ident; -{ - tree chain; - - if ((chain = cls_ref_chain)) - { - tree tail; - do - { - if (ident == TREE_VALUE (chain)) - return; - - tail = chain; - chain = TREE_CHAIN (chain); - } - while (chain); - - /* append to the end of the list */ - TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT); - } - else - cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT); -} - -/* Get a class reference, creating it if necessary. Also create the - reference variable. */ - -tree -get_class_reference (ident) - tree ident; -{ - if (flag_next_runtime) - { - tree *chain; - tree decl; - - for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) - if (TREE_VALUE (*chain) == ident) - { - if (! TREE_PURPOSE (*chain)) - TREE_PURPOSE (*chain) = build_class_reference_decl (ident); - return TREE_PURPOSE (*chain); - } - - decl = build_class_reference_decl (ident); - *chain = perm_tree_cons (decl, ident, NULLT); - return decl; - } - else - { - tree params; - - add_class_reference (ident); - - params = build_tree_list (NULLT, - my_build_string (IDENTIFIER_LENGTH (ident) + 1, - IDENTIFIER_POINTER (ident))); - - assemble_external (objc_get_class_decl); - return build_function_call (objc_get_class_decl, params); - } -} - -/* sel_refdef_chain is a list whose "value" fields will be instances - of identifier_node that represent the selector. It returns the - offset of the selector from the beginning of the _OBJC_STRINGS - pool. This offset is typically used by init_selector during code - generation. - - For each string section we have a chain which maps identifier nodes - to decls for the strings. */ - -static tree -add_objc_string (ident, section) - tree ident; - enum string_section section; -{ - tree *chain, decl; - - if (section == class_names) - chain = &class_names_chain; - else if (section == meth_var_names) - chain = &meth_var_names_chain; - else if (section == meth_var_types) - chain = &meth_var_types_chain; - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return TREE_PURPOSE (*chain); - - chain = &TREE_CHAIN (*chain); - } - - decl = build_objc_string_decl (ident, section); - - *chain = perm_tree_cons (decl, ident, NULLT); - - return decl; -} - -static tree -build_objc_string_decl (name, section) - tree name; - enum string_section section; -{ - tree decl, ident; - char buf[256]; - struct obstack *save_current_obstack = current_obstack; - struct obstack *save_rtl_obstack = rtl_obstack; - static int class_names_idx = 0; - static int meth_var_names_idx = 0; - static int meth_var_types_idx = 0; - - if (section == class_names) - sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++); - else if (section == meth_var_names) - sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); - else if (section == meth_var_types) - sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); - - rtl_obstack = current_obstack = &permanent_obstack; - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0)); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - TREE_CONSTANT (decl) = 1; - - make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation */ - pushdecl_top_level (decl); /* our `extended/custom' pushdecl in c-decl.c */ - - current_obstack = save_current_obstack; - rtl_obstack = save_rtl_obstack; - - return decl; -} - - -void -objc_declare_alias (alias_ident, class_ident) - tree alias_ident; - tree class_ident; -{ - if (!doing_objc_thang) - objc_fatal (); - - if (is_class_name (class_ident) != class_ident) - warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident)); - else if (is_class_name (alias_ident)) - warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident)); - else - alias_chain = tree_cons (class_ident, alias_ident, alias_chain); -} - -void -objc_declare_class (ident_list) - tree ident_list; -{ - tree list; - - if (!doing_objc_thang) - objc_fatal (); - - for (list = ident_list; list; list = TREE_CHAIN (list)) - { - tree ident = TREE_VALUE (list); - tree decl; - - if ((decl = lookup_name (ident))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (ident)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (! is_class_name (ident)) - { - tree record = xref_tag (RECORD_TYPE, ident); - TREE_STATIC_TEMPLATE (record) = 1; - class_chain = tree_cons (NULLT, ident, class_chain); - } - } -} - -tree -is_class_name (ident) - tree ident; -{ - tree chain; - - if (lookup_interface (ident)) - return ident; - - for (chain = class_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return ident; - } - - for (chain = alias_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return TREE_PURPOSE (chain); - } - - return 0; -} - -tree -lookup_interface (ident) - tree ident; -{ - tree chain; - - for (chain = interface_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == CLASS_NAME (chain)) - return chain; - } - return NULLT; -} - -static tree -objc_copy_list (list, head) - tree list; - tree *head; -{ - tree newlist = NULL_TREE, tail = NULL_TREE; - - while (list) - { - tail = copy_node (list); - - /* The following statement fixes a bug when inheriting instance - variables that are declared to be bitfields. finish_struct - expects to find the width of the bitfield in DECL_INITIAL, - which it nulls out after processing the decl of the super - class...rather than change the way finish_struct works (which - is risky), I create the situation it expects...s.naroff - (7/23/89). */ - - if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) - DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0); - - newlist = chainon (newlist, tail); - list = TREE_CHAIN (list); - } - *head = newlist; - return tail; -} - -/* Used by: build_private_template, get_class_ivars, and - continue_class. COPY is 1 when called from @defs. In this case - copy all fields. Otherwise don't copy leaf ivars since we rely on - them being side-effected exactly once by finish_struct. */ - -static tree -build_ivar_chain (interface, copy) - tree interface; - int copy; -{ - tree my_name, super_name, ivar_chain; - - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - /* Possibly copy leaf ivars. */ - if (copy) - objc_copy_list (CLASS_IVARS (interface), &ivar_chain); - else - ivar_chain = CLASS_IVARS (interface); - - while (super_name) - { - tree op1; - tree super_interface = lookup_interface (super_name); - - if (!super_interface) - { - /* fatal did not work with 2 args...should fix */ - error ("Cannot find interface declaration for `%s', superclass of `%s'", - IDENTIFIER_POINTER (super_name), - IDENTIFIER_POINTER (my_name)); - exit (34); - } - if (super_interface == interface) - { - fatal ("Circular inheritance in interface declaration for `%s'", - IDENTIFIER_POINTER (super_name)); - } - interface = super_interface; - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - op1 = CLASS_IVARS (interface); - if (op1) - { - tree head, tail = objc_copy_list (op1, &head); - - /* Prepend super class ivars...make a copy of the list, we - do not want to alter the original. */ - TREE_CHAIN (tail) = ivar_chain; - ivar_chain = head; - } - } - return ivar_chain; -} - -/* struct { - struct objc_class *isa; - ... - }; */ - -static tree -build_private_template (class) - tree class; -{ - tree ivar_context; - - if (CLASS_STATIC_TEMPLATE (class)) - { - uprivate_record = CLASS_STATIC_TEMPLATE (class); - ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class)); - } - else - { - uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class)); - - ivar_context = build_ivar_chain (class, 0); - - finish_struct (uprivate_record, ivar_context); - - CLASS_STATIC_TEMPLATE (class) = uprivate_record; - - /* mark this record as class template - for class type checking */ - TREE_STATIC_TEMPLATE (uprivate_record) = 1; - } - instance_type = groktypename (build_tree_list (build_tree_list (NULLT, uprivate_record), - build1 (INDIRECT_REF, NULLT, NULLT))); - return ivar_context; -} - -/* Begin code generation for protocols... */ - -/* struct objc_protocol { - char *protocol_name; - struct objc_protocol **protocol_list; - struct objc_method_desc *instance_methods; - struct objc_method_desc *class_methods; - }; */ - -static tree -build_protocol_template () -{ - tree decl_specs, field_decl, field_decl_chain; - tree template; - - template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* char *protocol_name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_name")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULLT, template); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - return finish_struct (template, field_decl_chain); -} - -static tree -build_descriptor_table_initializer (entries, size) - tree entries; - int *size; -{ - tree initlist = NULLT; - - do - { - initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), initlist); - - initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), meth_var_types), initlist); - - (*size)++; - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* struct objc_method_prototype_list { - int count; - struct objc_method_prototype { - SEL name; - char *types; - } list[1]; - }; */ - -static tree -build_method_prototype_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - /* generate an unnamed struct definition */ - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT); - - /* int method_count; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULLT, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain); - - return objc_ivar_list_record; -} - -static tree -build_method_prototype_template () -{ - tree proto_record; - tree decl_specs, field_decl, field_decl_chain; - - proto_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), NULLT); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd")); -#endif /* OBJC_INT_SELECTORS */ - - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (proto_record, field_decl_chain); - - return proto_record; -} - -static int -forwarding_offset (parm) - tree parm; -{ - int offset_in_bytes; - - if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM) - { - rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0); - - /* ??? Here we assume that the parm address is indexed - off the frame pointer or arg pointer. - If that is not true, we produce meaningless results, - but do not crash. */ - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - offset_in_bytes = INTVAL (XEXP (addr, 1)); - else - offset_in_bytes = 0; - - offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET; - } -#ifdef OBJC_FORWARDING_REG_OFFSET - else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG) - { - int regno = REGNO (DECL_INCOMING_RTL (parm)); - - offset_in_bytes = 4 * (regno - OBJC_FORWARDING_FIRST_REG) - + OBJC_FORWARDING_REG_OFFSET; - } -#endif /* OBJC_FORWARDING_REG_OFFSET */ - else - return 0; - - /* This is the case where the parm is passed as an int or double - and it is converted to a char, short or float and stored back - in the parmlist. In this case, describe the parm - with the variable's declared type, and adjust the address - if the least significant bytes (which we are using) are not - the first ones. */ -#if BYTES_BIG_ENDIAN - if (TREE_TYPE (parm) != DECL_ARG_TYPE (parm)) - offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm))) - - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm)))); -#endif - - return offset_in_bytes; -} - -static tree -encode_method_prototype (method_decl, func_decl) - tree method_decl; - tree func_decl; -{ - tree parms; - int stack_size, i; - tree user_args; - int max_parm_end = 0; - char buf[40]; - tree result; - - /* `oneway' and 'bycopy', for remote object are the only method qualifiers */ - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl))); - - /* C type */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* stack size */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (parm_end > max_parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buf, "%d", stack_size); - obstack_grow (&util_obstack, buf, strlen (buf)); - - user_args = METHOD_SEL_ARGS (method_decl); - - /* argument types */ - for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms; - parms = TREE_CHAIN (parms), i++) - { - /* process argument qualifiers for user supplied arguments */ - if (i > 1) - { - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args))); - user_args = TREE_CHAIN (user_args); - } - - /* type */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* compute offset */ - sprintf (buf, "%d", forwarding_offset (parms)); - obstack_grow (&util_obstack, buf, strlen (buf)); - } - - obstack_1grow (&util_obstack, '\0'); - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -static tree -generate_descriptor_table (type, name, size, list, proto) - tree type; - char *name; - int size; - tree list; - tree proto; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, proto), - decl_specs, 1); - end_temporary_allocation (); - - initlist = build_tree_list (NULLT, build_int_2 (size, 0)); - initlist = tree_cons (NULLT, list, initlist); - - finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT); - - return decl; -} - -static void -generate_method_descriptors (protocol) /* generate_dispatch_tables */ - tree protocol; -{ - static tree objc_method_prototype_template; - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_prototype_template) - objc_method_prototype_template = build_method_prototype_template (); - - cast = build_tree_list (build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), NULLT); - variable_length_type = groktypename (cast); - - chain = PROTOCOL_CLS_METHODS (protocol); - if (chain) - { - size = 0; - - initlist = build_descriptor_table_initializer (chain, &size); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - - UOBJC_CLASS_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_CLASS_METHODS", - size, initlist, protocol); - /* cast! */ - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = PROTOCOL_NST_METHODS (protocol); - if (chain) - { - size = 0; - initlist = build_descriptor_table_initializer (chain, &size); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - - UOBJC_INSTANCE_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_INSTANCE_METHODS", - size, initlist, protocol); - /* cast! */ - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -build_tmp_function_decl () -{ - tree decl_specs, expr_decl, parms; - - /* struct objc_object *objc_xxx (id, SEL, ...); */ - pushlevel (0); - decl_specs = build_tree_list (NULLT, objc_object_reference); - push_parm_decl (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULLT, NULLT))); - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULLT, NULLT); - - push_parm_decl (build_tree_list (decl_specs, expr_decl)); - parms = get_parm_info (0); - poplevel (0, 0, 0); - - decl_specs = build_tree_list (NULLT, objc_object_reference); - expr_decl = build_nt (CALL_EXPR, get_identifier ("objc_xxx"), parms, NULLT); - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); - - return define_decl (expr_decl, decl_specs); -} - -static void -hack_method_prototype (nst_methods, tmp_decl) - tree nst_methods; - tree tmp_decl; -{ - tree parms; - - /* Hack to avoid problem with static typing of self arg. */ - TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL); - start_method_def (nst_methods); - TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL); - - if (METHOD_ADD_ARGS (nst_methods) == (tree) 1) - parms = get_parm_info (0); /* we have a `, ...' */ - else - parms = get_parm_info (1); /* place a `void_at_end' */ - - poplevel (0, 0, 0); /* Must be called BEFORE start_function. */ - - /* Usually called from store_parm_decls -> init_function_start. */ - - init_emit (); /* needed to make assign_parms work (with -O). */ - - DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms); - - { - /* Code taken from start_function. */ - tree restype = TREE_TYPE (TREE_TYPE (tmp_decl)); - /* Promote the value to int before returning it. */ - if (TREE_CODE (restype) == INTEGER_TYPE - && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node)) - restype = integer_type_node; - DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype); - } - - /* Typically called from expand_function_start for function definitions. */ - assign_parms (tmp_decl, 0); - - /* install return type */ - TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods)); -} - -static void -generate_protocol_references (plist) - tree plist; -{ - tree lproto; - - /* forward declare protocols referenced */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree proto = TREE_VALUE (lproto); - - if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_NAME (proto)) - { - if (! PROTOCOL_FORWARD_DECL (proto)) - build_protocol_reference (proto); - - if (PROTOCOL_LIST (proto)) - generate_protocol_references (PROTOCOL_LIST (proto)); - } - } -} - -static void -generate_protocols () -{ - tree p, tmp_decl, encoding; - tree sc_spec, decl_specs, decl; - tree initlist, protocol_name_expr, refs_decl, refs_expr; - tree cast_type2 = 0; - - tmp_decl = build_tmp_function_decl (); - - if (! objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - /* if a protocol was directly referenced, pull in indirect references */ - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) - generate_protocol_references (PROTOCOL_LIST (p)); - - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - { - tree nst_methods = PROTOCOL_NST_METHODS (p); - tree cls_methods = PROTOCOL_CLS_METHODS (p); - - /* if protocol wasn't referenced, don't generate any code */ - if (! PROTOCOL_FORWARD_DECL (p)) - continue; - - /* Make sure we link in the Protocol class. */ - add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); - - while (nst_methods) - { - hack_method_prototype (nst_methods, tmp_decl); - encoding = encode_method_prototype (nst_methods, tmp_decl); - METHOD_ENCODING (nst_methods) = encoding; - - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - hack_method_prototype (cls_methods, tmp_decl); - encoding = encode_method_prototype (cls_methods, tmp_decl); - METHOD_ENCODING (cls_methods) = encoding; - - cls_methods = TREE_CHAIN (cls_methods); - } - generate_method_descriptors (p); - - if (PROTOCOL_LIST (p)) - refs_decl = generate_protocol_list (p); - else - refs_decl = 0; - - /* static struct objc_protocol _OBJC_PROTOCOL_; */ - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, objc_protocol_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p), - decl_specs, 1); - end_temporary_allocation (); - - protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); - - if (refs_decl) - { - if (!cast_type2) - cast_type2 - = groktypename (build_tree_list (build_tree_list (NULLT, objc_protocol_template), - build1 (INDIRECT_REF, NULLT, - build1 (INDIRECT_REF, NULLT, NULLT)))); - - refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0); - TREE_TYPE (refs_expr) = cast_type2; - } - else - refs_expr = build_int_2 (0, 0); - - /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set - by generate_method_descriptors, which is called above. */ - initlist = build_protocol_initializer (protocol_name_expr, refs_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl); - finish_decl (decl, initlist, NULLT); - - /* Mark the decl as used to avoid "defined but not used" warning. */ - TREE_USED (decl) = 1; - } -} - -static tree -build_protocol_initializer (protocol_name, protocol_list, - instance_methods, class_methods) - tree protocol_name; - tree protocol_list; - tree instance_methods; - tree class_methods; -{ - tree initlist = NULLT, expr; - static tree cast_type = 0; - - if (!cast_type) - cast_type - = groktypename (build_tree_list - (build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))), - build1 (INDIRECT_REF, NULLT, NULLT))); - - /* filling the "isa" in with one allows the runtime system to - detect that the version change...should remove before final release */ - - expr = build_int_2 (PROTOCOL_VERSION, 0); - TREE_TYPE (expr) = cast_type; - initlist = tree_cons (NULLT, expr, initlist); - initlist = tree_cons (NULLT, protocol_name, initlist); - initlist = tree_cons (NULLT, protocol_list, initlist); - - if (!instance_methods) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - if (!class_methods) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} -/* end code generation for protocols... */ - -/* struct objc_category { - char *category_name; - char *class_name; - struct objc_method_list *instance_methods; - struct objc_method_list *class_methods; - struct objc_protocol_list *protocols; - }; */ - -static void -build_category_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_category_template = start_struct (RECORD_TYPE, - get_identifier (UTAG_CATEGORY)); - /* char *category_name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("category_name")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* char *class_name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_name")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("instance_methods")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class_methods")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT) -; - chainon (field_decl_chain, field_decl); - - finish_struct (objc_category_template, field_decl_chain); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - }; */ - -static void -build_class_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_class_template = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULLT, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("isa")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* struct objc_class *super_class; */ - - decl_specs = build_tree_list (NULLT, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("super_class")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("name")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* long version; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* long info; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("info"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* long instance_size; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("instance_size"); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_ivar_list *ivars; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivars")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *methods; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("methods")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - if (flag_next_runtime) - { - /* struct objc_cache *cache; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier ("objc_cache"))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("cache")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - } - else - { - /* struct sarray *dtable; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier ("sarray"))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("dtable")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *subclass_list; */ - - decl_specs = build_tree_list (NULLT, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("subclass_list")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *sibling_class; */ - - decl_specs = build_tree_list (NULLT, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("sibling_class")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - } - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - - finish_struct (objc_class_template, field_decl_chain); -} - -/* Generate appropriate forward declarations for an implementation. */ - -static void -synth_forward_declarations () -{ - tree sc_spec, decl_specs, an_id; - - /* extern struct objc_class _OBJC_CLASS_; */ - - an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context); - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULLT, objc_class_template, sc_spec); - UOBJC_CLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_CLASS_decl) = 1; - - /* extern struct objc_class _OBJC_METACLASS_; */ - - an_id = synth_id_with_class_suffix ("_OBJC_METACLASS", - implementation_context); - - UOBJC_METACLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_METACLASS_decl) = 1; - - /* pre-build the following entities - for speed/convenience. */ - - an_id = get_identifier ("super_class"); - ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id); - uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id); -} - -static void -error_with_ivar (message, decl, rawdecl) - char *message; - tree decl; - tree rawdecl; -{ - count_error (0); - - report_error_function (DECL_SOURCE_FILE (decl)); - - fprintf (stderr, "%s:%d: ", - DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf)); -} - -#define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \ - TREE_CODE (t) == UNION_TYPE || \ - TREE_CODE (t) == ENUMERAL_TYPE) - -static void -check_ivars (inter, imp) - tree inter; - tree imp; -{ - tree intdecls = CLASS_IVARS (inter); - tree impdecls = CLASS_IVARS (imp); - tree rawintdecls = CLASS_RAW_IVARS (inter); - tree rawimpdecls = CLASS_RAW_IVARS (imp); - - while (1) - { - tree t1, t2; - - if (intdecls == 0 && impdecls == 0) - break; - if (intdecls == 0 || impdecls == 0) - { - error ("inconsistent instance variable specification"); - break; - } - t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls); - - if (!comptypes (t1, t2)) - { - if (DECL_NAME (intdecls) == DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable type", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - else /* both the type and the name don't match */ - { - error ("inconsistent instance variable specification"); - break; - } - } - else if (DECL_NAME (intdecls) != DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable name", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - intdecls = TREE_CHAIN (intdecls); - impdecls = TREE_CHAIN (impdecls); - rawintdecls = TREE_CHAIN (rawintdecls); - rawimpdecls = TREE_CHAIN (rawimpdecls); - } -} - -/* Set super_type to the data type node for struct objc_super *, - first defining struct objc_super itself. - This needs to be done just once per compilation. */ - -static tree -build_super_template () -{ - tree record, decl_specs, field_decl, field_decl_chain; - - record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER)); - - /* struct objc_object *self; */ - - decl_specs = build_tree_list (NULLT, objc_object_reference); - field_decl = get_identifier ("self"); - field_decl = build1 (INDIRECT_REF, NULLT, field_decl); - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* struct objc_class *class; */ - - decl_specs = get_identifier (UTAG_CLASS); - decl_specs = build_tree_list (NULLT, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("class")); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (record, field_decl_chain); - - /* `struct objc_super *' */ - super_type = groktypename (build_tree_list (build_tree_list (NULLT, record), - build1 (INDIRECT_REF, - NULLT, NULLT))); - return record; -} - -/* struct objc_ivar { - char *ivar_name; - char *ivar_type; - int ivar_offset; - }; */ - -static tree -build_ivar_template () -{ - tree objc_ivar_id, objc_ivar_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_id = get_identifier (UTAG_IVAR); - objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id); - - /* char *ivar_name; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_name")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULLT); - field_decl_chain = field_decl; - - /* char *ivar_type; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("ivar_type")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* int ivar_offset; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_offset"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_record, field_decl_chain); - - return objc_ivar_record; -} - -/* struct { - int ivar_count; - struct objc_ivar ivar_list[ivar_count]; - }; */ - -static tree -build_ivar_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT); - - /* int ivar_count; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_count"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULLT); - field_decl_chain = field_decl; - - /* struct objc_ivar ivar_list[]; */ - - decl_specs = build_tree_list (NULLT, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain); - - return objc_ivar_list_record; -} - -/* struct { - int method_next; - int method_count; - struct objc_method method_list[method_count]; - }; */ - -static tree -build_method_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULLT); - - /* int method_next; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_next"); - - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - /* int method_count; */ - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULLT, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain); - - return objc_ivar_list_record; -} - -static tree -build_ivar_list_initializer (field_decl, size) - tree field_decl; - int *size; -{ - tree initlist = NULLT; - - do - { - /* set name */ - if (DECL_NAME (field_decl)) - initlist = tree_cons (NULLT, - add_objc_string (DECL_NAME (field_decl), - meth_var_names), - initlist); - else - /* unnamed bit-field ivar (yuck). */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - - /* set type */ - encode_field_decl (field_decl, - obstack_object_size (&util_obstack), - OBJC_ENCODE_DONT_INLINE_DEFS); - obstack_1grow (&util_obstack, 0); /* null terminate string */ - initlist - = tree_cons - (NULLT, - add_objc_string (get_identifier (obstack_finish (&util_obstack)), - meth_var_types), - initlist); - obstack_free (&util_obstack, util_firstobj); - - /* set offset */ - initlist - = tree_cons - (NULLT, - build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) - / BITS_PER_UNIT), - 0), - initlist); - (*size)++; - field_decl = TREE_CHAIN (field_decl); - } - while (field_decl); - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -static tree -generate_ivars_list (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1); - end_temporary_allocation (); - - initlist = build_tree_list (NULLT, build_int_2 (size, 0)); - initlist = tree_cons (NULLT, list, initlist); - - finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT); - - return decl; -} - -static void -generate_ivar_lists () -{ - tree initlist, ivar_list_template, chain; - tree cast, variable_length_type; - int size; - - generating_instance_variables = 1; - - if (!objc_ivar_template) - objc_ivar_template = build_ivar_template (); - - cast - = build_tree_list - (build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))), - NULLT); - variable_length_type = groktypename (cast); - - /* only generate class variables for the root of the inheritance - hierarchy since these will be the same for every class */ - - if (CLASS_SUPER_NAME (implementation_template) == NULLT - && (chain = TYPE_FIELDS (objc_class_template))) - { - size = 0; - initlist = build_ivar_list_initializer (chain, &size); - - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - - UOBJC_CLASS_VARIABLES_decl = - generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES", - size, initlist); - /* cast! */ - TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_CLASS_VARIABLES_decl = 0; - - chain = CLASS_IVARS (implementation_template); - if (chain) - { - size = 0; - initlist = build_ivar_list_initializer (chain, &size); - - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - - UOBJC_INSTANCE_VARIABLES_decl = - generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES", - size, initlist); - /* cast! */ - TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_VARIABLES_decl = 0; - - generating_instance_variables = 0; -} - -static tree -build_dispatch_table_initializer (entries, size) - tree entries; - int *size; -{ - tree initlist = NULLT; - - do - { - initlist = tree_cons (NULLT, build_selector (METHOD_SEL_NAME (entries)), - initlist); - - initlist = tree_cons (NULLT, add_objc_string (METHOD_ENCODING (entries), - meth_var_types), - initlist); - - initlist = tree_cons (NULLT, METHOD_DEFINITION (entries), initlist); - - (*size)++; - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* To accomplish method prototyping without generating all kinds of - inane warnings, the definition of the dispatch table entries were - changed from: - - struct objc_method { SEL _cmd; id (*_imp)(); }; - to: - struct objc_method { SEL _cmd; void *_imp; }; */ - -static tree -build_method_template () -{ - tree _SLT_record; - tree decl_specs, field_decl, field_decl_chain; - - _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_UNSIGNED], NULLT); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* not OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), - NULLT); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_cmd")); -#endif /* not OBJC_INT_SELECTORS */ - - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], NULLT); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("method_types")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - /* void *_imp; */ - - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_VOID], NULLT); - field_decl = build1 (INDIRECT_REF, NULLT, get_identifier ("_imp")); - field_decl = grokfield (input_filename, lineno, field_decl, decl_specs, NULLT); - chainon (field_decl_chain, field_decl); - - finish_struct (_SLT_record, field_decl_chain); - - return _SLT_record; -} - - -static tree -generate_dispatch_table (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1); - end_temporary_allocation (); - - initlist = build_tree_list (NULLT, build_int_2 (0, 0)); - initlist = tree_cons (NULLT, build_int_2 (size, 0), initlist); - initlist = tree_cons (NULLT, list, initlist); - - finish_decl (decl, build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)), NULLT); - - return decl; -} - -static void -generate_dispatch_tables () -{ - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_template) - objc_method_template = build_method_template (); - - cast - = build_tree_list - (build_tree_list (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))), - NULLT); - variable_length_type = groktypename (cast); - - chain = CLASS_CLS_METHODS (implementation_context); - if (chain) - { - size = 0; - initlist = build_dispatch_table_initializer (chain, &size); - - method_list_template = build_method_list_template (objc_method_template, - size); - - UOBJC_CLASS_METHODS_decl - = generate_dispatch_table (method_list_template, - ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? "_OBJC_CLASS_METHODS" - : "_OBJC_CATEGORY_CLASS_METHODS"), - size, initlist); - /* cast! */ - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = CLASS_NST_METHODS (implementation_context); - if (chain) - { - size = 0; - initlist = build_dispatch_table_initializer (chain, &size); - - method_list_template = build_method_list_template (objc_method_template, - size); - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - UOBJC_INSTANCE_METHODS_decl = - generate_dispatch_table (method_list_template, - "_OBJC_INSTANCE_METHODS", - size, initlist); - else - /* we have a category */ - UOBJC_INSTANCE_METHODS_decl = - generate_dispatch_table (method_list_template, - "_OBJC_CATEGORY_INSTANCE_METHODS", - size, initlist); - /* cast! */ - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -generate_protocol_list (i_or_p) - tree i_or_p; -{ - static tree cast_type = 0; - tree initlist, decl_specs, sc_spec; - tree refs_decl, expr_decl, lproto, e, plist; - int size = 0; - - if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE - || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - plist = CLASS_PROTOCOL_LIST (i_or_p); - else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - plist = PROTOCOL_LIST (i_or_p); - else - abort (); - - if (!cast_type) - cast_type - = groktypename - (build_tree_list - (build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULLT, NULLT))); - - /* compute size */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) - size++; - - /* build initializer */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), NULLT); - - e = build_int_2 (size, 0); - TREE_TYPE (e) = cast_type; - initlist = tree_cons (NULLT, e, initlist); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree pval = TREE_VALUE (lproto); - - if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (pval)) - { - e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0); - initlist = tree_cons (NULLT, e, initlist); - } - } - - /* static struct objc_protocol *refs[n]; */ - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL)), - sc_spec); - - if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - - expr_decl = build1 (INDIRECT_REF, NULLT, expr_decl); - - refs_decl = start_decl (expr_decl, decl_specs, 1); - end_temporary_allocation (); - - finish_decl (refs_decl, build_nt (CONSTRUCTOR, NULLT, - nreverse (initlist)), NULLT); - - return refs_decl; -} - -static tree -build_category_initializer (cat_name, class_name, - instance_methods, class_methods, protocol_list) - tree cat_name; - tree class_name; - tree instance_methods; - tree class_methods; - tree protocol_list; -{ - tree initlist = NULLT, expr; - - initlist = tree_cons (NULLT, cat_name, initlist); - initlist = tree_cons (NULLT, class_name, initlist); - - if (!instance_methods) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - if (!class_methods) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - - /* protocol_list = */ - if (!protocol_list) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULLT, - build1 (INDIRECT_REF, NULLT, NULLT)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - initlist = tree_cons (NULLT, expr, initlist); - } - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - }; */ - -static tree -build_shared_structure_initializer (isa, super, name, size, status, - dispatch_table, ivar_list, protocol_list) - tree isa; - tree super; - tree name; - tree size; - int status; - tree dispatch_table; - tree ivar_list; - tree protocol_list; -{ - tree initlist = NULLT, expr; - - /* isa = */ - initlist = tree_cons (NULLT, isa, initlist); - - /* super_class = */ - initlist = tree_cons (NULLT, super, initlist); - - /* name = */ - initlist = tree_cons (NULLT, name, initlist); - - /* version = */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - - /* info = */ - initlist = tree_cons (NULLT, build_int_2 (status, 0), initlist); - - /* instance_size = */ - initlist = tree_cons (NULLT, size, initlist); - - /* objc_ivar_list = */ - if (!ivar_list) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, ivar_list, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - - /* objc_method_list = */ - if (!dispatch_table) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, dispatch_table, 0); - initlist = tree_cons (NULLT, expr, initlist); - } - - if (flag_next_runtime) - /* method_cache = */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - /* dtable = */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - - /* subclass_list = */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - - /* sibling_class = */ - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - } - - /* protocol_list = */ - if (! protocol_list) - initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULLT, - build1 (INDIRECT_REF, NULLT, NULLT)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - initlist = tree_cons (NULLT, expr, initlist); - } - - return build_nt (CONSTRUCTOR, NULLT, nreverse (initlist)); -} - -/* static struct objc_category _OBJC_CATEGORY_ = { ... }; */ -static void -generate_category (cat) - tree cat; -{ - tree sc_spec, decl_specs, decl; - tree initlist, cat_name_expr, class_name_expr; - tree protocol_decl, category; - - add_class_reference (CLASS_NAME (cat)); - cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); - - class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); - - category = CLASS_CATEGORY_LIST (implementation_template); - - /* find the category interface from the class it is associated with */ - while (category) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category && CLASS_PROTOCOL_LIST (category)) - { - generate_protocol_references (CLASS_PROTOCOL_LIST (category)); - protocol_decl = generate_protocol_list (category); - } - else - protocol_decl = 0; - - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - decl_specs = tree_cons (NULLT, objc_category_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY", - implementation_context), - decl_specs, 1); - end_temporary_allocation (); - - initlist = build_category_initializer (cat_name_expr, class_name_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl, - protocol_decl); - - TREE_USED (decl) = 1; - finish_decl (decl, initlist, NULLT); -} - -/* static struct objc_class _OBJC_METACLASS_Foo={ ... }; - static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - -static void -generate_shared_structures () -{ - tree sc_spec, decl_specs, decl; - tree name_expr, super_expr, root_expr; - tree my_root_id = NULLT, my_super_id = NULLT; - tree cast_type, initlist, protocol_decl; - - my_super_id = CLASS_SUPER_NAME (implementation_template); - if (my_super_id) - { - add_class_reference (my_super_id); - - /* Compute "my_root_id" - this is required for code generation. - the "isa" for all meta class structures points to the root of - the inheritance hierarchy (e.g. "__Object")... */ - my_root_id = my_super_id; - do - { - tree my_root_int = lookup_interface (my_root_id); - - if (my_root_int && CLASS_SUPER_NAME (my_root_int)) - my_root_id = CLASS_SUPER_NAME (my_root_int); - else - break; - } - while (1); - } - else /* no super class */ - { - my_root_id = CLASS_NAME (implementation_template); - } - - cast_type - = groktypename (build_tree_list (build_tree_list (NULLT, - objc_class_template), - build1 (INDIRECT_REF, NULLT, NULLT))); - - name_expr = add_objc_string (CLASS_NAME (implementation_template), - class_names); - - /* install class `isa' and `super' pointers at runtime */ - if (my_super_id) - { - super_expr = add_objc_string (my_super_id, class_names); - super_expr = build_c_cast (cast_type, super_expr); /* cast! */ - } - else - super_expr = build_int_2 (0, 0); - - root_expr = add_objc_string (my_root_id, class_names); - root_expr = build_c_cast (cast_type, root_expr); /* cast! */ - - if (CLASS_PROTOCOL_LIST (implementation_template)) - { - generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template)); - protocol_decl = generate_protocol_list (implementation_template); - } - else - protocol_decl = 0; - - /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]); - decl_specs = tree_cons (NULLT, objc_class_template, sc_spec); - - decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1); - end_temporary_allocation (); - - initlist - = build_shared_structure_initializer - (root_expr, super_expr, name_expr, - build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) - / BITS_PER_UNIT), - 0), - 2 /*CLS_META*/, - UOBJC_CLASS_METHODS_decl, - UOBJC_CLASS_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULLT); - - /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - - decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1); - end_temporary_allocation (); - - initlist - = build_shared_structure_initializer - (build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0), - super_expr, name_expr, - build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) - / BITS_PER_UNIT), - 0), - 1 /*CLS_FACTORY*/, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_INSTANCE_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULLT); -} - -static tree -synth_id_with_class_suffix (preamble, ctxt) - char *preamble; - tree ctxt; -{ - char *string; - if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE) - { - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3); - sprintf (string, "%s_%s", preamble, - IDENTIFIER_POINTER (CLASS_NAME (ctxt))); - } - else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE) - { - /* we have a category */ - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) - + strlen (class_name) - + strlen (class_super_name) - + 3); - sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name); - } - else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE) - { - char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt)); - string = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3); - sprintf (string, "%s_%s", preamble, protocol_name); - } - return get_identifier (string); -} - -static int -is_objc_type_qualifier (node) - tree node; -{ - return (TREE_CODE (node) == IDENTIFIER_NODE - && (node == ridpointers [(int) RID_CONST] - || node == ridpointers [(int) RID_VOLATILE] - || node == ridpointers [(int) RID_IN] - || node == ridpointers [(int) RID_OUT] - || node == ridpointers [(int) RID_INOUT] - || node == ridpointers [(int) RID_BYCOPY] - || node == ridpointers [(int) RID_ONEWAY])); -} - -/* If type is empty or only type qualifiers are present, add default - type of id (otherwise grokdeclarator will default to int). */ - -static tree -adjust_type_for_id_default (type) - tree type; -{ - tree declspecs, chain; - - if (!type) - return build_tree_list (build_tree_list (NULLT, objc_object_reference), - build1 (INDIRECT_REF, NULLT, NULLT)); - - declspecs = TREE_PURPOSE (type); - - /* Determine if a typespec is present. */ - for (chain = declspecs; - chain; - chain = TREE_CHAIN (chain)) - { - if (!is_objc_type_qualifier (TREE_VALUE (chain))) - return type; - } - - return build_tree_list (tree_cons (NULLT, objc_object_reference, declspecs), - build1 (INDIRECT_REF, NULLT, NULLT)); -} - -/* usage: - keyworddecl: - selector ':' '(' typename ')' identifier - - purpose: - transform an Objective-C keyword argument into - the C equivalent parameter declarator. - - in: key_name, an "identifier_node" (optional). - arg_type, a "tree_list" (optional). - arg_name, an "identifier_node". - - note: it would be really nice to strongly type the preceding - arguments in the function prototype; however, then i - could not use the "accessor" macros defined in "tree.h". - - out: an instance of "keyword_decl". */ - -tree -build_keyword_decl (key_name, arg_type, arg_name) - tree key_name; - tree arg_type; - tree arg_name; -{ - tree keyword_decl; - - /* if no type is specified, default to "id" */ - arg_type = adjust_type_for_id_default (arg_type); - - keyword_decl = make_node (KEYWORD_DECL); - - TREE_TYPE (keyword_decl) = arg_type; - KEYWORD_ARG_NAME (keyword_decl) = arg_name; - KEYWORD_KEY_NAME (keyword_decl) = key_name; - - return keyword_decl; -} - -/* Given a chain of keyword_decl's, synthesize the full keyword selector. */ -static tree -build_keyword_selector (selector) - tree selector; -{ - int len = 0; - tree key_chain, key_name; - char *buf; - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - - if (key_name) - len += IDENTIFIER_LENGTH (key_name) + 1; - else /* just a ':' arg */ - len++; - } - buf = (char *)alloca (len + 1); - bzero (buf, len + 1); - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - - if (key_name) - strcat (buf, IDENTIFIER_POINTER (key_name)); - strcat (buf, ":"); - } - return get_identifier (buf); -} - -/* used for declarations and definitions */ - -tree -build_method_decl (code, ret_type, selector, add_args) - enum tree_code code; - tree ret_type; - tree selector; - tree add_args; -{ - tree method_decl; - - /* if no type is specified, default to "id" */ - ret_type = adjust_type_for_id_default (ret_type); - - method_decl = make_node (code); - TREE_TYPE (method_decl) = ret_type; - - /* If we have a keyword selector, create an identifier_node that - represents the full selector name (`:' included)... */ - if (TREE_CODE (selector) == KEYWORD_DECL) - { - METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector); - METHOD_SEL_ARGS (method_decl) = selector; - METHOD_ADD_ARGS (method_decl) = add_args; - } - else - { - METHOD_SEL_NAME (method_decl) = selector; - METHOD_SEL_ARGS (method_decl) = NULLT; - METHOD_ADD_ARGS (method_decl) = NULLT; - } - - return method_decl; -} - -#define METHOD_DEF 0 -#define METHOD_REF 1 - -/* Used by `build_message_expr' and `comp_method_types'. Return an - argument list for method METH. CONTEXT is either METHOD_DEF or - METHOD_REF, saying whether we are trying to define a method or call - one. SUPERFLAG says this is for a send to super; this makes a - difference for the NeXT calling sequence in which the lookup and - the method call are done together. */ - -static tree -get_arg_type_list (meth, context, superflag) - tree meth; - int context; - int superflag; -{ - tree arglist, akey; - - /* receiver type */ - if (flag_next_runtime && superflag) - arglist = build_tree_list (NULLT, super_type); - else if (context == METHOD_DEF) - arglist = build_tree_list (NULLT, TREE_TYPE (self_decl)); - else - arglist = build_tree_list (NULLT, id_type); - - /* selector type - will eventually change to `int' */ - chainon (arglist, build_tree_list (NULLT, selector_type)); - - /* build a list of argument types */ - for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey)) - { - tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey)); - chainon (arglist, build_tree_list (NULLT, TREE_TYPE (arg_decl))); - } - - if (METHOD_ADD_ARGS (meth) == (tree)1) - /* We have a `, ...' immediately following the selector, - finalize the arglist...simulate get_parm_info (0). */ - ; - else if (METHOD_ADD_ARGS (meth)) - { - /* we have a variable length selector */ - tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth)); - chainon (arglist, add_arg_list); - } - else - /* finalize the arglist...simulate get_parm_info (1) */ - chainon (arglist, build_tree_list (NULLT, void_type_node)); - - return arglist; -} - -static tree -check_duplicates (hsh) - hash hsh; -{ - tree meth = NULLT; - - if (hsh) - { - meth = hsh->key; - - if (hsh->list) - { - /* we have two methods with the same name and different types */ - attr loop; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+'; - - warning ("multiple declarations for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - - warn_with_method ("using", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("also found", type, loop->value); - } - } - return meth; -} - -/* If RECEIVER is a class reference, return the identifier node for the - referenced class. RECEIVER is created by get_class_reference, so we - check the exact form created depending on which runtimes are used. */ - -static tree -receiver_is_class_object (receiver) - tree receiver; -{ - tree chain, exp, arg; - if (flag_next_runtime) - { - /* The receiver is a variable created by build_class_reference_decl. */ - if (TREE_CODE (receiver) == VAR_DECL - && TREE_TYPE (receiver) == objc_class_type) - /* Look up the identifier. */ - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - if (TREE_PURPOSE (chain) == receiver) - return TREE_VALUE (chain); - } - else - { - /* The receiver is a function call that returns an id. Check if - it is a call to objc_getClass, if so, pick up the class name. */ - if ((exp = TREE_OPERAND (receiver, 0)) - && TREE_CODE (exp) == ADDR_EXPR - && (exp = TREE_OPERAND (exp, 0)) - && TREE_CODE (exp) == FUNCTION_DECL - && exp == objc_get_class_decl - /* we have a call to objc_getClass! */ - && (arg = TREE_OPERAND (receiver, 1)) - && TREE_CODE (arg) == TREE_LIST - && (arg = TREE_VALUE (arg))) - { - STRIP_NOPS (arg); - if (TREE_CODE (arg) == ADDR_EXPR - && (arg = TREE_OPERAND (arg, 0)) - && TREE_CODE (arg) == STRING_CST) - /* finally, we have the class name */ - return get_identifier (TREE_STRING_POINTER (arg)); - } - } - return 0; -} - -/* If we are currently building a message expr, this holds - the identifier of the selector of the message. This is - used when printing warnings about argument mismatches. */ - -static tree building_objc_message_expr = 0; - -tree -maybe_building_objc_message_expr () -{ - return building_objc_message_expr; -} - -/* Construct an expression for sending a message. - MESS has the object to send to in TREE_PURPOSE - and the argument list (including selector) in TREE_VALUE. - - (*((*)())_msg)(receiver, selTransTbl[n], ...); - (*((*)())_msgSuper)(receiver, selTransTbl[n], ...); */ - -tree -build_message_expr (mess) - tree mess; -{ - tree receiver = TREE_PURPOSE (mess); - tree selector, self_object; - tree rtype, sel_name; - tree args = TREE_VALUE (mess); - tree method_params = NULLT; - tree method_prototype = NULLT; - tree retval; - int statically_typed = 0, statically_allocated = 0; - tree class_ident = 0; - - /* 1 if this is sending to the superclass. */ - int super; - - if (!doing_objc_thang) - objc_fatal (); - - if (TREE_CODE (receiver) == ERROR_MARK) - return error_mark_node; - - /* determine receiver type */ - rtype = TREE_TYPE (receiver); - super = IS_SUPER (rtype); - - if (! super) - { - if (TREE_STATIC_TEMPLATE (rtype)) - statically_allocated = 1; - else if (TREE_CODE (rtype) == POINTER_TYPE - && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype))) - statically_typed = 1; - else if ((flag_next_runtime - || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype))) - && (class_ident = receiver_is_class_object (receiver))) - ; - else if (! IS_ID (rtype) - /* Allow any type that matches objc_class_type. */ - && ! comptypes (rtype, objc_class_type)) - { - bzero (errbuf, BUFSIZE); - warning ("invalid receiver type `%s'", - gen_declaration (rtype, errbuf)); - } - if (statically_allocated) - receiver = build_unary_op (ADDR_EXPR, receiver, 0); - - /* Don't evaluate the receiver twice. */ - receiver = save_expr (receiver); - self_object = receiver; - } - else - /* If sending to `super', use current self as the object. */ - self_object = self_decl; - - /* Obtain the full selector name. */ - - if (TREE_CODE (args) == IDENTIFIER_NODE) - /* a unary selector */ - sel_name = args; - else if (TREE_CODE (args) == TREE_LIST) - sel_name = build_keyword_selector (args); - - /* Build the parameters list for looking up the method. - These are the object itself and the selector. */ - - selector = build_selector_reference (sel_name); - - /* Build the parameter list to give to the method. */ - - method_params = NULLT; - if (TREE_CODE (args) == TREE_LIST) - { - tree chain = args, prev = NULLT; - - /* We have a keyword selector--check for comma expressions. */ - while (chain) - { - tree element = TREE_VALUE (chain); - - /* We have a comma expression, must collapse... */ - if (TREE_CODE (element) == TREE_LIST) - { - if (prev) - TREE_CHAIN (prev) = element; - else - args = element; - } - prev = chain; - chain = TREE_CHAIN (chain); - } - method_params = args; - } - - /* Determine operation return type. */ - - if (IS_SUPER (rtype)) - { - tree iface; - - if (CLASS_SUPER_NAME (implementation_template)) - { - iface = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - method_prototype = lookup_instance_method_static (iface, sel_name); - else - method_prototype = lookup_class_method_static (iface, sel_name); - - if (iface && !method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)), - IDENTIFIER_POINTER (sel_name)); - } - else - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - } - else if (statically_allocated) - { - tree ctype = TREE_TYPE (rtype); - tree iface = lookup_interface (TYPE_NAME (rtype)); - - if (iface) - method_prototype = lookup_instance_method_static (iface, sel_name); - - /* NEW!!! */ - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (rtype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (statically_typed) - { - tree ctype = TREE_TYPE (rtype); - - /* `self' is now statically_typed...all methods should be visible - within the context of the implementation... */ - if (implementation_context - && CLASS_NAME (implementation_context) == TYPE_NAME (ctype)) - { - method_prototype = lookup_instance_method_static (implementation_template, sel_name); - - /* NEW!!! */ - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (! method_prototype - && implementation_template != implementation_context) - /* the method is not published in the interface...check locally */ - method_prototype - = lookup_method (CLASS_NST_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (TYPE_NAME (ctype)))) - method_prototype = lookup_instance_method_static (iface, sel_name); - - if (! method_prototype) - { - tree protocol_list = TYPE_PROTOCOL_LIST (ctype); - if (protocol_list) - method_prototype - = lookup_method_in_protocol_list (protocol_list, sel_name, 0); - } - } - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (ctype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (class_ident) - { - if (implementation_context - && CLASS_NAME (implementation_context) == class_ident) - { - method_prototype - = lookup_class_method_static (implementation_template, sel_name); - - if (!method_prototype - && implementation_template != implementation_context) - /* the method is not published in the interface...check locally */ - method_prototype - = lookup_method (CLASS_CLS_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (class_ident))) - method_prototype = lookup_class_method_static (iface, sel_name); - } - - if (!method_prototype) - { - warning ("cannot find class (factory) method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - else if (IS_PROTOCOL_QUALIFIED_ID (rtype)) - { - /* An anonymous object that has been qualified with a protocol. */ - - tree protocol_list = TYPE_PROTOCOL_LIST (rtype); - - method_prototype = lookup_method_in_protocol_list (protocol_list, - sel_name, 0); - - if (!method_prototype) - { - hash hsh; - - warning ("method `%s' not implemented by protocol.", - IDENTIFIER_POINTER (sel_name)); - - /* try and find the method signiture in the global pools! */ - - if (!(hsh = hash_lookup (nst_method_hash_list, sel_name))) - hsh = hash_lookup (cls_method_hash_list, sel_name); - - if (!(method_prototype = check_duplicates (hsh))) - warning ("return type defaults to id"); - } - } - else - { - hash hsh; - - /* we think we have an instance...loophole: extern id Object; */ - hsh = hash_lookup (nst_method_hash_list, sel_name); - if (!hsh) - /* for various loopholes...like sending messages to self in a - factory context... */ - hsh = hash_lookup (cls_method_hash_list, sel_name); - - method_prototype = check_duplicates (hsh); - if (!method_prototype) - { - warning ("cannot find method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - - /* Save the selector name for printing error messages. */ - building_objc_message_expr = sel_name; - - retval = build_objc_method_call (super, method_prototype, - receiver, self_object, - selector, method_params); - - building_objc_message_expr = 0; - - return retval; -} - -/* Build a tree expression to send OBJECT the operation SELECTOR, - looking up the method on object LOOKUP_OBJECT (often same as OBJECT), - assuming the method has prototype METHOD_PROTOTYPE. - (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) - Use METHOD_PARAMS as list of args to pass to the method. - If SUPER_FLAG is nonzero, we look up the superclass's method. */ - -static tree -build_objc_method_call (super_flag, method_prototype, lookup_object, object, - selector, method_params) - int super_flag; - tree method_prototype, lookup_object, object, selector, method_params; -{ - tree sender = (super_flag ? umsg_super_decl : umsg_decl); - tree rcv_p = (super_flag - ? build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))) - : id_type); - - if (flag_next_runtime) - { - if (! method_prototype) - { - method_params = tree_cons (NULLT, lookup_object, - tree_cons (NULLT, selector, - method_params)); - assemble_external (sender); - return build_function_call (sender, method_params); - } - else - { - /* This is a real kludge, but it is used only for the Next. - Clobber the data type of SENDER temporarily to accept - all the arguments for this operation, and to return - whatever this operation returns. */ - tree arglist = NULLT; - tree retval; - - /* Save the proper contents of SENDER's data type. */ - tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender)); - tree savret = TREE_TYPE (TREE_TYPE (sender)); - - /* Install this method's argument types. */ - arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist; - - /* Install this method's return type. */ - TREE_TYPE (TREE_TYPE (sender)) - = groktypename (TREE_TYPE (method_prototype)); - - /* Call SENDER with all the parameters. This will do type - checking using the arg types for this method. */ - method_params = tree_cons (NULLT, lookup_object, - tree_cons (NULLT, selector, - method_params)); - assemble_external (sender); - retval = build_function_call (sender, method_params); - - /* Restore SENDER's return/argument types. */ - TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg; - TREE_TYPE (TREE_TYPE (sender)) = savret; - return retval; - } - } - else - { - /* This is the portable way. - First call the lookup function to get a pointer to the method, - then cast the pointer, then call it with the method arguments. */ - tree method; - - /* Avoid trouble since we may evaluate each of these twice. */ - object = save_expr (object); - selector = save_expr (selector); - - lookup_object = build_c_cast (rcv_p, lookup_object); /* cast! */ - - assemble_external (sender); - method - = build_function_call (sender, - tree_cons (NULLT, lookup_object, - tree_cons (NULLT, selector, NULLT))); - - /* If we have a method prototype, construct the data type this - method needs, and cast what we got from SENDER into a pointer - to that type. */ - if (method_prototype) - { - tree arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - tree valtype = groktypename (TREE_TYPE (method_prototype)); - tree fake_function_type = build_function_type (valtype, arglist); - TREE_TYPE (method) = build_pointer_type (fake_function_type); - } - else - TREE_TYPE (method) - = build_pointer_type (build_function_type (ptr_type_node, NULLT)); - - /* Pass the object to the method. */ - assemble_external (method); - return build_function_call (method, - tree_cons (NULLT, object, - tree_cons (NULLT, selector, - method_params))); - } -} - -static void -build_protocol_reference (p) - tree p; -{ - tree decl, ident, ptype; - struct obstack *save_current_obstack = current_obstack; - struct obstack *save_rtl_obstack = rtl_obstack; - - rtl_obstack = current_obstack = &permanent_obstack; - - /* extern struct objc_protocol _OBJC_PROTOCOL_; */ - - ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p); - ptype - = groktypename (build_tree_list (build_tree_list (NULLT, - objc_protocol_template), - NULLT)); - - if (IDENTIFIER_GLOBAL_VALUE (ident)) - decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */ - else - { - decl = build_decl (VAR_DECL, ident, ptype); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - - /* usually called from `rest_of_decl_compilation' */ - make_decl_rtl (decl, 0, 1); - /* our `extended/custom' pushdecl in c-decl.c */ - pushdecl_top_level (decl); - } - current_obstack = save_current_obstack; - rtl_obstack = save_rtl_obstack; - - PROTOCOL_FORWARD_DECL (p) = decl; -} - -tree -build_protocol_expr (protoname) - tree protoname; -{ - tree expr; - tree p; - - if (!doing_objc_thang) - objc_fatal (); - - p = lookup_protocol (protoname); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (protoname)); - return error_mark_node; - } - - if (!PROTOCOL_FORWARD_DECL (p)) - build_protocol_reference (p); - - expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); - - TREE_TYPE (expr) = protocol_type; - - return expr; -} - -tree -build_selector_expr (selnamelist) - tree selnamelist; -{ - tree selname; - - if (!doing_objc_thang) - objc_fatal (); - - /* obtain the full selector name */ - if (TREE_CODE (selnamelist) == IDENTIFIER_NODE) - /* a unary selector */ - selname = selnamelist; - else if (TREE_CODE (selnamelist) == TREE_LIST) - selname = build_keyword_selector (selnamelist); - - return build_selector_reference (selname); -} - -tree -build_encode_expr (type) - tree type; -{ - tree result; - char *string; - - if (!doing_objc_thang) - objc_fatal (); - - encode_type (type, obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - obstack_1grow (&util_obstack, 0); /* null terminate string */ - string = obstack_finish (&util_obstack); - - /* synthesize a string that represents the encoded struct/union */ - result = my_build_string (strlen (string) + 1, string); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -tree -build_ivar_reference (id) - tree id; -{ - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - { - /* Historically, a class method that produced objects (factory - method) would assign `self' to the instance that it - allocated. This would effectively turn the class method into - an instance method. Following this assignment, the instance - variables could be accessed. That practice, while safe, - violates the simple rule that a class method should not refer - to an instance variable. It's better to catch the cases - where this is done unknowingly than to support the above - paradigm. */ - warning ("instance variable `%s' accessed in class method", - IDENTIFIER_POINTER (id)); - TREE_TYPE (self_decl) = instance_type; /* cast */ - } - - return build_component_ref (build_indirect_ref (self_decl, "->"), id); -} - -#define HASH_ALLOC_LIST_SIZE 170 -#define ATTR_ALLOC_LIST_SIZE 170 -#define SIZEHASHTABLE 257 - -/* make positive */ -#define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff) - -static void -hash_init () -{ - nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - - if (!nst_method_hash_list || !cls_method_hash_list) - perror ("unable to allocate space in objc-tree.c"); - else - { - int i; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - nst_method_hash_list[i] = 0; - cls_method_hash_list[i] = 0; - } - } -} - -static void -hash_enter (hashlist, method) - hash *hashlist; - tree method; -{ - static hash hash_alloc_list = 0; - static int hash_alloc_index = 0; - hash obj; - int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE; - - if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE) - { - hash_alloc_index = 0; - hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry) - * HASH_ALLOC_LIST_SIZE); - if (! hash_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &hash_alloc_list[hash_alloc_index++]; - obj->list = 0; - obj->next = hashlist[slot]; - obj->key = method; - - hashlist[slot] = obj; /* append to front */ -} - -static hash -hash_lookup (hashlist, sel_name) - hash *hashlist; - tree sel_name; -{ - hash target; - - target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE]; - - while (target) - { - if (sel_name == METHOD_SEL_NAME (target->key)) - return target; - - target = target->next; - } - return 0; -} - -static void -hash_add_attr (entry, value) - hash entry; - tree value; -{ - static attr attr_alloc_list = 0; - static int attr_alloc_index = 0; - attr obj; - - if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE) - { - attr_alloc_index = 0; - attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute) - * ATTR_ALLOC_LIST_SIZE); - if (! attr_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &attr_alloc_list[attr_alloc_index++]; - obj->next = entry->list; - obj->value = value; - - entry->list = obj; /* append to front */ -} - -static tree -lookup_method (mchain, method) - tree mchain; - tree method; -{ - tree key; - - if (TREE_CODE (method) == IDENTIFIER_NODE) - key = method; - else - key = METHOD_SEL_NAME (method); - - while (mchain) - { - if (METHOD_SEL_NAME (mchain) == key) - return mchain; - mchain = TREE_CHAIN (mchain); - } - return NULLT; -} - -static tree -lookup_instance_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_NST_METHODS (inter); - tree meth = NULLT; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_NST_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* NEW!!! */ - /* Check for instance methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 0)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_NST_METHODS (category); - } - while (category); - } - - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 0)))) - return meth; - } - - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_NST_METHODS (inter); - } - while (inter); - - return meth; -} - -static tree -lookup_class_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_CLS_METHODS (inter); - tree meth = NULLT; - tree root_inter = NULLT; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_CLS_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* NEW!!! */ - /* Check for class methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 1)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_CLS_METHODS (category); - } - while (category); - } - - /* NEW!!! */ - /* Check for class methods in protocols. */ - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 1)))) - return meth; - } - - root_inter = inter; - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_CLS_METHODS (inter); - } - while (inter); - -/* NEW!!! */ - /* Simulate wrap around. */ - return lookup_instance_method_static (root_inter, ident); -} - -tree -add_class_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method))) - { - /* put method on list in reverse order */ - TREE_CHAIN (method) = CLASS_CLS_METHODS (class); - CLASS_CLS_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* check types, if different complain */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* install on a global chain */ - hash_enter (cls_method_hash_list, method); - } - else - { - /* check types, if different add to a list */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -tree -add_instance_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_NST_METHODS (class), method))) - { - /* put method on list in reverse order */ - TREE_CHAIN (method) = CLASS_NST_METHODS (class); - CLASS_NST_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* check types, if different complain */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* install on a global chain */ - hash_enter (nst_method_hash_list, method); - } - else - { - /* check types, if different add to a list */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -static tree -add_class (class) - tree class; -{ - /* put interfaces on list in reverse order */ - TREE_CHAIN (class) = interface_chain; - interface_chain = class; - return interface_chain; -} - -static void -add_category (class, category) - tree class; - tree category; -{ - /* put categories on list in reverse order */ - - tree cat = CLASS_CATEGORY_LIST (class); - while (cat) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - warning ("duplicate interface declaration for category `%s(%s)'", - IDENTIFIER_POINTER (CLASS_NAME (class)), - IDENTIFIER_POINTER (CLASS_SUPER_NAME (category))); - cat = CLASS_CATEGORY_LIST (cat); - } - - CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class); - CLASS_CATEGORY_LIST (class) = category; -} - -/* Called after parsing each instance variable declaration. Necessary to - preserve typedefs and implement public/private... - - PUBLIC is 1 for public, 0 for protected, and 2 for private. */ - -tree -add_instance_variable (class, public, declarator, declspecs, width) - tree class; - int public; - tree declarator; - tree declspecs; - tree width; -{ - tree field_decl, raw_decl; - - raw_decl = build_tree_list (declspecs /*purpose*/, declarator/*value*/); - - if (CLASS_RAW_IVARS (class)) - chainon (CLASS_RAW_IVARS (class), raw_decl); - else - CLASS_RAW_IVARS (class) = raw_decl; - - field_decl = grokfield (input_filename, lineno, - declarator, declspecs, width); - - /* overload the public attribute, it is not used for FIELD_DECL's */ - switch (public) - { - case 0: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 1; - break; - - case 1: - TREE_PUBLIC (field_decl) = 1; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 0; - break; - - case 2: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 1; - TREE_PROTECTED (field_decl) = 0; - break; - - } - - if (CLASS_IVARS (class)) - chainon (CLASS_IVARS (class), field_decl); - else - CLASS_IVARS (class) = field_decl; - - return class; -} - -tree -is_ivar (decl_chain, ident) - tree decl_chain; - tree ident; -{ - for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain)) - if (DECL_NAME (decl_chain) == ident) - return decl_chain; - return NULL_TREE; -} - -/* True if the ivar is private and we are not in its implementation. */ - -int -is_private (decl) - tree decl; -{ - if (TREE_PRIVATE (decl) - && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl))) - { - error ("instance variable `%s' is declared private", - IDENTIFIER_POINTER (DECL_NAME (decl))); - return 1; - } - else - return 0; -} - -/* we have an instance variable reference, check to see if it is public...*/ - -int -is_public (expr, identifier) - tree expr; - tree identifier; -{ - tree basetype = TREE_TYPE (expr); - enum tree_code code = TREE_CODE (basetype); - tree decl; - - if (code == RECORD_TYPE) - { - if (TREE_STATIC_TEMPLATE (basetype)) - { - if (!lookup_interface (TYPE_NAME (basetype))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (TYPE_NAME (basetype))); - return 0; - } - - if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier))) - { - if (TREE_PUBLIC (decl)) - return 1; - - /* important difference between the Stepstone translator: - all instance variables should be public within the context - of the implementation. */ - if (implementation_context - && (((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - || (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE)) - && (CLASS_NAME (implementation_context) - == TYPE_NAME (basetype)))) - return ! is_private (decl); - - error ("instance variable `%s' is declared %s", - IDENTIFIER_POINTER (identifier), - TREE_PRIVATE (decl) ? "private" : "protected"); - return 0; - } - } - else if (implementation_context && (basetype == objc_object_reference)) - { - TREE_TYPE (expr) = uprivate_record; - warning ("static access to object of type `id'"); - } - } - return 1; -} - -/* implement @defs () within struct bodies. */ - -tree -get_class_ivars (interface) - tree interface; -{ - if (!doing_objc_thang) - objc_fatal (); - - return build_ivar_chain (interface, 1); -} - -/* make sure all entries in "chain" are also in "list" */ - -static int -check_methods (chain, list, mtype) - tree chain; - tree list; - int mtype; -{ - int first = 1; - - while (chain) - { - if (!lookup_method (list, chain)) - { - if (first) - { - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - chain = TREE_CHAIN (chain); - } - return first; -} - -static int -conforms_to_protocol (class, protocol) -tree class; -tree protocol; -{ - while (protocol) - { - tree p = CLASS_PROTOCOL_LIST (class); - while (p && TREE_VALUE (p) != TREE_VALUE (protocol)) - p = TREE_CHAIN (p); - if (!p) - { - tree super = (CLASS_SUPER_NAME (class) - ? lookup_interface (CLASS_SUPER_NAME (class)) - : NULL_TREE); - int tmp = super ? conforms_to_protocol (super, protocol) : 0; - if (!tmp) - return 0; - } - protocol = TREE_CHAIN (protocol); - } - return 1; -} - -/* Make sure all methods in CHAIN are accessible as MTYPE methods in - CONTEXT. This is one of two mechanisms to check protocol integrity -*/ - -static int -check_methods_accessible (chain, context, mtype) - tree chain; - tree context; /* implementation_context */ - int mtype; -{ - int first = 1; - tree list; - - while (chain) - { - while (context) - { - if (mtype == '+') - list = CLASS_CLS_METHODS (context); - else - list = CLASS_NST_METHODS (context); - - if (lookup_method (list, chain)) - break; - - else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CLASS_INTERFACE_TYPE) - context = (CLASS_SUPER_NAME (context) - ? lookup_interface (CLASS_SUPER_NAME (context)) - : NULL_TREE); - - else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE) - context = (CLASS_NAME (context) - ? lookup_interface (CLASS_NAME (context)) - : NULL_TREE); - else - abort (); - } - - if (context == NULL_TREE) - { - if (first) - { - if (TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER - (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER - (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - - chain = TREE_CHAIN (chain); /* next method... */ - } - return first; -} - -static void -check_protocols (proto_list, type, name) - tree proto_list; - char *type; - char *name; -{ - for ( ; proto_list; proto_list = TREE_CHAIN (proto_list)) - { - tree p = TREE_VALUE (proto_list); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - int f1, f2; - - /* Ensure that all protocols have bodies! */ - if (flag_warn_protocol) { - f1 = check_methods (PROTOCOL_CLS_METHODS (p), - CLASS_CLS_METHODS (implementation_context), - '+'); - f2 = check_methods (PROTOCOL_NST_METHODS (p), - CLASS_NST_METHODS (implementation_context), - '-'); - } else { - f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p), - implementation_context, - '+'); - f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p), - implementation_context, - '-'); - } - - if (!f1 || !f2) - warning ("%s `%s' does not fully implement the `%s' protocol", - type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - - } - else - ; /* an identifier...if we could not find a protocol. */ - - /* Check protocols recursively. */ - if (PROTOCOL_LIST (p)) - { - tree super_class - = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p))) - check_protocols (PROTOCOL_LIST (p), type, name); - } - } -} - -/* Make sure that the class CLASS_NAME is defined - CODE says which kind of thing CLASS_NAME ought to be. - It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. - - If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange - whose matching pop is in continue_class. */ - -tree -start_class (code, class_name, super_name, protocol_list) - enum tree_code code; - tree class_name; - tree super_name; - tree protocol_list; -{ - tree class, decl; - - if (code == CLASS_INTERFACE_TYPE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - if (!doing_objc_thang) - objc_fatal (); - - class = make_node (code); - TYPE_BINFO (class) = make_tree_vec (5); - - CLASS_NAME (class) = class_name; - CLASS_SUPER_NAME (class) = super_name; - CLASS_CLS_METHODS (class) = NULL_TREE; - - if (! is_class_name (class_name) && (decl = lookup_name (class_name))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (class_name)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (code == CLASS_IMPLEMENTATION_TYPE) - { - { - static tree implemented_classes = 0; - tree chain = implemented_classes; - for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain)) - if (TREE_VALUE (chain) == class_name) - { - error ("reimplementation of class `%s'", - IDENTIFIER_POINTER (class_name)); - return error_mark_node; - } - implemented_classes = perm_tree_cons (NULLT, class_name, - implemented_classes); - } - - /* pre-build the following entities - for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - - if (!objc_super_template) - objc_super_template = build_super_template (); - - method_slot = 0; /* reset for multiple classes per file */ - - implementation_context = class; - - /* lookup the interface for this implementation. */ - - if (!(implementation_template = lookup_interface (class_name))) - { - warning ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - add_class (implementation_template = implementation_context); - } - - /* if a super class has been specified in the implementation, - insure it conforms to the one specified in the interface */ - - if (super_name - && (super_name != CLASS_SUPER_NAME (implementation_template))) - { - tree previous_name = CLASS_SUPER_NAME (implementation_template); - char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : ""; - error ("conflicting super class name `%s'", - IDENTIFIER_POINTER (super_name)); - error ("previous declaration of `%s'", name); - } - else if (! super_name) - { - CLASS_SUPER_NAME (implementation_context) - = CLASS_SUPER_NAME (implementation_template); - } - } - else if (code == CLASS_INTERFACE_TYPE) - { - if (lookup_interface (class_name)) - warning ("duplicate interface declaration for class `%s'", - IDENTIFIER_POINTER (class_name)); - else - add_class (class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - else if (code == CATEGORY_INTERFACE_TYPE) - { - tree class_category_is_assoc_with; - - /* for a category, class_name is really the name of the class that - the following set of methods will be associated with...we must - find the interface so that can derive the objects template */ - - if (!(class_category_is_assoc_with = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (1); - } - else - add_category (class_category_is_assoc_with, class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - else if (code == CATEGORY_IMPLEMENTATION_TYPE) - { - /* pre-build the following entities - for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - - if (!objc_super_template) - objc_super_template = build_super_template (); - - method_slot = 0; /* reset for multiple classes per file */ - - implementation_context = class; - - /* for a category, class_name is really the name of the class that - the following set of methods will be associated with...we must - find the interface so that can derive the objects template */ - - if (!(implementation_template = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (1); - } - } - return class; -} - -tree -continue_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - struct imp_entry *imp_entry; - tree ivar_context; - - /* check consistency of the instance variables. */ - - if (CLASS_IVARS (class)) - check_ivars (implementation_template, class); - - /* code generation */ - - ivar_context = build_private_template (implementation_template); - - if (!objc_class_template) - build_class_template (); - - if (!(imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry)))) - perror ("unable to allocate in objc-tree.c"); - - imp_entry->next = imp_list; - imp_entry->imp_context = class; - imp_entry->imp_template = implementation_template; - - synth_forward_declarations (); - imp_entry->class_decl = UOBJC_CLASS_decl; - imp_entry->meta_decl = UOBJC_METACLASS_decl; - - /* append to front and increment count */ - imp_list = imp_entry; - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - imp_count++; - else - cat_count++; - - return ivar_context; - } - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class)); - - if (!TYPE_FIELDS (record)) - { - finish_struct (record, build_ivar_chain (class, 0)); - CLASS_STATIC_TEMPLATE (class) = record; - - /* mark this record as a class template - for static typing */ - TREE_STATIC_TEMPLATE (record) = 1; - } - return NULLT; - } - else - return error_mark_node; -} - -/* This is called once we see the "@end" in an interface/implementation. */ - -void -finish_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - { - /* all code generation is done in finish_objc */ - - if (implementation_template != implementation_context) - { - /* ensure that all method listed in the interface contain bodies! */ - check_methods (CLASS_CLS_METHODS (implementation_template), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (implementation_template), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (implementation_template)) - check_protocols (CLASS_PROTOCOL_LIST (implementation_template), - "class", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - } - } - else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - tree category = CLASS_CATEGORY_LIST (implementation_template); - - /* find the category interface from the class it is associated with */ - while (category) - { - if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category) - { - /* ensure that all method listed in the interface contain bodies! */ - check_methods (CLASS_CLS_METHODS (category), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (category), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (category)) - check_protocols (CLASS_PROTOCOL_LIST (category), - "category", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - } - } - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree decl_specs; - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class)); - char *string = (char *) alloca (strlen (class_name) + 3); - - /* extern struct objc_object *_; */ - - sprintf (string, "_%s", class_name); - - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULLT, objc_object_reference, decl_specs); - define_decl (build1 (INDIRECT_REF, NULLT, get_identifier (string)), - decl_specs); - } -} - -static tree -add_protocol (protocol) - tree protocol; -{ - /* put protocol on list in reverse order */ - TREE_CHAIN (protocol) = protocol_chain; - protocol_chain = protocol; - return protocol_chain; -} - -static tree -lookup_protocol (ident) - tree ident; -{ - tree chain; - - for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == PROTOCOL_NAME (chain)) - return chain; - } - return NULLT; -} - -tree -start_protocol (code, name, list) - enum tree_code code; - tree name; - tree list; -{ - tree protocol; - - if (!doing_objc_thang) - objc_fatal (); - - /* This is as good a place as any. Need to invoke push_tag_toplevel. */ - if (!objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - protocol = make_node (code); - TYPE_BINFO (protocol) = make_tree_vec (2); - - PROTOCOL_NAME (protocol) = name; - PROTOCOL_LIST (protocol) = list; - - lookup_and_install_protocols (list); - - if (lookup_protocol (name)) - warning ("duplicate declaration for protocol `%s'", - IDENTIFIER_POINTER (name)); - else - add_protocol (protocol); - - PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; - - return protocol; -} - -void -finish_protocol (protocol) - tree protocol; -{ -} - - -/* "Encode" a data type into a string, which grows in util_obstack. - ??? What is the FORMAT? Someone please document this! */ - -static void -encode_type_qualifiers (declspecs) - tree declspecs; -{ - tree spec; - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - if (ridpointers[RID_CONST] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'r'); - else if (ridpointers[RID_IN] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'n'); - else if (ridpointers[RID_INOUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'N'); - else if (ridpointers[RID_OUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'o'); - else if (ridpointers[RID_BYCOPY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'O'); - else if (ridpointers[RID_ONEWAY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'V'); - } -} - -/* Encode a pointer type. */ - -static void -encode_pointer (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree pointer_to = TREE_TYPE (type); - - if (TREE_CODE (pointer_to) == RECORD_TYPE) - { - if (TYPE_NAME (pointer_to) - && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to)); - - if (strcmp (name, TAG_OBJECT) == 0) /* '@' */ - { - obstack_1grow (&util_obstack, '@'); - return; - } - else if (TREE_STATIC_TEMPLATE (pointer_to)) - { - if (generating_instance_variables) - { - obstack_1grow (&util_obstack, '@'); - obstack_1grow (&util_obstack, '"'); - obstack_grow (&util_obstack, name, strlen (name)); - obstack_1grow (&util_obstack, '"'); - return; - } - else - { - obstack_1grow (&util_obstack, '@'); - return; - } - } - else if (strcmp (name, TAG_CLASS) == 0) /* '#' */ - { - obstack_1grow (&util_obstack, '#'); - return; - } -#ifndef OBJC_INT_SELECTORS - else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */ - { - obstack_1grow (&util_obstack, ':'); - return; - } -#endif /* OBJC_INT_SELECTORS */ - } - } - else if (TREE_CODE (pointer_to) == INTEGER_TYPE - && TYPE_MODE (pointer_to) == QImode) - { - obstack_1grow (&util_obstack, '*'); - return; - } - - /* we have a type that does not get special treatment... */ - - /* NeXT extension */ - obstack_1grow (&util_obstack, '^'); - encode_type (pointer_to, curtype, format); -} - -static void -encode_array (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree an_int_cst = TYPE_SIZE (type); - tree array_of = TREE_TYPE (type); - char buffer[40]; - - /* An incomplete array is treated like a pointer. */ - if (an_int_cst == NULL) - { - /* split for obvious reasons. North-Keys 30 Mar 1991 */ - encode_pointer (type, curtype, format); - return; - } - - sprintf (buffer, "[%d", - (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - obstack_grow (&util_obstack, buffer, strlen (buffer)); - encode_type (array_of, curtype, format); - obstack_1grow (&util_obstack, ']'); - return; -} - -static void -encode_aggregate (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - switch (code) - { - case RECORD_TYPE: - { - if (obstack_object_size (&util_obstack) > 0 - && *(obstack_next_free (&util_obstack) - 1) == '^') - { - tree name = TYPE_NAME (type); - - /* we have a reference - this is a NeXT extension */ - - if (obstack_object_size (&util_obstack) - curtype == 1 - && format == OBJC_ENCODE_INLINE_DEFS) - { - /* output format of struct for first level only! */ - - tree fields = TYPE_FIELDS (type); - - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, '{'); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, '='); - } - else - obstack_grow (&util_obstack, "{?=", 3); - - for ( ; fields; fields = TREE_CHAIN (fields)) - encode_field_decl (fields, curtype, format); - obstack_1grow (&util_obstack, '}'); - } - else if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, '{'); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, '}'); - } - else /* we have an untagged structure or a typedef */ - obstack_grow (&util_obstack, "{?}", 3); - } - else - { - tree name = TYPE_NAME (type); - tree fields = TYPE_FIELDS (type); - - if (format == OBJC_ENCODE_INLINE_DEFS - || generating_instance_variables) - { - obstack_1grow (&util_obstack, '{'); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else - obstack_1grow (&util_obstack, '?'); - - obstack_1grow (&util_obstack, '='); - - for (; fields; fields = TREE_CHAIN (fields)) - { - if (generating_instance_variables) - { - tree fname = DECL_NAME (fields); - - obstack_1grow (&util_obstack, '"'); - if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) - { - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (fname), - strlen (IDENTIFIER_POINTER (fname))); - } - obstack_1grow (&util_obstack, '"'); - } - encode_field_decl (fields, curtype, format); - } - obstack_1grow (&util_obstack, '}'); - } - else - { - obstack_1grow (&util_obstack, '{'); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else /* we have an untagged structure or a typedef */ - obstack_1grow (&util_obstack, '?'); - obstack_1grow (&util_obstack, '}'); - } - } - break; - } - case UNION_TYPE: - { - if (*obstack_next_free (&util_obstack) == '^' - || format != OBJC_ENCODE_INLINE_DEFS) - { - /* we have a reference - this is a NeXT extension-- - or we don't want the details. */ - if (TYPE_NAME (type) - && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, '('); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (TYPE_NAME (type)), - strlen (IDENTIFIER_POINTER (TYPE_NAME (type)))); - obstack_1grow (&util_obstack, ')'); - } - else /* we have an untagged structure or a typedef */ - obstack_grow (&util_obstack, "(?)", 3); - } - else - { - tree fields = TYPE_FIELDS (type); - obstack_1grow (&util_obstack, '('); - for ( ; fields; fields = TREE_CHAIN (fields)) - encode_field_decl (fields, curtype, format); - obstack_1grow (&util_obstack, ')'); - } - break; - } - - case ENUMERAL_TYPE: - obstack_1grow (&util_obstack, 'i'); - break; - } -} - -/* Support bitfields, the current version of Objective-C does not support - them. the string will consist of one or more "b:n"'s where n is an - integer describing the width of the bitfield. Currently, classes in - the kit implement a method "-(char *)describeBitfieldStruct:" that - simulates this...if they do not implement this method, the archiver - assumes the bitfield is 16 bits wide (padded if necessary) and packed - according to the GNU compiler. After looking at the "kit", it appears - that all classes currently rely on this default behavior, rather than - hand generating this string (which is tedious). */ - -static void -encode_bitfield (width, format) - int width; - int format; -{ - char buffer[40]; - sprintf (buffer, "b%d", width); - obstack_grow (&util_obstack, buffer, strlen (buffer)); -} - -/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */ - -static void -encode_type (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - if (code == INTEGER_TYPE) - { - if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0 - && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0) - { - /* unsigned integer types */ - - if (TYPE_MODE (type) == QImode) /* 'C' */ - obstack_1grow (&util_obstack, 'C'); - else if (TYPE_MODE (type) == HImode) /* 'S' */ - obstack_1grow (&util_obstack, 'S'); - else if (TYPE_MODE (type) == SImode) - { - if (type == long_unsigned_type_node) - obstack_1grow (&util_obstack, 'L'); /* 'L' */ - else - obstack_1grow (&util_obstack, 'I'); /* 'I' */ - } - else if (TYPE_MODE (type) == DImode) /* 'Q' */ - obstack_1grow (&util_obstack, 'Q'); - } - else /* signed integer types */ - { - if (TYPE_MODE (type) == QImode) /* 'c' */ - obstack_1grow (&util_obstack, 'c'); - else if (TYPE_MODE (type) == HImode) /* 's' */ - obstack_1grow (&util_obstack, 's'); - else if (TYPE_MODE (type) == SImode) /* 'i' */ - { - if (type == long_integer_type_node) - obstack_1grow (&util_obstack, 'l'); /* 'l' */ - else - obstack_1grow (&util_obstack, 'i'); /* 'i' */ - } - else if (TYPE_MODE (type) == DImode) /* 'q' */ - obstack_1grow (&util_obstack, 'q'); - } - } - else if (code == REAL_TYPE) - { - /* floating point types */ - - if (TYPE_MODE (type) == SFmode) /* 'f' */ - obstack_1grow (&util_obstack, 'f'); - else if (TYPE_MODE (type) == DFmode - || TYPE_MODE (type) == TFmode) /* 'd' */ - obstack_1grow (&util_obstack, 'd'); - } - - else if (code == VOID_TYPE) /* 'v' */ - obstack_1grow (&util_obstack, 'v'); - - else if (code == ARRAY_TYPE) - encode_array (type, curtype, format); - - else if (code == POINTER_TYPE) - encode_pointer (type, curtype, format); - - else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE) - encode_aggregate (type, curtype, format); - - else if (code == FUNCTION_TYPE) /* '?' */ - obstack_1grow (&util_obstack, '?'); -} - -static void -encode_field_decl (field_decl, curtype, format) - tree field_decl; - int curtype; - int format; -{ - tree type; - - /* If this field is obviously a bitfield, or is a bitfield that has been - clobbered to look like a ordinary integer mode, go ahead and generate - the bitfield typing information. */ - type = TREE_TYPE (field_decl); - if (DECL_BIT_FIELD (field_decl)) - encode_bitfield (DECL_FIELD_SIZE (field_decl), format); - else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && DECL_FIELD_SIZE (field_decl) - && TYPE_MODE (type) > DECL_MODE (field_decl)) - encode_bitfield (DECL_FIELD_SIZE (field_decl), format); - else - encode_type (TREE_TYPE (field_decl), curtype, format); -} - -static tree -expr_last (complex_expr) - tree complex_expr; -{ - tree next; - - if (complex_expr) - while ((next = TREE_OPERAND (complex_expr, 0))) - complex_expr = next; - return complex_expr; -} - -/* The selector of the current method, - or NULL if we aren't compiling a method. */ - -tree -maybe_objc_method_name (decl) - tree decl; -{ - if (method_context) - return METHOD_SEL_NAME (method_context); - else - return 0; -} - -/* Transform a method definition into a function definition as follows: - - synthesize the first two arguments, "self" and "_cmd". */ - -void -start_method_def (method) - tree method; -{ - tree decl_specs; - - /* Required to implement _msgSuper. */ - method_context = method; - UOBJC_SUPER_decl = NULLT; - - pushlevel (0); /* Must be called BEFORE start_function. */ - - /* Generate prototype declarations for arguments..."new-style". */ - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - decl_specs = build_tree_list (NULLT, uprivate_record); - else - /* really a `struct objc_class *'...however we allow people to - assign to self...which changes its type midstream. */ - decl_specs = build_tree_list (NULLT, objc_object_reference); - - push_parm_decl (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULLT, self_id))); - -#ifdef OBJC_INT_SELECTORS - decl_specs = build_tree_list (NULLT, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULLT, ridpointers[(int) RID_INT], decl_specs); - push_parm_decl (build_tree_list (decl_specs, ucmd_id)); -#else /* not OBJC_INT_SELECTORS */ - decl_specs = build_tree_list (NULLT, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - push_parm_decl (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULLT, ucmd_id))); -#endif /* not OBJC_INT_SELECTORS */ - - /* generate argument declarations if a keyword_decl */ - if (METHOD_SEL_ARGS (method)) - { - tree arglist = METHOD_SEL_ARGS (method); - do - { - tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist)); - tree arg_decl = TREE_VALUE (TREE_TYPE (arglist)); - - if (arg_decl) - { - tree last_expr = expr_last (arg_decl); - - /* unite the abstract decl with its name */ - TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist); - push_parm_decl (build_tree_list (arg_spec, arg_decl)); - /* unhook...restore the abstract declarator */ - TREE_OPERAND (last_expr, 0) = NULLT; - } - else - push_parm_decl (build_tree_list (arg_spec, - KEYWORD_ARG_NAME (arglist))); - - arglist = TREE_CHAIN (arglist); - } - while (arglist); - } - - if (METHOD_ADD_ARGS (method) > (tree)1) - { - /* we have a variable length selector - in "prototype" format */ - tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - while (akey) - { - /* This must be done prior to calling pushdecl. pushdecl is - going to change our chain on us. */ - tree nextkey = TREE_CHAIN (akey); - pushdecl (akey); - akey = nextkey; - } - } -} - -static void -warn_with_method (message, mtype, method) - char *message; - char mtype; - tree method; -{ - if (count_error (1) == 0) - return; - - report_error_function (DECL_SOURCE_FILE (method)); - - fprintf (stderr, "%s:%d: warning: ", - DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%c%s'\n", - message, mtype, gen_method_decl (method, errbuf)); -} - -/* return 1 if `method' is consistent with `proto' */ - -static int -comp_method_with_proto (method, proto) - tree method, proto; -{ - static tree function_type = 0; - - /* create a function_type node once */ - if (!function_type) - { - struct obstack *ambient_obstack = current_obstack; - - current_obstack = &permanent_obstack; - function_type = make_node (FUNCTION_TYPE); - current_obstack = ambient_obstack; - } - - /* Install argument types - normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0); - - /* install return type */ - TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto)); - - return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type); -} - -/* return 1 if `proto1' is consistent with `proto2' */ - -static int -comp_proto_with_proto (proto1, proto2) - tree proto1, proto2; -{ - static tree function_type1 = 0, function_type2 = 0; - - /* create a couple function_type node's once */ - if (!function_type1) - { - struct obstack *ambient_obstack = current_obstack; - - current_obstack = &permanent_obstack; - function_type1 = make_node (FUNCTION_TYPE); - function_type2 = make_node (FUNCTION_TYPE); - current_obstack = ambient_obstack; - } - - /* Install argument types - normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0); - TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0); - - /* install return type */ - TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1)); - TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2)); - - return comptypes (function_type1, function_type2); -} - -/* - generate an identifier for the function. the format is "_n_cls", - where 1 <= n <= nMethods, and cls is the name the implementation we - are processing. - - install the return type from the method declaration. - - if we have a prototype, check for type consistency. */ - -static void -really_start_method (method, parmlist) - tree method, parmlist; -{ - tree sc_spec, ret_spec, ret_decl, decl_specs; - tree method_decl, method_id; - char *buf, *sel_name, *class_name, *cat_name; - - /* synth the storage class & assemble the return type */ - sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT); - ret_spec = TREE_PURPOSE (TREE_TYPE (method)); - decl_specs = chainon (sc_spec, ret_spec); - - sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method)); - class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - cat_name = ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? NULL - : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - method_slot++; - /* Make sure this is big enough for any plausible method label. */ - buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name) - + (cat_name ? strlen (cat_name) : 0)); - - OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL, - class_name, cat_name, sel_name, method_slot); - - method_id = get_identifier (buf); - - method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULLT); - - /* check the declarator portion of the return type for the method */ - if ((ret_decl = TREE_VALUE (TREE_TYPE (method)))) - { - /* unite the complex decl (specified in the abstract decl) with the - function decl just synthesized..(int *), (int (*)()), (int (*)[]). */ - tree save_expr = expr_last (ret_decl); - - TREE_OPERAND (save_expr, 0) = method_decl; - method_decl = ret_decl; - /* fool the parser into thinking it is starting a function */ - start_function (decl_specs, method_decl, 0); - /* unhook...this has the effect of restoring the abstract declarator */ - TREE_OPERAND (save_expr, 0) = NULLT; - } - else - { - TREE_VALUE (TREE_TYPE (method)) = method_decl; - /* fool the parser into thinking it is starting a function */ - start_function (decl_specs, method_decl, 0); - /* unhook...this has the effect of restoring the abstract declarator */ - TREE_VALUE (TREE_TYPE (method)) = NULLT; - } - - METHOD_DEFINITION (method) = current_function_decl; - - /* Check consistency...start_function, pushdecl, duplicate_decls. */ - - if (implementation_template != implementation_context) - { - tree proto; - - if (TREE_CODE (method) == INSTANCE_METHOD_DECL) - proto = lookup_instance_method_static (implementation_template, - METHOD_SEL_NAME (method)); - else - proto = lookup_class_method_static (implementation_template, - METHOD_SEL_NAME (method)); - - if (proto && ! comp_method_with_proto (method, proto)) - { - char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+'); - - warn_with_method ("conflicting types for", type, method); - warn_with_method ("previous declaration of", type, proto); - } - } -} - -/* The following routine is always called...this "architecture" is to - accommodate "old-style" variable length selectors. - - - a:a b:b // prototype ; id c; id d; // old-style. */ - -void -continue_method_def () -{ - tree parmlist; - - if (METHOD_ADD_ARGS (method_context) == (tree)1) - /* We have a `, ...' immediately following the selector. */ - parmlist = get_parm_info (0); - else - parmlist = get_parm_info (1); /* place a `void_at_end' */ - - /* Set self_decl from the first argument...this global is used by - build_ivar_reference calling build_indirect_ref. */ - self_decl = TREE_PURPOSE (parmlist); - - poplevel (0, 0, 0); /* must be called BEFORE start_function. */ - - really_start_method (method_context, parmlist); - - store_parm_decls (); /* must be called AFTER start_function. */ -} - -/* Called by the parser, from the `pushlevel' production. */ - -void -add_objc_decls () -{ - if (!UOBJC_SUPER_decl) - { - UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER), - build_tree_list (NULLT, - objc_super_template), - 0); - - finish_decl (UOBJC_SUPER_decl, NULLT, NULLT); - - /* this prevents `unused variable' warnings when compiling with -Wall. */ - DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl) = 1; - } -} - -/* _n_Method (id self, SEL sel, ...) - { - struct objc_super _S; - _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...); - } */ - -tree -get_super_receiver () -{ - if (method_context) - { - tree super_expr, super_expr_list; - - /* set receiver to self */ - super_expr = build_component_ref (UOBJC_SUPER_decl, self_id); - super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl); - super_expr_list = build_tree_list (NULLT, super_expr); - - /* set class to begin searching */ - super_expr = build_component_ref (UOBJC_SUPER_decl, - get_identifier ("class")); - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* [_cls, __cls]Super are "pre-built" in - synth_forward_declarations. */ - - super_expr = build_modify_expr (super_expr, NOP_EXPR, - ((TREE_CODE (method_context) - == INSTANCE_METHOD_DECL) - ? ucls_super_ref - : uucls_super_ref)); - } - else /* we have a category... */ - { - tree super_name = CLASS_SUPER_NAME (implementation_template); - tree super_class; - - if (!super_name) /* Barf if super used in a category of Object. */ - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - if (flag_next_runtime) - { - super_class = get_class_reference (super_name); - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - super_class - = build_component_ref (build_indirect_ref (super_class, "->"), - get_identifier ("isa")); - } - else - { - add_class_reference (super_name); - super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL - ? objc_get_class_decl : objc_get_meta_class_decl); - assemble_external (super_class); - super_class - = build_function_call - (super_class, - build_tree_list (NULLT, - my_build_string (IDENTIFIER_LENGTH (super_name) + 1, - IDENTIFIER_POINTER (super_name)))); - } - - /* cast! */ - TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref); - super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class); - } - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0); - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - return build_compound_expr (super_expr_list); - } - else - { - error ("[super ...] must appear in a method context"); - return error_mark_node; - } -} - -static tree -encode_method_def (func_decl) - tree func_decl; -{ - tree parms; - int stack_size; - int max_parm_end = 0; - char buffer[40]; - tree result; - - /* return type */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - /* stack size */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (parm_end > max_parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buffer, "%d", stack_size); - obstack_grow (&util_obstack, buffer, strlen (buffer)); - - /* argument types */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - /* type */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* compute offset */ - sprintf (buffer, "%d", forwarding_offset (parms)); - obstack_grow (&util_obstack, buffer, strlen (buffer)); - } - - obstack_1grow (&util_obstack, 0); /* null terminate string */ - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -void -finish_method_def () -{ - METHOD_ENCODING (method_context) = encode_method_def (current_function_decl); - - finish_function (0); - - /* this must be done AFTER finish_function, since the optimizer may - find "may be used before set" errors. */ - method_context = NULLT; /* required to implement _msgSuper. */ -} - -int -lang_report_error_function (decl) - tree decl; -{ - if (method_context) - { - fprintf (stderr, "In method `%s'\n", - IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context))); - return 1; - } - else - return 0; -} - -static int -is_complex_decl (type) - tree type; -{ - return (TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == FUNCTION_TYPE - || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type))); -} - - -/* Code to convert a decl node into text for a declaration in C. */ - -static char tmpbuf[256]; - -static void -adorn_decl (decl, str) - tree decl; - char *str; -{ - enum tree_code code = TREE_CODE (decl); - - if (code == ARRAY_REF) - { - tree an_int_cst = TREE_OPERAND (decl, 1); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST) - sprintf (str + strlen (str), "[%d]", TREE_INT_CST_LOW (an_int_cst)); - else - strcat (str, "[]"); - } - else if (code == ARRAY_TYPE) - { - tree an_int_cst = TYPE_SIZE (decl); - tree array_of = TREE_TYPE (decl); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE) - sprintf (str + strlen (str), "[%d]", - (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - else - strcat (str, "[]"); - } - else if (code == CALL_EXPR) - { - tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1)); - - strcat (str, "("); - while (chain) - { - gen_declaration (chain, str); - chain = TREE_CHAIN (chain); - if (chain) - strcat (str, ", "); - } - strcat (str, ")"); - } - else if (code == FUNCTION_TYPE) - { - tree chain = TYPE_ARG_TYPES (decl); /* a list of types */ - - strcat (str, "("); - while (chain && TREE_VALUE (chain) != void_type_node) - { - gen_declaration (TREE_VALUE (chain), str); - chain = TREE_CHAIN (chain); - if (chain && TREE_VALUE (chain) != void_type_node) - strcat (str, ", "); - } - strcat (str, ")"); - } - else if (code == INDIRECT_REF) - { - strcpy (tmpbuf, "*"); - if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST) - { - tree chain; - - for (chain = nreverse (copy_list (TREE_TYPE (decl))); - chain; - chain = TREE_CHAIN (chain)) - { - if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE) - { - strcat (tmpbuf, " "); - strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain))); - } - } - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } - else if (code == POINTER_TYPE) - { - strcpy (tmpbuf, "*"); - if (TREE_READONLY (decl) || TYPE_VOLATILE (decl)) - { - if (TREE_READONLY (decl)) - strcat (tmpbuf, " const"); - if (TYPE_VOLATILE (decl)) - strcat (tmpbuf, " volatile"); - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } -} - -static char * -gen_declarator (decl, buf, name) - tree decl; - char *buf; - char *name; -{ - if (decl) - { - enum tree_code code = TREE_CODE (decl); - char *str; - tree op; - int wrap = 0; - - switch (code) - { - case ARRAY_REF: - case INDIRECT_REF: - case CALL_EXPR: - op = TREE_OPERAND (decl, 0); - - /* we have a pointer to a function or array...(*)(), (*)[] */ - if ((code == ARRAY_REF || code == CALL_EXPR) - && op && TREE_CODE (op) == INDIRECT_REF) - wrap = 1; - - str = gen_declarator (op, buf, name); - - if (wrap) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - adorn_decl (decl, str); - break; - - case ARRAY_TYPE: - case FUNCTION_TYPE: - case POINTER_TYPE: - strcpy (buf, name); - str = buf; - - /* this clause is done iteratively...rather than recursively */ - do - { - op = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULLT); - - adorn_decl (decl, str); - - /* we have a pointer to a function or array...(*)(), (*)[] */ - if (code == POINTER_TYPE - && op && (TREE_CODE (op) == FUNCTION_TYPE - || TREE_CODE (op) == ARRAY_TYPE)) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - decl = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULLT); - } - while (decl && (code = TREE_CODE (decl))); - - break; - - case IDENTIFIER_NODE: - /* will only happen if we are processing a "raw" expr-decl. */ - strcpy (buf, IDENTIFIER_POINTER (decl)); - return buf; - } - - return str; - } - else /* we have an abstract declarator or a _DECL node */ - { - strcpy (buf, name); - return buf; - } -} - -static void -gen_declspecs (declspecs, buf, raw) - tree declspecs; - char *buf; - int raw; -{ - if (raw) - { - tree chain; - - for (chain = nreverse (copy_list (declspecs)); - chain; chain = TREE_CHAIN (chain)) - { - tree aspec = TREE_VALUE (chain); - - if (TREE_CODE (aspec) == IDENTIFIER_NODE) - strcat (buf, IDENTIFIER_POINTER (aspec)); - else if (TREE_CODE (aspec) == RECORD_TYPE) - { - if (TYPE_NAME (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - - /* NEW!!! */ - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - else - strcat (buf, "untagged struct"); - } - else if (TREE_CODE (aspec) == UNION_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged union"); - } - else if (TREE_CODE (aspec) == ENUMERAL_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged enum"); - } - else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec)) - { - strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec))); - } - /* NEW!!! */ - else if (IS_ID (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - if (TREE_CHAIN (chain)) - strcat (buf, " "); - } - } - else - { - /* type qualifiers */ - - if (TREE_READONLY (declspecs)) - strcat (buf, "const "); - if (TYPE_VOLATILE (declspecs)) - strcat (buf, "volatile "); - - switch (TREE_CODE (declspecs)) - { - /* type specifiers */ - - case INTEGER_TYPE: /* signed integer types */ - declspecs = TYPE_MAIN_VARIANT (declspecs); - - if (declspecs == short_integer_type_node) /* 's' */ - strcat (buf, "short int "); - else if (declspecs == integer_type_node) /* 'i' */ - strcat (buf, "int "); - else if (declspecs == long_integer_type_node) /* 'l' */ - strcat (buf, "long int "); - else if (declspecs == long_long_integer_type_node) /* 'l' */ - strcat (buf, "long long int "); - else if (declspecs == signed_char_type_node /* 'c' */ - || declspecs == char_type_node) - strcat (buf, "char "); - - /* unsigned integer types */ - - else if (declspecs == short_unsigned_type_node) /* 'S' */ - strcat (buf, "unsigned short "); - else if (declspecs == unsigned_type_node) /* 'I' */ - strcat (buf, "unsigned int "); - else if (declspecs == long_unsigned_type_node) /* 'L' */ - strcat (buf, "unsigned long "); - else if (declspecs == long_long_unsigned_type_node) /* 'L' */ - strcat (buf, "unsigned long long "); - else if (declspecs == unsigned_char_type_node) /* 'C' */ - strcat (buf, "unsigned char "); - break; - - case REAL_TYPE: /* floating point types */ - declspecs = TYPE_MAIN_VARIANT (declspecs); - - if (declspecs == float_type_node) /* 'f' */ - strcat (buf, "float "); - else if (declspecs == double_type_node) /* 'd' */ - strcat (buf, "double "); - else if (declspecs == long_double_type_node) /* 'd' */ - strcat (buf, "long double "); - break; - - case RECORD_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - if (! TREE_STATIC_TEMPLATE (declspecs)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - /* NEW!!! */ - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - else - strcat (buf, "untagged struct"); - - strcat (buf, " "); - break; - - case UNION_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - else - strcat (buf, "untagged union "); - break; - - case ENUMERAL_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - else - strcat (buf, "untagged enum "); - break; - - case VOID_TYPE: - strcat (buf, "void "); - break; - - /* NEW!!! */ - case POINTER_TYPE: - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - } - } -} - -static char * -gen_declaration (atype_or_adecl, buf) - tree atype_or_adecl; - char *buf; -{ - char declbuf[256]; - - if (TREE_CODE (atype_or_adecl) == TREE_LIST) - { - tree declspecs; /* "identifier_node", "record_type" */ - tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */ - - /* we have a "raw", abstract declarator (typename) */ - declarator = TREE_VALUE (atype_or_adecl); - declspecs = TREE_PURPOSE (atype_or_adecl); - - gen_declspecs (declspecs, buf, 1); - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - else - { - tree atype; - tree declspecs; /* "integer_type", "real_type", "record_type"... */ - tree declarator; /* "array_type", "function_type", "pointer_type". */ - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - atype = TREE_TYPE (atype_or_adecl); - else - atype = atype_or_adecl; /* assume we have a *_type node */ - - if (is_complex_decl (atype)) - { - tree chain; - - /* get the declaration specifier...it is at the end of the list */ - declarator = chain = atype; - do - chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */ - while (is_complex_decl (chain)); - declspecs = chain; - } - else - { - declspecs = atype; - declarator = NULLT; - } - - gen_declspecs (declspecs, buf, 0); - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - { - char *decl_name = (DECL_NAME (atype_or_adecl) - ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) - : ""); - - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, decl_name)); - } - else if (decl_name[0]) - { - strcat (buf, " "); - strcat (buf, decl_name); - } - } - else if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - return buf; -} - -#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth)))) - -static char * -gen_method_decl (method, buf) - tree method; - char *buf; -{ - tree chain; - - if (RAW_TYPESPEC (method) != objc_object_reference) - { - strcpy (buf, "("); - gen_declaration (TREE_TYPE (method), buf); - strcat (buf, ")"); - } - - chain = METHOD_SEL_ARGS (method); - if (chain) - { /* we have a chain of keyword_decls */ - do - { - if (KEYWORD_KEY_NAME (chain)) - strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain))); - - strcat (buf, ":"); - if (RAW_TYPESPEC (chain) != objc_object_reference) - { - strcat (buf, "("); - gen_declaration (TREE_TYPE (chain), buf); - strcat (buf, ")"); - } - strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain))); - if ((chain = TREE_CHAIN (chain))) - strcat (buf, " "); - } - while (chain); - - if (METHOD_ADD_ARGS (method) == (tree)1) - strcat (buf, ", ..."); - else if (METHOD_ADD_ARGS (method)) - { - /* we have a tree list node as generate by get_parm_info. */ - chain = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - /* know we have a chain of parm_decls */ - while (chain) - { - strcat (buf, ", "); - gen_declaration (chain, buf); - chain = TREE_CHAIN (chain); - } - } - } - else /* we have a unary selector */ - strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); - - return buf; -} - -/* debug info... */ - -static void -dump_interface (fp, chain) - FILE *fp; - tree chain; -{ - char *buf = (char *)xmalloc (256); - char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain)); - tree ivar_decls = CLASS_RAW_IVARS (chain); - tree nst_methods = CLASS_NST_METHODS (chain); - tree cls_methods = CLASS_CLS_METHODS (chain); - - fprintf (fp, "\n@interface %s", my_name); - - if (CLASS_SUPER_NAME (chain)) - { - char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); - fprintf (fp, " : %s\n", super_name); - } - else - fprintf (fp, "\n"); - - if (ivar_decls) - { - fprintf (fp, "{\n"); - do - { - bzero (buf, 256); - fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf)); - ivar_decls = TREE_CHAIN (ivar_decls); - } - while (ivar_decls); - fprintf (fp, "}\n"); - } - - while (nst_methods) - { - bzero (buf, 256); - fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf)); - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - bzero (buf, 256); - fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf)); - cls_methods = TREE_CHAIN (cls_methods); - } - fprintf (fp, "\n@end"); -} - -static void -init_objc () -{ - /* Add the special tree codes of Objective C to the tables. */ - -#define LAST_CODE LAST_AND_UNUSED_TREE_CODE - - gcc_obstack_init (&util_obstack); - util_firstobj = (char *) obstack_finish (&util_obstack); - - tree_code_type - = (char **) xrealloc (tree_code_type, - sizeof (char *) * LAST_OBJC_TREE_CODE); - tree_code_length - = (int *) xrealloc (tree_code_length, - sizeof (int) * LAST_OBJC_TREE_CODE); - tree_code_name - = (char **) xrealloc (tree_code_name, - sizeof (char *) * LAST_OBJC_TREE_CODE); - bcopy (objc_tree_code_type, - tree_code_type + (int) LAST_CODE, - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (char *))); - bcopy (objc_tree_code_length, - tree_code_length + (int) LAST_CODE, - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (int))); - bcopy (objc_tree_code_name, - tree_code_name + (int) LAST_CODE, - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (char *))); - - errbuf = (char *)xmalloc (BUFSIZE); - hash_init (); - synth_module_prologue (); -} - -static void -finish_objc () -{ - struct imp_entry *impent; - tree chain; - /* The internally generated initializers appear to have missing braces. - Don't warn about this. */ - int save_warn_missing_braces = warn_missing_braces; - warn_missing_braces = 0; - - generate_forward_declaration_to_string_table (); - -#ifdef OBJC_PROLOGUE - OBJC_PROLOGUE; -#endif - - if (implementation_context || class_names_chain - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - generate_objc_symtab_decl (); - - for (impent = imp_list; impent; impent = impent->next) - { - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - UOBJC_CLASS_decl = impent->class_decl; - UOBJC_METACLASS_decl = impent->meta_decl; - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* all of the following reference the string pool... */ - generate_ivar_lists (); - generate_dispatch_tables (); - generate_shared_structures (); - } - else - { - generate_dispatch_tables (); - generate_category (implementation_context); - } - } - - /* If we are using an array of selectors, we must always - finish up the array decl even if no selectors were used. */ - if (! flag_next_runtime || sel_ref_chain) - build_selector_translation_table (); - - if (protocol_chain) - generate_protocols (); - - if (implementation_context || class_names_chain - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - { - /* Arrange for Objc data structures to be initialized at run time. */ - char *init_name = build_module_descriptor (); - if (init_name) - assemble_constructor (init_name); - } - - /* dump the class references...this forces the appropriate classes - to be linked into the executable image, preserving unix archive - semantics...this can be removed when we move to a more dynamically - linked environment. */ - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - handle_class_ref (chain); - if (TREE_PURPOSE (chain)) - generate_classref_translation_entry (chain); - } - - for (impent = imp_list; impent; impent = impent->next) - handle_impent (impent); - - /* dump the string table last */ - - generate_strings (); - - if (flag_gen_declaration) - { - add_class (implementation_context); - dump_interface (gen_declaration_file, implementation_context); - } - - if (warn_selector) - { - int slot; - hash hsh; - - /* Run through the selector hash tables and print a warning for any - selector which has multiple methods. */ - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - } - - warn_missing_braces = save_warn_missing_braces; -} - -/* Subroutines of finish_objc. */ - -static void -generate_classref_translation_entry (chain) - tree chain; -{ - tree expr, name, decl_specs, decl, sc_spec; - tree type; - - type = TREE_TYPE (TREE_PURPOSE (chain)); - - expr = add_objc_string (TREE_VALUE (chain), class_names); - expr = build_c_cast (type, expr); /* cast! */ - - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]); - - /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULLT, type, sc_spec); - - /* the `decl' that is returned from start_decl is the one that we - forward declared in `build_class_reference'. */ - decl = start_decl (name, decl_specs, 1); - end_temporary_allocation (); - finish_decl (decl, expr, NULLT); - return; -} - -static void -handle_class_ref (chain) - tree chain; -{ - char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); - if (! flag_next_runtime) - { - tree decl; - char *string = (char *) alloca (strlen (name) + 30); - tree exp; - - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), name); - - /* Make a decl for this name, so we can use its address in a tree. */ - decl = build_decl (VAR_DECL, get_identifier (string), char_type_node); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - pushdecl (decl); - rest_of_decl_compilation (decl, 0, 0, 0); - - /* Make following constant read-only (why not)? */ - readonly_data_section (); - - exp = build1 (ADDR_EXPR, string_type_node, decl); - - /* Align the section properly. */ - assemble_constant_align (exp); - - /* Inform the assembler about this new external thing. */ - assemble_external (decl); - - /* Output a constant to reference this address. */ - output_constant (exp, int_size_in_bytes (string_type_node)); - } - else - { - /* This overreliance on our assembler (i.e. lack of portability) - should be dealt with at some point. The GNU strategy (above) - won't work either, but it is a start. */ - char *string = (char *) alloca (strlen (name) + 30); - sprintf (string, ".reference .objc_class_name_%s", name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } -} - -static void -handle_impent (impent) - struct imp_entry *impent; -{ - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) + 30); - - if (flag_next_runtime) - { - /* Grossly unportable. - People should know better than to assume - such things about assembler syntax! */ - sprintf (string, ".objc_class_name_%s=0", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_class_name_%s", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - else - { - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), class_name); - assemble_global (string); - assemble_label (string); - } - } - else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) - + strlen (class_super_name) + 30); - - /* Do the same for categories. Even though no references to these - symbols are generated automatically by the compiler, it gives - you a handle to pull them into an archive by hand. */ - if (flag_next_runtime) - { - /* Grossly unportable. */ - sprintf (string, ".objc_category_name_%s_%s=0", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_category_name_%s_%s", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - else - { - sprintf (string, "%sobjc_category_name_%s_%s", - (flag_next_runtime ? "." : "__"), - class_name, class_super_name); - assemble_global (string); - assemble_label (string); - } - } -} - -#ifdef DEBUG - -static void -objc_debug (fp) - FILE *fp; -{ - char *buf = (char *)xmalloc (256); - - { /* dump function prototypes */ - tree loop = UOBJC_MODULES_decl; - - fprintf (fp, "\n\nfunction prototypes:\n"); - while (loop) - { - if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop)) - { - /* we have a function definition - generate prototype */ - bzero (errbuf, BUFSIZE); - gen_declaration (loop, errbuf); - fprintf (fp, "%s;\n", errbuf); - } - loop = TREE_CHAIN (loop); - } - } - { /* dump global chains */ - tree loop; - int i, index = 0, offset = 0; - hash hashlist; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = nst_method_hash_list[i]) - { - fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = cls_method_hash_list[i]) - { - fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - fprintf (fp, "\nsel_refdef_chain:\n"); - for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop)) - { - fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset, - IDENTIFIER_POINTER (TREE_VALUE (loop))); - index++; - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1; - } - fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index); - } -} -#endif - -void -print_lang_statistics () -{ -} diff --git a/gnu/usr.bin/gcc2/cc1obj/objc-act.h b/gnu/usr.bin/gcc2/cc1obj/objc-act.h deleted file mode 100644 index 9f2394b9392..00000000000 --- a/gnu/usr.bin/gcc2/cc1obj/objc-act.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Declarations for objc-act.c. - Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: objc-act.h,v 1.1.1.1 1995/10/18 08:39:29 deraadt Exp $ -*/ - -/*** Public Interface (procedures) ***/ - -/* used by yyparse */ - -void objc_finish PROTO((void)); -tree start_class PROTO((enum tree_code, tree, tree, tree)); -tree continue_class PROTO((tree)); -void finish_class PROTO((tree)); -void start_method_def PROTO((tree)); -void continue_method_def PROTO((void)); -void finish_method_def PROTO((void)); -tree start_protocol PROTO((enum tree_code, tree, tree)); -void finish_protocol PROTO((tree)); -void add_objc_decls PROTO((void)); - -tree is_ivar PROTO((tree, tree)); -int is_private PROTO((tree)); -int is_public PROTO((tree, tree)); -tree add_instance_variable PROTO((tree, int, tree, tree, tree)); -tree add_class_method PROTO((tree, tree)); -tree add_instance_method PROTO((tree, tree)); -tree get_super_receiver PROTO((void)); -tree get_class_ivars PROTO((tree)); -tree get_class_reference PROTO((tree)); -tree get_static_reference PROTO((tree, tree)); -tree get_object_reference PROTO((tree)); -tree build_message_expr PROTO((tree)); -tree build_selector_expr PROTO((tree)); -tree build_ivar_reference PROTO((tree)); -tree build_keyword_decl PROTO((tree, tree, tree)); -tree build_method_decl PROTO((enum tree_code, tree, tree, tree)); -tree build_protocol_expr PROTO((tree)); -tree build_objc_string_object PROTO((tree)); - -extern tree objc_ivar_chain; -extern tree objc_method_context; - -void objc_declare_alias PROTO((tree, tree)); -void objc_declare_class PROTO((tree)); - -extern int objc_receiver_context; - -/* the following routines are used to implement statically typed objects */ - -int objc_comptypes PROTO((tree, tree, int)); -void objc_check_decl PROTO((tree)); - -/* NeXT extensions */ - -tree build_encode_expr PROTO((tree)); - -/* Objective-C structures */ - -/* KEYWORD_DECL */ -#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name) -#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments) - -/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */ -#define METHOD_SEL_NAME(DECL) ((DECL)->decl.name) -#define METHOD_SEL_ARGS(DECL) ((DECL)->decl.arguments) -#define METHOD_ADD_ARGS(DECL) ((DECL)->decl.result) -#define METHOD_DEFINITION(DECL) ((DECL)->decl.initial) -#define METHOD_ENCODING(DECL) ((DECL)->decl.context) - -/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, - PROTOCOL_INTERFACE_TYPE */ -#define CLASS_NAME(CLASS) ((CLASS)->type.name) -#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context) -#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 2) -#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 3) -#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 4) -#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name) -#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context) - -/* Define the Objective-C or Objective-C++ language-specific tree codes. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, -enum objc_tree_code { -#ifdef OBJCPLUS - dummy_tree_code = LAST_CPLUS_TREE_CODE, -#else - dummy_tree_code = LAST_AND_UNUSED_TREE_CODE, -#endif -#include "objc-tree.def" - LAST_OBJC_TREE_CODE -}; -#undef DEFTREECODE diff --git a/gnu/usr.bin/gcc2/cc1obj/objc-parse.c b/gnu/usr.bin/gcc2/cc1obj/objc-parse.c deleted file mode 100644 index 1be54f5d83e..00000000000 --- a/gnu/usr.bin/gcc2/cc1obj/objc-parse.c +++ /dev/null @@ -1,4630 +0,0 @@ - -/* A Bison parser, made from objc-parse.y */ - -#ifndef lint -static char rcsid[] = "$Id: objc-parse.c,v 1.1.1.1 1995/10/18 08:39:29 deraadt Exp $"; -#endif /* not lint */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define IDENTIFIER 258 -#define TYPENAME 259 -#define SCSPEC 260 -#define TYPESPEC 261 -#define TYPE_QUAL 262 -#define CONSTANT 263 -#define STRING 264 -#define ELLIPSIS 265 -#define SIZEOF 266 -#define ENUM 267 -#define STRUCT 268 -#define UNION 269 -#define IF 270 -#define ELSE 271 -#define WHILE 272 -#define DO 273 -#define FOR 274 -#define SWITCH 275 -#define CASE 276 -#define DEFAULT 277 -#define BREAK 278 -#define CONTINUE 279 -#define RETURN 280 -#define GOTO 281 -#define ASM_KEYWORD 282 -#define TYPEOF 283 -#define ALIGNOF 284 -#define ALIGN 285 -#define ATTRIBUTE 286 -#define EXTENSION 287 -#define LABEL 288 -#define REALPART 289 -#define IMAGPART 290 -#define ASSIGN 291 -#define OROR 292 -#define ANDAND 293 -#define EQCOMPARE 294 -#define ARITHCOMPARE 295 -#define LSHIFT 296 -#define RSHIFT 297 -#define UNARY 298 -#define PLUSPLUS 299 -#define MINUSMINUS 300 -#define HYPERUNARY 301 -#define POINTSAT 302 -#define INTERFACE 303 -#define IMPLEMENTATION 304 -#define END 305 -#define SELECTOR 306 -#define DEFS 307 -#define ENCODE 308 -#define CLASSNAME 309 -#define PUBLIC 310 -#define PRIVATE 311 -#define PROTECTED 312 -#define PROTOCOL 313 -#define OBJECTNAME 314 -#define CLASS 315 -#define ALIAS 316 -#define OBJC_STRING 317 - -#line 31 "objc-parse.y" - -#include -#include -#include - -#include "config.h" -#include "tree.h" -#include "input.h" -#include "c-lex.h" -#include "c-tree.h" -#include "flags.h" - -#ifdef MULTIBYTE_CHARS -#include -#include -#endif - -#include "objc-act.h" - -/* Since parsers are distinct for each language, put the language string - definition here. */ -char *language_string = "GNU Obj-C"; - -#ifndef errno -extern int errno; -#endif - -void yyerror (); - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#line 69 "objc-parse.y" -typedef union {long itype; tree ttype; enum tree_code code; - char *filename; int lineno; } YYSTYPE; -#line 190 "objc-parse.y" - -/* Number of statements (loosely speaking) seen so far. */ -static int stmt_count; - -/* Input file and line number of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static char *if_stmt_file; -static int if_stmt_line; - -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* Stack of saved values of current_declspecs. */ -static tree declspec_stack; - -/* 1 if we explained undeclared var errors. */ -static int undeclared_variable_notice; - -/* Objective-C specific information */ - -tree objc_interface_context; -tree objc_implementation_context; -tree objc_method_context; -tree objc_ivar_chain; -tree objc_ivar_context; -enum tree_code objc_inherit_code; -int objc_receiver_context; -int objc_public_flag; - - -/* Tell yyparse how to print a token's value, if yydebug is set. */ - -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint (); - -#ifndef YYLTYPE -typedef - struct yyltype - { - int timestamp; - int first_line; - int first_column; - int last_line; - int last_column; - char *text; - } - yyltype; - -#define YYLTYPE yyltype -#endif - -#include - -#ifndef __STDC__ -#define const -#endif - - - -#define YYFINAL 865 -#define YYFLAG -32768 -#define YYNTBASE 85 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 317 ? yytranslate[x] : 281) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 81, 2, 2, 2, 53, 44, 2, 60, - 77, 51, 49, 82, 50, 59, 52, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 39, 78, 2, - 37, 2, 38, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 61, 2, 84, 43, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 83, 42, 79, 80, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 40, 41, 45, 46, 47, 48, 54, 55, 56, - 57, 58, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76 -}; - -static const short yyprhs[] = { 0, - 0, 1, 3, 4, 7, 8, 12, 14, 16, 18, - 24, 28, 33, 38, 41, 44, 47, 50, 52, 53, - 54, 62, 67, 68, 69, 77, 82, 83, 84, 91, - 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, - 115, 117, 119, 120, 122, 124, 128, 130, 133, 134, - 138, 141, 144, 147, 152, 155, 160, 163, 166, 168, - 173, 181, 183, 187, 191, 195, 199, 203, 207, 211, - 215, 219, 223, 227, 231, 235, 239, 245, 249, 253, - 255, 257, 259, 263, 267, 268, 273, 278, 283, 287, - 291, 294, 297, 299, 301, 303, 305, 307, 309, 312, - 314, 317, 318, 320, 323, 327, 329, 331, 334, 337, - 342, 347, 350, 353, 357, 359, 361, 364, 367, 368, - 373, 378, 382, 386, 389, 392, 395, 399, 400, 403, - 406, 408, 410, 413, 416, 419, 423, 424, 427, 429, - 431, 433, 436, 439, 444, 449, 451, 453, 455, 457, - 461, 463, 467, 468, 473, 474, 481, 485, 486, 493, - 497, 498, 505, 507, 511, 513, 518, 523, 532, 534, - 537, 541, 546, 548, 550, 554, 558, 564, 565, 569, - 570, 574, 576, 578, 582, 586, 591, 595, 599, 601, - 603, 607, 612, 616, 620, 622, 626, 630, 634, 639, - 643, 645, 646, 653, 658, 661, 662, 669, 674, 677, - 678, 686, 687, 694, 697, 698, 700, 701, 703, 705, - 708, 709, 713, 716, 721, 725, 727, 731, 733, 735, - 737, 741, 746, 753, 759, 761, 765, 767, 771, 774, - 777, 778, 780, 782, 785, 786, 789, 793, 797, 800, - 804, 809, 813, 816, 820, 823, 825, 828, 831, 832, - 834, 837, 838, 839, 841, 843, 846, 850, 852, 855, - 858, 865, 871, 877, 880, 883, 888, 889, 894, 895, - 896, 900, 905, 909, 911, 913, 915, 917, 920, 921, - 926, 928, 932, 933, 934, 942, 948, 951, 952, 953, - 954, 967, 968, 975, 978, 981, 984, 988, 995, 1004, - 1015, 1028, 1032, 1037, 1039, 1041, 1042, 1049, 1053, 1059, - 1062, 1065, 1066, 1068, 1069, 1071, 1072, 1074, 1076, 1080, - 1085, 1087, 1091, 1092, 1095, 1098, 1099, 1104, 1107, 1108, - 1110, 1112, 1116, 1118, 1122, 1125, 1128, 1131, 1134, 1137, - 1138, 1141, 1143, 1146, 1148, 1152, 1154, 1158, 1160, 1162, - 1164, 1166, 1168, 1170, 1172, 1176, 1180, 1185, 1186, 1187, - 1198, 1199, 1206, 1207, 1208, 1221, 1222, 1231, 1232, 1239, - 1242, 1243, 1252, 1257, 1258, 1268, 1274, 1275, 1282, 1283, - 1287, 1291, 1293, 1295, 1297, 1299, 1300, 1304, 1307, 1311, - 1315, 1317, 1318, 1320, 1324, 1326, 1330, 1333, 1334, 1335, - 1336, 1344, 1345, 1346, 1347, 1355, 1356, 1357, 1360, 1362, - 1364, 1367, 1368, 1372, 1374, 1376, 1377, 1378, 1384, 1385, - 1386, 1392, 1397, 1399, 1405, 1408, 1409, 1412, 1413, 1415, - 1417, 1419, 1422, 1425, 1430, 1433, 1436, 1438, 1442, 1444, - 1446, 1448, 1449, 1452, 1453, 1457, 1459, 1461, 1464, 1466, - 1468, 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, - 1488, 1490, 1492, 1494, 1496, 1498, 1500, 1502, 1504, 1506, - 1508, 1510, 1512, 1514, 1521, 1525, 1531, 1534, 1536, 1538, - 1540, 1543, 1545, 1549, 1552, 1554, 1556, 1557, 1558, 1565, - 1567, 1569, 1571, 1574, 1577, 1579, 1584, 1589 -}; - -static const short yyrhs[] = { -1, - 86, 0, 0, 87, 89, 0, 0, 86, 88, 89, - 0, 91, 0, 90, 0, 213, 0, 27, 60, 100, - 77, 78, 0, 117, 127, 78, 0, 121, 117, 127, - 78, 0, 119, 117, 126, 78, 0, 121, 78, 0, - 119, 78, 0, 1, 78, 0, 1, 79, 0, 78, - 0, 0, 0, 119, 117, 142, 92, 111, 93, 172, - 0, 119, 117, 142, 1, 0, 0, 0, 121, 117, - 145, 94, 111, 95, 172, 0, 121, 117, 145, 1, - 0, 0, 0, 117, 145, 96, 111, 97, 172, 0, - 117, 145, 1, 0, 3, 0, 4, 0, 73, 0, - 68, 0, 44, 0, 50, 0, 49, 0, 55, 0, - 56, 0, 80, 0, 81, 0, 102, 0, 0, 102, - 0, 106, 0, 102, 82, 106, 0, 107, 0, 51, - 105, 0, 0, 32, 104, 105, 0, 99, 105, 0, - 41, 98, 0, 11, 103, 0, 11, 60, 160, 77, - 0, 29, 103, 0, 29, 60, 160, 77, 0, 34, - 105, 0, 35, 105, 0, 103, 0, 60, 160, 77, - 105, 0, 60, 160, 77, 83, 137, 151, 79, 0, - 105, 0, 106, 49, 106, 0, 106, 50, 106, 0, - 106, 51, 106, 0, 106, 52, 106, 0, 106, 53, - 106, 0, 106, 47, 106, 0, 106, 48, 106, 0, - 106, 46, 106, 0, 106, 45, 106, 0, 106, 44, - 106, 0, 106, 42, 106, 0, 106, 43, 106, 0, - 106, 41, 106, 0, 106, 40, 106, 0, 106, 38, - 196, 39, 106, 0, 106, 37, 106, 0, 106, 36, - 106, 0, 3, 0, 8, 0, 109, 0, 60, 100, - 77, 0, 60, 1, 77, 0, 0, 60, 108, 173, - 77, 0, 107, 60, 101, 77, 0, 107, 61, 100, - 84, 0, 107, 59, 98, 0, 107, 58, 98, 0, - 107, 55, 0, 107, 56, 0, 272, 0, 278, 0, - 279, 0, 280, 0, 110, 0, 9, 0, 109, 9, - 0, 76, 0, 110, 76, 0, 0, 113, 0, 113, - 10, 0, 178, 179, 114, 0, 112, 0, 167, 0, - 113, 112, 0, 112, 167, 0, 119, 117, 126, 78, - 0, 121, 117, 127, 78, 0, 119, 78, 0, 121, - 78, 0, 178, 179, 118, 0, 115, 0, 167, 0, - 116, 115, 0, 115, 167, 0, 0, 119, 117, 126, - 78, 0, 121, 117, 127, 78, 0, 119, 117, 138, - 0, 121, 117, 140, 0, 119, 78, 0, 121, 78, - 0, 124, 120, 0, 121, 124, 120, 0, 0, 120, - 125, 0, 120, 5, 0, 7, 0, 5, 0, 121, - 7, 0, 121, 5, 0, 124, 123, 0, 162, 124, - 123, 0, 0, 123, 125, 0, 6, 0, 146, 0, - 4, 0, 68, 229, 0, 73, 229, 0, 28, 60, - 100, 77, 0, 28, 60, 160, 77, 0, 6, 0, - 7, 0, 146, 0, 129, 0, 126, 82, 129, 0, - 131, 0, 127, 82, 129, 0, 0, 27, 60, 109, - 77, 0, 0, 142, 128, 133, 37, 130, 136, 0, - 142, 128, 133, 0, 0, 145, 128, 133, 37, 132, - 136, 0, 145, 128, 133, 0, 0, 31, 60, 60, - 134, 77, 77, 0, 135, 0, 134, 82, 135, 0, - 3, 0, 3, 60, 3, 77, 0, 3, 60, 8, - 77, 0, 3, 60, 3, 82, 8, 82, 8, 77, - 0, 106, 0, 83, 79, 0, 83, 137, 79, 0, - 83, 137, 82, 79, 0, 1, 0, 136, 0, 137, - 82, 136, 0, 98, 39, 136, 0, 137, 82, 98, - 39, 136, 0, 0, 142, 139, 173, 0, 0, 145, - 141, 173, 0, 143, 0, 145, 0, 60, 143, 77, - 0, 143, 60, 208, 0, 143, 61, 100, 84, 0, - 143, 61, 84, 0, 51, 163, 143, 0, 4, 0, - 73, 0, 144, 60, 208, 0, 144, 61, 100, 84, - 0, 144, 61, 84, 0, 51, 163, 144, 0, 4, - 0, 145, 60, 208, 0, 60, 145, 77, 0, 51, - 163, 145, 0, 145, 61, 100, 84, 0, 145, 61, - 84, 0, 3, 0, 0, 13, 98, 83, 147, 153, - 79, 0, 13, 83, 153, 79, 0, 13, 98, 0, - 0, 14, 98, 83, 148, 153, 79, 0, 14, 83, - 153, 79, 0, 14, 98, 0, 0, 12, 98, 83, - 149, 158, 152, 79, 0, 0, 12, 83, 150, 158, - 152, 79, 0, 12, 98, 0, 0, 82, 0, 0, - 82, 0, 154, 0, 154, 155, 0, 0, 154, 155, - 78, 0, 154, 78, 0, 66, 60, 68, 77, 0, - 122, 117, 156, 0, 122, 0, 162, 117, 156, 0, - 162, 0, 1, 0, 157, 0, 156, 82, 157, 0, - 178, 179, 142, 133, 0, 178, 179, 142, 39, 106, - 133, 0, 178, 179, 39, 106, 133, 0, 159, 0, - 158, 82, 159, 0, 98, 0, 98, 37, 106, 0, - 122, 161, 0, 162, 161, 0, 0, 164, 0, 7, - 0, 162, 7, 0, 0, 163, 7, 0, 60, 164, - 77, 0, 51, 163, 164, 0, 51, 163, 0, 164, - 60, 201, 0, 164, 61, 100, 84, 0, 164, 61, - 84, 0, 60, 201, 0, 61, 100, 84, 0, 61, - 84, 0, 181, 0, 165, 181, 0, 165, 167, 0, - 0, 165, 0, 1, 78, 0, 0, 0, 170, 0, - 171, 0, 170, 171, 0, 33, 212, 78, 0, 173, - 0, 1, 173, 0, 83, 79, 0, 83, 168, 169, - 116, 166, 79, 0, 83, 168, 169, 1, 79, 0, - 83, 168, 169, 165, 79, 0, 175, 180, 0, 175, - 1, 0, 15, 60, 100, 77, 0, 0, 18, 177, - 180, 17, 0, 0, 0, 178, 179, 183, 0, 178, - 179, 194, 180, 0, 178, 179, 182, 0, 183, 0, - 194, 0, 173, 0, 191, 0, 100, 78, 0, 0, - 174, 16, 184, 180, 0, 174, 0, 174, 16, 1, - 0, 0, 0, 17, 185, 60, 100, 77, 186, 180, - 0, 176, 60, 100, 77, 78, 0, 176, 1, 0, - 0, 0, 0, 19, 60, 196, 78, 187, 196, 78, - 188, 196, 77, 189, 180, 0, 0, 20, 60, 100, - 77, 190, 180, 0, 23, 78, 0, 24, 78, 0, - 25, 78, 0, 25, 100, 78, 0, 27, 195, 60, - 100, 77, 78, 0, 27, 195, 60, 100, 39, 197, - 77, 78, 0, 27, 195, 60, 100, 39, 197, 39, - 197, 77, 78, 0, 27, 195, 60, 100, 39, 197, - 39, 197, 39, 200, 77, 78, 0, 26, 98, 78, - 0, 26, 51, 100, 78, 0, 78, 0, 192, 0, - 0, 19, 60, 107, 77, 193, 180, 0, 21, 106, - 39, 0, 21, 106, 10, 106, 39, 0, 22, 39, - 0, 98, 39, 0, 0, 7, 0, 0, 100, 0, - 0, 198, 0, 199, 0, 198, 82, 199, 0, 9, - 60, 100, 77, 0, 109, 0, 200, 82, 109, 0, - 0, 202, 203, 0, 205, 77, 0, 0, 206, 78, - 204, 203, 0, 1, 77, 0, 0, 10, 0, 206, - 0, 206, 82, 10, 0, 207, 0, 206, 82, 207, - 0, 119, 144, 0, 119, 145, 0, 119, 161, 0, - 121, 145, 0, 121, 161, 0, 0, 209, 210, 0, - 203, 0, 211, 77, 0, 3, 0, 211, 82, 3, - 0, 98, 0, 212, 82, 98, 0, 217, 0, 215, - 0, 216, 0, 227, 0, 236, 0, 64, 0, 98, - 0, 214, 82, 98, 0, 74, 214, 78, 0, 75, - 98, 98, 78, 0, 0, 0, 62, 98, 229, 83, - 218, 230, 79, 219, 243, 64, 0, 0, 62, 98, - 229, 220, 243, 64, 0, 0, 0, 62, 98, 39, - 98, 229, 83, 221, 230, 79, 222, 243, 64, 0, - 0, 62, 98, 39, 98, 229, 223, 243, 64, 0, - 0, 63, 98, 83, 224, 230, 79, 0, 63, 98, - 0, 0, 63, 98, 39, 98, 83, 225, 230, 79, - 0, 63, 98, 39, 98, 0, 0, 62, 98, 60, - 98, 77, 229, 226, 243, 64, 0, 63, 98, 60, - 98, 77, 0, 0, 72, 98, 229, 228, 243, 64, - 0, 0, 46, 214, 46, 0, 230, 231, 232, 0, - 232, 0, 70, 0, 71, 0, 69, 0, 0, 232, - 233, 78, 0, 232, 78, 0, 122, 117, 234, 0, - 162, 117, 234, 0, 1, 0, 0, 235, 0, 234, - 82, 235, 0, 142, 0, 142, 39, 106, 0, 39, - 106, 0, 0, 0, 0, 49, 237, 253, 238, 254, - 239, 172, 0, 0, 0, 0, 50, 240, 253, 241, - 254, 242, 172, 0, 0, 0, 244, 245, 0, 248, - 0, 90, 0, 245, 248, 0, 0, 245, 246, 90, - 0, 78, 0, 1, 0, 0, 0, 49, 249, 253, - 250, 247, 0, 0, 0, 50, 251, 253, 252, 247, - 0, 60, 160, 77, 262, 0, 262, 0, 60, 160, - 77, 263, 260, 0, 263, 260, 0, 0, 78, 255, - 0, 0, 256, 0, 257, 0, 167, 0, 256, 257, - 0, 257, 167, 0, 119, 117, 258, 78, 0, 119, - 78, 0, 121, 78, 0, 259, 0, 258, 82, 259, - 0, 144, 0, 145, 0, 161, 0, 0, 82, 10, - 0, 0, 82, 261, 205, 0, 264, 0, 266, 0, - 263, 266, 0, 3, 0, 4, 0, 73, 0, 265, - 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, - 0, 17, 0, 18, 0, 19, 0, 20, 0, 21, - 0, 22, 0, 23, 0, 24, 0, 25, 0, 26, - 0, 27, 0, 11, 0, 28, 0, 29, 0, 6, - 0, 7, 0, 264, 39, 60, 160, 77, 98, 0, - 264, 39, 98, 0, 39, 60, 160, 77, 98, 0, - 39, 98, 0, 264, 0, 268, 0, 270, 0, 268, - 270, 0, 102, 0, 264, 39, 269, 0, 39, 269, - 0, 100, 0, 68, 0, 0, 0, 61, 273, 271, - 274, 267, 84, 0, 264, 0, 276, 0, 277, 0, - 276, 277, 0, 264, 39, 0, 39, 0, 65, 60, - 275, 77, 0, 72, 60, 98, 77, 0, 67, 60, - 160, 77, 0 -}; - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 227, 232, 246, 248, 248, 249, 251, 253, 254, 255, - 265, 271, 273, 275, 277, 279, 280, 281, 286, 292, - 294, 295, 297, 302, 304, 305, 307, 312, 314, 315, - 319, 321, 322, 323, 326, 328, 330, 332, 334, 336, - 338, 342, 346, 349, 352, 355, 359, 361, 364, 367, - 370, 374, 400, 405, 407, 409, 411, 413, 417, 419, - 422, 447, 449, 451, 453, 455, 457, 459, 461, 463, - 465, 467, 469, 471, 473, 475, 477, 479, 482, 488, - 650, 651, 653, 659, 661, 675, 693, 695, 697, 709, - 723, 725, 727, 729, 731, 733, 735, 740, 742, 748, - 750, 754, 756, 757, 767, 772, 774, 775, 776, 779, - 784, 788, 791, 799, 804, 806, 807, 808, 815, 823, - 828, 832, 836, 840, 842, 850, 853, 857, 859, 861, - 872, 876, 878, 881, 894, 897, 901, 903, 911, 912, - 913, 917, 919, 921, 923, 929, 930, 931, 934, 936, - 939, 941, 944, 947, 953, 958, 960, 966, 971, 973, - 980, 983, 988, 990, 995, 1000, 1010, 1021, 1039, 1041, - 1045, 1047, 1049, 1055, 1058, 1063, 1065, 1069, 1086, 1090, - 1107, 1114, 1116, 1121, 1124, 1129, 1131, 1133, 1135, 1136, - 1144, 1150, 1152, 1154, 1156, 1162, 1168, 1170, 1172, 1174, - 1176, 1179, 1184, 1188, 1191, 1193, 1195, 1197, 1200, 1202, - 1205, 1208, 1211, 1214, 1218, 1220, 1223, 1225, 1229, 1232, - 1237, 1239, 1241, 1245, 1269, 1275, 1280, 1285, 1290, 1294, - 1296, 1300, 1304, 1308, 1318, 1320, 1325, 1328, 1332, 1335, - 1339, 1342, 1345, 1348, 1352, 1355, 1359, 1363, 1365, 1367, - 1369, 1371, 1373, 1375, 1377, 1385, 1387, 1388, 1391, 1393, - 1396, 1399, 1412, 1414, 1419, 1421, 1424, 1438, 1441, 1444, - 1446, 1451, 1456, 1464, 1469, 1472, 1485, 1493, 1497, 1501, - 1505, 1511, 1515, 1520, 1522, 1533, 1536, 1537, 1542, 1547, - 1550, 1558, 1560, 1570, 1580, 1581, 1589, 1592, 1604, 1608, - 1625, 1632, 1641, 1643, 1648, 1653, 1657, 1661, 1672, 1679, - 1686, 1693, 1704, 1708, 1711, 1716, 1739, 1770, 1794, 1822, - 1837, 1848, 1851, 1855, 1858, 1863, 1865, 1868, 1870, 1874, - 1879, 1882, 1888, 1893, 1898, 1900, 1909, 1910, 1916, 1918, - 1923, 1925, 1929, 1932, 1938, 1941, 1943, 1945, 1947, 1954, - 1959, 1964, 1966, 1975, 1978, 1983, 1986, 1992, 1994, 1995, - 1996, 1997, 1998, 2012, 2015, 2019, 2025, 2031, 2038, 2043, - 2049, 2056, 2062, 2068, 2073, 2079, 2086, 2092, 2098, 2104, - 2112, 2118, 2124, 2132, 2139, 2145, 2154, 2161, 2169, 2174, - 2183, 2185, 2188, 2190, 2191, 2194, 2199, 2200, 2217, 2223, - 2228, 2232, 2235, 2236, 2239, 2247, 2253, 2262, 2272, 2279, - 2283, 2288, 2297, 2304, 2308, 2318, 2320, 2321, 2323, 2325, - 2326, 2327, 2328, 2330, 2332, 2335, 2341, 2346, 2346, 2351, - 2355, 2357, 2363, 2368, 2373, 2382, 2384, 2390, 2392, 2395, - 2397, 2398, 2399, 2402, 2405, 2407, 2411, 2414, 2421, 2424, - 2426, 2430, 2435, 2440, 2445, 2452, 2456, 2459, 2465, 2467, - 2468, 2469, 2472, 2474, 2475, 2476, 2477, 2478, 2479, 2480, - 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, - 2491, 2492, 2492, 2495, 2501, 2506, 2511, 2517, 2519, 2522, - 2524, 2531, 2543, 2548, 2554, 2556, 2562, 2566, 2567, 2573, - 2575, 2578, 2580, 2586, 2591, 2597, 2604, 2613 -}; - -static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", -"TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", -"ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", -"BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ALIGN", -"ATTRIBUTE","EXTENSION","LABEL","REALPART","IMAGPART","ASSIGN","'='","'?'","':'", -"OROR","ANDAND","'|'","'^'","'&'","EQCOMPARE","ARITHCOMPARE","LSHIFT","RSHIFT", -"'+'","'-'","'*'","'/'","'%'","UNARY","PLUSPLUS","MINUSMINUS","HYPERUNARY","POINTSAT", -"'.'","'('","'['","INTERFACE","IMPLEMENTATION","END","SELECTOR","DEFS","ENCODE", -"CLASSNAME","PUBLIC","PRIVATE","PROTECTED","PROTOCOL","OBJECTNAME","CLASS","ALIAS", -"OBJC_STRING","')'","';'","'}'","'~'","'!'","','","'{'","']'","program","extdefs", -"@1","@2","extdef","datadef","fndef","@3","@4","@5","@6","@7","@8","identifier", -"unop","expr","exprlist","nonnull_exprlist","unary_expr","@9","cast_expr","expr_no_commas", -"primary","@10","string","objc_string","xdecls","lineno_datadecl","datadecls", -"datadecl","lineno_decl","decls","setspecs","decl","typed_declspecs","reserved_declspecs", -"declmods","typed_typespecs","reserved_typespecquals","typespec","typespecqual_reserved", -"initdecls","notype_initdecls","maybeasm","initdcl","@11","notype_initdcl","@12", -"maybe_attribute","attribute_list","attrib","init","initlist","nested_function", -"@13","notype_nested_function","@14","declarator","after_type_declarator","parm_declarator", -"notype_declarator","structsp","@15","@16","@17","@18","maybecomma","maybecomma_warn", -"component_decl_list","component_decl_list2","component_decl","components","component_declarator", -"enumlist","enumerator","typename","absdcl","nonempty_type_quals","type_quals", -"absdcl1","stmts","xstmts","errstmt","pushlevel","maybe_label_decls","label_decls", -"label_decl","compstmt_or_error","compstmt","simple_if","if_prefix","do_stmt_start", -"@19","save_filename","save_lineno","lineno_labeled_stmt","lineno_stmt_or_label", -"stmt_or_label","stmt","@20","@21","@22","@23","@24","@25","@26","all_iter_stmt", -"all_iter_stmt_simple","@27","label","maybe_type_qual","xexpr","asm_operands", -"nonnull_asm_operands","asm_operand","asm_clobbers","parmlist","@28","parmlist_1", -"@29","parmlist_2","parms","parm","parmlist_or_identifiers","@30","parmlist_or_identifiers_1", -"identifiers","identifiers_or_typenames","objcdef","identifier_list","classdecl", -"aliasdecl","classdef","@31","@32","@33","@34","@35","@36","@37","@38","@39", -"protocoldef","@40","protocolrefs","ivar_decl_list","visibility_spec","ivar_decls", -"ivar_decl","ivars","ivar_declarator","methoddef","@41","@42","@43","@44","@45", -"@46","methodprotolist","@47","methodprotolist2","@48","semi_or_error","methodproto", -"@49","@50","@51","@52","methoddecl","optarglist","myxdecls","mydecls","mydecl", -"myparms","myparm","optparmlist","@53","unaryselector","keywordselector","selector", -"reservedwords","keyworddecl","messageargs","keywordarglist","keywordexpr","keywordarg", -"receiver","objcmessageexpr","@54","@55","selectorarg","keywordnamelist","keywordname", -"objcselectorexpr","objcprotocolexpr","objcencodeexpr","" -}; -#endif - -static const short yyr1[] = { 0, - 85, 85, 87, 86, 88, 86, 89, 89, 89, 89, - 90, 90, 90, 90, 90, 90, 90, 90, 92, 93, - 91, 91, 94, 95, 91, 91, 96, 97, 91, 91, - 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, - 99, 100, 101, 101, 102, 102, 103, 103, 104, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 105, 105, - 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, - 107, 107, 107, 107, 108, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 109, 109, 110, - 110, 111, 111, 111, 112, 113, 113, 113, 113, 114, - 114, 114, 114, 115, 116, 116, 116, 116, 117, 118, - 118, 118, 118, 118, 118, 119, 119, 120, 120, 120, - 121, 121, 121, 121, 122, 122, 123, 123, 124, 124, - 124, 124, 124, 124, 124, 125, 125, 125, 126, 126, - 127, 127, 128, 128, 130, 129, 129, 132, 131, 131, - 133, 133, 134, 134, 135, 135, 135, 135, 136, 136, - 136, 136, 136, 137, 137, 137, 137, 139, 138, 141, - 140, 142, 142, 143, 143, 143, 143, 143, 143, 143, - 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, - 145, 147, 146, 146, 146, 148, 146, 146, 146, 149, - 146, 150, 146, 146, 151, 151, 152, 152, 153, 153, - 154, 154, 154, 154, 155, 155, 155, 155, 155, 156, - 156, 157, 157, 157, 158, 158, 159, 159, 160, 160, - 161, 161, 162, 162, 163, 163, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 165, 165, 165, 166, 166, - 167, 168, 169, 169, 170, 170, 171, 172, 172, 173, - 173, 173, 173, 174, 174, 175, 177, 176, 178, 179, - 180, 180, 181, 182, 182, 183, 183, 183, 184, 183, - 183, 183, 185, 186, 183, 183, 183, 187, 188, 189, - 183, 190, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 191, 193, 192, 194, 194, 194, - 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, - 200, 200, 202, 201, 203, 204, 203, 203, 205, 205, - 205, 205, 206, 206, 207, 207, 207, 207, 207, 209, - 208, 210, 210, 211, 211, 212, 212, 213, 213, 213, - 213, 213, 213, 214, 214, 215, 216, 218, 219, 217, - 220, 217, 221, 222, 217, 223, 217, 224, 217, 217, - 225, 217, 217, 226, 217, 217, 228, 227, 229, 229, - 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, - 233, 234, 234, 234, 235, 235, 235, 237, 238, 239, - 236, 240, 241, 242, 236, 243, 244, 243, 245, 245, - 245, 246, 245, 247, 247, 249, 250, 248, 251, 252, - 248, 253, 253, 253, 253, 254, 254, 255, 255, 256, - 256, 256, 256, 257, 257, 257, 258, 258, 259, 259, - 259, 260, 260, 261, 260, 262, 263, 263, 264, 264, - 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 266, 266, 266, 266, 267, 267, 268, - 268, 269, 270, 270, 271, 271, 273, 274, 272, 275, - 275, 276, 276, 277, 277, 278, 279, 280 -}; - -static const short yyr2[] = { 0, - 0, 1, 0, 2, 0, 3, 1, 1, 1, 5, - 3, 4, 4, 2, 2, 2, 2, 1, 0, 0, - 7, 4, 0, 0, 7, 4, 0, 0, 6, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 3, 1, 2, 0, 3, - 2, 2, 2, 4, 2, 4, 2, 2, 1, 4, - 7, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 5, 3, 3, 1, - 1, 1, 3, 3, 0, 4, 4, 4, 3, 3, - 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, - 2, 0, 1, 2, 3, 1, 1, 2, 2, 4, - 4, 2, 2, 3, 1, 1, 2, 2, 0, 4, - 4, 3, 3, 2, 2, 2, 3, 0, 2, 2, - 1, 1, 2, 2, 2, 3, 0, 2, 1, 1, - 1, 2, 2, 4, 4, 1, 1, 1, 1, 3, - 1, 3, 0, 4, 0, 6, 3, 0, 6, 3, - 0, 6, 1, 3, 1, 4, 4, 8, 1, 2, - 3, 4, 1, 1, 3, 3, 5, 0, 3, 0, - 3, 1, 1, 3, 3, 4, 3, 3, 1, 1, - 3, 4, 3, 3, 1, 3, 3, 3, 4, 3, - 1, 0, 6, 4, 2, 0, 6, 4, 2, 0, - 7, 0, 6, 2, 0, 1, 0, 1, 1, 2, - 0, 3, 2, 4, 3, 1, 3, 1, 1, 1, - 3, 4, 6, 5, 1, 3, 1, 3, 2, 2, - 0, 1, 1, 2, 0, 2, 3, 3, 2, 3, - 4, 3, 2, 3, 2, 1, 2, 2, 0, 1, - 2, 0, 0, 1, 1, 2, 3, 1, 2, 2, - 6, 5, 5, 2, 2, 4, 0, 4, 0, 0, - 3, 4, 3, 1, 1, 1, 1, 2, 0, 4, - 1, 3, 0, 0, 7, 5, 2, 0, 0, 0, - 12, 0, 6, 2, 2, 2, 3, 6, 8, 10, - 12, 3, 4, 1, 1, 0, 6, 3, 5, 2, - 2, 0, 1, 0, 1, 0, 1, 1, 3, 4, - 1, 3, 0, 2, 2, 0, 4, 2, 0, 1, - 1, 3, 1, 3, 2, 2, 2, 2, 2, 0, - 2, 1, 2, 1, 3, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 4, 0, 0, 10, - 0, 6, 0, 0, 12, 0, 8, 0, 6, 2, - 0, 8, 4, 0, 9, 5, 0, 6, 0, 3, - 3, 1, 1, 1, 1, 0, 3, 2, 3, 3, - 1, 0, 1, 3, 1, 3, 2, 0, 0, 0, - 7, 0, 0, 0, 7, 0, 0, 2, 1, 1, - 2, 0, 3, 1, 1, 0, 0, 5, 0, 0, - 5, 4, 1, 5, 2, 0, 2, 0, 1, 1, - 1, 2, 2, 4, 2, 2, 1, 3, 1, 1, - 1, 0, 2, 0, 3, 1, 1, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 6, 3, 5, 2, 1, 1, 1, - 2, 1, 3, 2, 1, 1, 0, 0, 6, 1, - 1, 1, 2, 2, 1, 4, 4, 4 -}; - -static const short yydefact[] = { 3, - 5, 0, 0, 0, 141, 132, 139, 131, 0, 0, - 0, 0, 0, 408, 412, 0, 0, 363, 389, 0, - 389, 0, 0, 18, 4, 8, 7, 0, 119, 119, - 128, 140, 9, 359, 360, 358, 361, 362, 6, 16, - 17, 31, 32, 34, 33, 212, 214, 221, 205, 221, - 209, 0, 0, 0, 0, 389, 380, 0, 142, 389, - 143, 364, 0, 0, 201, 245, 0, 0, 151, 0, - 15, 0, 134, 133, 14, 0, 128, 126, 0, 210, - 0, 0, 0, 202, 0, 206, 80, 81, 98, 0, - 0, 49, 0, 0, 0, 35, 37, 36, 0, 38, - 39, 0, 497, 0, 0, 0, 100, 40, 41, 0, - 0, 42, 59, 62, 45, 47, 82, 97, 93, 94, - 95, 96, 243, 0, 241, 137, 0, 241, 459, 460, - 482, 483, 479, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 480, - 481, 0, 0, 461, 409, 433, 452, 456, 462, 457, - 413, 0, 0, 371, 0, 0, 378, 0, 387, 366, - 0, 0, 0, 0, 11, 0, 30, 0, 350, 0, - 0, 161, 189, 245, 0, 190, 0, 149, 0, 182, - 183, 0, 0, 127, 130, 146, 147, 129, 148, 237, - 217, 235, 0, 0, 204, 229, 223, 119, 220, 119, - 221, 208, 221, 0, 53, 0, 55, 0, 57, 58, - 52, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 0, 324, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 91, 92, 0, 0, 43, 0, 99, 101, 144, 245, - 333, 0, 239, 242, 135, 145, 244, 137, 240, 0, - 487, 0, 436, 454, 435, 0, 458, 0, 436, 389, - 0, 368, 417, 383, 0, 396, 390, 417, 365, 367, - 246, 198, 197, 152, 153, 0, 196, 0, 200, 0, - 0, 28, 0, 279, 107, 280, 0, 160, 0, 0, - 13, 0, 22, 0, 161, 350, 0, 12, 26, 0, - 0, 218, 0, 217, 0, 279, 222, 279, 0, 0, - 0, 0, 50, 84, 83, 262, 0, 0, 496, 495, - 498, 505, 500, 0, 501, 502, 0, 0, 10, 46, - 79, 78, 325, 0, 76, 75, 73, 74, 72, 71, - 70, 68, 69, 63, 64, 65, 66, 67, 90, 89, - 0, 44, 0, 249, 0, 253, 0, 255, 0, 333, - 0, 138, 136, 0, 0, 0, 410, 453, 339, 0, - 485, 414, 376, 389, 396, 0, 0, 381, 386, 0, - 0, 0, 0, 0, 354, 340, 241, 241, 352, 0, - 341, 343, 351, 0, 199, 261, 0, 109, 104, 108, - 0, 0, 158, 188, 184, 150, 20, 157, 185, 187, - 0, 24, 238, 236, 213, 0, 224, 225, 230, 280, - 227, 203, 207, 54, 56, 270, 263, 86, 0, 60, - 0, 504, 506, 0, 503, 508, 507, 0, 87, 88, - 248, 247, 334, 254, 250, 252, 0, 0, 432, 452, - 119, 0, 441, 437, 439, 0, 0, 455, 341, 0, - 0, 373, 417, 384, 0, 372, 426, 429, 420, 0, - 119, 119, 422, 419, 396, 395, 393, 394, 379, 396, - 401, 398, 119, 119, 0, 388, 154, 338, 195, 245, - 333, 345, 346, 347, 245, 348, 349, 335, 336, 0, - 353, 0, 0, 29, 268, 105, 119, 119, 0, 0, - 0, 155, 186, 0, 211, 279, 0, 0, 0, 264, - 265, 173, 80, 0, 0, 169, 174, 215, 0, 488, - 0, 489, 490, 77, 251, 486, 434, 445, 241, 446, - 442, 443, 411, 0, 415, 396, 0, 417, 369, 0, - 0, 153, 0, 0, 0, 421, 0, 0, 402, 402, - 397, 249, 350, 0, 249, 0, 342, 344, 355, 269, - 112, 0, 113, 0, 165, 0, 163, 159, 21, 0, - 25, 231, 0, 161, 356, 0, 0, 0, 279, 0, - 116, 280, 256, 266, 170, 0, 0, 0, 0, 492, - 494, 0, 499, 0, 491, 449, 450, 451, 0, 447, - 484, 0, 377, 0, 417, 427, 430, 423, 382, 0, - 405, 399, 403, 400, 194, 191, 193, 0, 337, 0, - 0, 0, 0, 0, 156, 161, 0, 232, 267, 0, - 272, 118, 117, 0, 0, 273, 258, 280, 257, 0, - 171, 0, 176, 0, 175, 61, 493, 444, 241, 374, - 385, 0, 0, 0, 407, 0, 0, 192, 110, 111, - 0, 0, 162, 164, 234, 161, 357, 271, 0, 141, - 0, 293, 277, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 389, 389, 314, 0, 0, 114, 119, 119, - 286, 291, 0, 0, 283, 284, 287, 315, 285, 172, - 0, 448, 417, 370, 425, 424, 428, 431, 406, 404, - 166, 0, 167, 233, 0, 0, 279, 324, 0, 0, - 320, 304, 305, 306, 0, 0, 0, 323, 0, 321, - 288, 124, 0, 125, 0, 0, 275, 280, 274, 297, - 0, 177, 0, 0, 0, 0, 0, 47, 0, 0, - 0, 318, 307, 0, 312, 0, 0, 122, 153, 0, - 123, 153, 292, 279, 0, 0, 375, 0, 276, 0, - 278, 316, 298, 302, 0, 313, 0, 120, 0, 121, - 0, 290, 281, 279, 0, 0, 294, 279, 324, 279, - 319, 326, 0, 179, 181, 282, 296, 168, 279, 317, - 0, 303, 0, 0, 327, 328, 308, 295, 299, 0, - 326, 0, 0, 324, 0, 0, 309, 329, 0, 330, - 0, 0, 300, 331, 0, 310, 279, 0, 0, 301, - 311, 332, 0, 0, 0 -}; - -static const short yydefgoto[] = { 863, - 1, 2, 3, 25, 26, 27, 314, 531, 320, 534, - 181, 417, 200, 110, 353, 371, 112, 113, 218, 114, - 115, 116, 225, 117, 118, 302, 303, 304, 526, 608, - 609, 28, 718, 407, 78, 408, 125, 265, 31, 198, - 187, 68, 182, 188, 600, 69, 530, 308, 596, 597, - 547, 548, 788, 809, 791, 811, 295, 190, 626, 191, - 32, 211, 213, 203, 79, 619, 323, 82, 83, 209, - 438, 439, 201, 202, 127, 628, 128, 173, 264, 610, - 665, 305, 447, 539, 540, 541, 524, 525, 722, 723, - 724, 747, 768, 421, 769, 613, 725, 726, 794, 746, - 829, 819, 844, 857, 820, 727, 728, 818, 729, 759, - 354, 834, 835, 836, 855, 376, 377, 409, 586, 410, - 411, 412, 297, 298, 413, 414, 606, 33, 63, 34, - 35, 36, 395, 635, 283, 566, 733, 483, 286, 495, - 568, 37, 288, 59, 400, 500, 401, 505, 642, 643, - 38, 54, 273, 477, 55, 279, 481, 396, 397, 493, - 575, 737, 494, 570, 683, 571, 684, 155, 387, 474, - 475, 476, 629, 630, 275, 389, 156, 157, 158, 159, - 160, 551, 552, 621, 553, 341, 119, 227, 451, 344, - 345, 346, 120, 121, 122 -}; - -static const short yypact[] = { 95, - 112, 2755, 2755, 203,-32768,-32768,-32768,-32768, 169, 177, - 191, 33, 73,-32768,-32768, 199, 199,-32768, 89, 199, - 89, 199, 199,-32768,-32768,-32768,-32768, 181, 65, 767, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768, 40, 97, 107, 97, - 115, 2540, 2375, 2999, 2999, 194, 39, 199,-32768, 89, --32768,-32768, 26, 199,-32768,-32768, 181, 104,-32768, 1688, --32768, 59,-32768,-32768,-32768, 181,-32768, 626, 199,-32768, - 148, 121, 373,-32768, 137,-32768,-32768,-32768,-32768, 2574, - 2629,-32768, 2540, 2540, 199,-32768,-32768,-32768, 2540,-32768, --32768, 1279,-32768, 176, 186, 215,-32768,-32768,-32768, 2540, - 207, 208,-32768,-32768, 3291, 613, 321, 256,-32768,-32768, --32768,-32768,-32768, 257, 178,-32768, 264, 3135,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768, 252, 2229,-32768,-32768,-32768, 2341, 253,-32768,-32768, --32768, 199, 199, 268, 199, 199,-32768, 45,-32768,-32768, - 199, 304, 114, 219,-32768, 59,-32768, 357,-32768, 1782, - 709, 364,-32768,-32768, 59,-32768, 246,-32768, 568, 393, - 428, 320, 1768, 626,-32768,-32768,-32768,-32768,-32768, 387, - 337,-32768, 199, 362,-32768,-32768,-32768, 434, 367, 602, - 97,-32768, 97, 1279,-32768, 1279,-32768, 2540,-32768,-32768, --32768,-32768, 385, 403, 408, 418, 2430, 3028, 2229, 199, --32768, 381, 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, - 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, 2540, --32768,-32768, 199, 199, 2540, 2540,-32768,-32768,-32768,-32768, - 178, 1862,-32768, 454, 571,-32768,-32768,-32768,-32768, 2229, --32768, 423, 430, 500,-32768, 253,-32768, 267, 430, 89, - 442,-32768, 467, 455, 460,-32768,-32768, 467,-32768,-32768, --32768, 428,-32768,-32768, 513, 535,-32768, 1871,-32768, 464, - 471,-32768, 69, 88,-32768,-32768, 490, 515, 282, 289, --32768, 59,-32768, 709, 364,-32768, 1922,-32768,-32768, 709, - 2540, 199, 474, 337, 480,-32768,-32768,-32768, 479, 481, - 485, 486,-32768,-32768,-32768, 487, 488, 2260,-32768,-32768, --32768,-32768, 529, 493, 3028,-32768, 494, 511,-32768, 3291, - 3291, 3291,-32768, 550, 1253, 1411, 1491, 575, 703, 1569, - 678, 319, 319, 433, 433,-32768,-32768,-32768,-32768,-32768, - 514, 208, 509, 376, 336,-32768, 2883,-32768, 517,-32768, - 1982,-32768, 571, 520, 3067, 756,-32768,-32768, 3152, 2229, --32768,-32768, 524, 89,-32768, 534, 2831,-32768,-32768, 363, - 2707, 546, 52, 540,-32768,-32768, 360, 3124,-32768, 557, - 347,-32768,-32768, 241,-32768,-32768, 56,-32768,-32768,-32768, - 3217, 551,-32768, 393,-32768,-32768,-32768, 598,-32768,-32768, - 528,-32768, 3291,-32768,-32768, 558,-32768, 560,-32768,-32768, - 560,-32768,-32768,-32768,-32768,-32768, 610,-32768, 1603,-32768, - 3096,-32768,-32768, 529,-32768,-32768,-32768, 2540,-32768,-32768, - 454,-32768,-32768,-32768,-32768,-32768, 561, 199,-32768, 2341, - 566, 2901,-32768,-32768, 3217, 1796, 56,-32768, 567, 576, - 56,-32768, 467,-32768, 378,-32768,-32768,-32768,-32768, 181, - 65, 767, 37,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768, 2454, 570,-32768,-32768,-32768,-32768,-32768, - 407, 456, 428,-32768,-32768, 428,-32768,-32768,-32768, 3200, --32768, 649, 408,-32768,-32768,-32768, 578, 2920, 651, 1679, - 56,-32768,-32768, 56,-32768,-32768, 349, 199, 874, 610, --32768,-32768, 618, 1360, 620, 3291,-32768, 580, 2540, 625, - 582, 3096,-32768, 1332,-32768,-32768,-32768,-32768, 360,-32768, --32768,-32768,-32768, 199,-32768,-32768, 612, 467,-32768, 2999, - 2999, 216, 59, 181, 2850,-32768, 457, 2724, 355, 355, --32768, 227,-32768, 2042, 405, 2883,-32768,-32768,-32768,-32768, --32768, 59,-32768, 181, 619, 249,-32768,-32768,-32768, 1679, --32768,-32768, 2540, 53,-32768, 353, 451, 793, 603, 955, --32768,-32768,-32768,-32768,-32768, 187, 1679, 1441, 604, 208, --32768, 2540,-32768, 625,-32768, 456, 428,-32768, 361,-32768, --32768, 476,-32768, 621, 467,-32768,-32768,-32768,-32768, 2540, - 645, 606,-32768, 606, 456,-32768,-32768, 607,-32768, 382, - 391, 335, 609, 651,-32768, 3206, 2540,-32768,-32768, 199, --32768,-32768,-32768, 1036, 611,-32768,-32768,-32768,-32768, 2124, --32768, 1522,-32768, 653,-32768,-32768,-32768,-32768, 360,-32768, --32768, 637, 63, 63, 3291, 2540, 355,-32768,-32768,-32768, - 283, 630,-32768,-32768,-32768, 3206,-32768,-32768, 2205, 663, - 648,-32768,-32768, 652, 658, 2540, 670, 633, 642, 2485, - 141, 726, 189, 212,-32768, 696, 660,-32768, 661, 2931, --32768, 720, 1117, 64,-32768,-32768,-32768,-32768,-32768,-32768, - 1679,-32768, 467,-32768,-32768,-32768,-32768,-32768, 3291,-32768, --32768, 732,-32768,-32768, 2540, 681,-32768, 2540, 2540, 3255, --32768,-32768,-32768,-32768, 664, 2540, 666,-32768, 685,-32768, --32768,-32768, 59,-32768, 181, 1198,-32768,-32768,-32768,-32768, - 2540,-32768, 694, 677, 687, 2540, 748, 443, 689, 698, - 2540,-32768,-32768, 700,-32768, 2540, 396,-32768, 93, 399, --32768, 42,-32768,-32768, 2205, 699,-32768, 775,-32768, 708, --32768,-32768,-32768,-32768, 3273,-32768, 41,-32768, 408,-32768, - 408,-32768,-32768,-32768, 711, 710,-32768,-32768, 2540,-32768, --32768, 777, 715,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 725,-32768, 749, 77, 741,-32768,-32768,-32768,-32768, 2540, - 777, 752, 777, 2540, 754, 140,-32768,-32768, 755,-32768, - 535, 758,-32768, 321, 322,-32768,-32768, 760, 535,-32768, --32768, 321, 826, 833,-32768 -}; - -static const short yypgoto[] = {-32768, --32768,-32768,-32768, 843, -353,-32768,-32768,-32768,-32768,-32768, --32768,-32768, -5,-32768, -52,-32768, -230, 444,-32768, -22, - 60, 99,-32768, -272,-32768, -57, 547,-32768,-32768, 243, --32768, -21,-32768, 17, 773, 19, -55, 587, -17, -214, - -545, -69, -186, -124,-32768,-32768,-32768, -289,-32768, 202, - -487, 313,-32768,-32768,-32768,-32768, -58, -131, -362, -18, - -38,-32768,-32768,-32768,-32768,-32768, 538, 10,-32768,-32768, - 531, 327, 665, 542, -46, -86, -54, -154, -228, 258, --32768, -271,-32768,-32768,-32768, 330, -381, -209,-32768,-32768, --32768,-32768, -113, -406, -680, -505,-32768, 109,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 110,-32768, - -693, 43,-32768, 47,-32768, 527,-32768, -339,-32768, 521, - 522, 392, -270,-32768,-32768,-32768,-32768,-32768, 855,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768, -19, -347,-32768, 414,-32768, 339, 229, --32768,-32768,-32768,-32768,-32768,-32768,-32768, -257,-32768,-32768, --32768, 233, 427,-32768,-32768,-32768,-32768, -28, 643,-32768, --32768, 446,-32768, 247, 458,-32768, 548, 552, -134,-32768, - -122,-32768,-32768, 305, 379,-32768,-32768,-32768,-32768,-32768, --32768, 591,-32768,-32768,-32768 -}; - - -#define YYLAST 3344 - - -static const short yytable[] = { 111, - 124, 61, 315, 47, 49, 51, 192, 72, 76, 70, - 56, 57, 77, 189, 60, 337, 62, 64, 29, 29, - 30, 30, 276, 403, 372, 428, 161, 208, 210, 309, - 402, 418, 375, 537, 277, 126, 164, 463, 263, 199, - 169, 269, 598, 489, 512, 429, 650, 485, 174, 224, - 382, 294, 62, 310, 779, 226, 523, 193, 172, 85, - 257, 65, 183, 735, 770, 126, 777, 306, 178, 301, - 219, 220, -106, -106, -106, -106, 222, 165, -106, 822, - -106, -106, -106, 307, 126, 487, 488, 231, -103, 221, - 287, 657, 52, 343, -1, 563, -106, 419, 166, 565, - -418, 179, 180, 170, 669, 374, 272, 171, 315, 184, - 268, -2, 655, 812, 473, 841, 65, 823, 185, 178, - 291, 167, 80, 771, -180, 831, 171, 300, 507, 673, - 675, 186, 53, 826, 58, 126, -106, 830, 336, 832, - 736, -106, 71, 42, 43, 461, 271, 577, 838, 599, - 849, -106, 601, 842, 292, 199, 280, 281, 669, 284, - 285, 224, 81, 224, 66, 289, 174, 331, 382, 332, - -103, 42, 43, 67, 340, -178, 860, 424, 851, 42, - 43, 175, 347, 65, 675, 176, 326, 426, 328, 84, - 306, 756, 268, 42, 43, 333, 126, 86, 126, 205, - 306, 42, 43, 373, 562, 670, 306, 204, 44, 379, - 454, 126, 440, 45, 440, 212, 852, 787, 632, 645, - 329, 638, 330, 384, 348, 567, 199, -34, 260, 65, - 509, 66, 162, 291, 58, 228, 44, 261, 262, 58, - 67, 45, 178, 772, 44, 229, 649, 369, 370, 45, - -33, 46, 126, 163, 42, 43, 427, 58, 44, 48, - 393, 699, 432, 45, 431, 671, 44, 611, 672, 42, - 43, 45, 391, 50, 230, 179, 180, 510, 179, 180, - 40, 41, 375, 232, 65, 183, 511, 262, 291, 233, - 292, 278, 350, 351, 352, 293, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 634, 270, 646, 590, 658, 450, 550, 521, 620, 44, - 514, 517, 522, 311, 45, 653, 390, 312, 467, 257, - 654, 258, 184, 259, 44, 276, 662, 691, 667, 45, - 266, 185, 692, 480, 199, 503, 504, 277, 316, 317, - 282, 65, 183, 461, 186, 582, 461, 65, 183, 741, - 585, 795, 65, 509, 742, 425, 695, 246, 247, 248, - 249, 250, 126, 206, 484, 490, 5, 682, 7, 123, - 433, 290, 291, 126, 9, 10, 11, 603, 513, 516, - 77, 620, 667, 640, 307, 380, 381, 318, 858, 184, - 13, 176, 471, 859, 472, 184, 744, 65, 185, 65, - 510, 291, 462, 491, 185, 492, 296, 624, 322, 511, - 262, 186, 440, 321, 519, 612, 260, 186, 520, 325, - 659, 496, 497, 498, 660, 261, 262, 527, 678, 528, - 19, 499, 679, 545, 327, 21, 496, 497, 498, 559, - 207, -219, 316, 317, 77, 515, 569, 515, 349, 689, - 721, 334, 556, 312, 511, 262, 511, 262, 690, 573, - 574, 572, 176, 808, 77, 773, 810, 312, 604, 335, - 176, 579, 580, 248, 249, 250, 268, 179, 180, 721, - 336, 471, 174, 472, 338, 612, 668, 251, 252, 385, - 253, 254, 255, 256, 192, 592, 594, 386, 546, 388, - 77, -226, -226, 380, 381, 583, 584, 554, 394, 802, - 641, 641, 503, 504, 651, 496, 497, 498, 416, 661, - -416, 648, 605, 215, 217, 639, 399, 398, 545, 178, - 627, 636, 637, 89, 496, 497, 498, 415, 416, 422, - 668, 423, 435, 490, 680, 572, 437, 442, 631, 443, - 126, 444, 445, 292, 448, 446, 292, 452, 313, 453, - 456, -19, -19, -19, -19, 572, 196, 197, 854, -19, - -19, -19, 9, 10, 11, 721, 862, 457, 458, 546, - 459, 491, 460, 492, 178, -19, 468, 486, -153, 824, - 464, 825, 315, 546, -153, 5, 482, 7, 267, 506, - 529, 533, 674, 9, 10, 11, 508, 717, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 641, 13, - 195, 196, 197, 518, 532, -19, 535, 9, 10, 11, - -19, 536, 538, 558, 555, -153, 717, 581, 520, -153, - -19, 589, 564, 595, 697, 591, -31, 755, 617, 546, - 627, 618, 656, 622, 716, 623, 674, 251, 252, 19, - 253, 254, 255, 256, 21, 633, 546, 546, 652, -228, - -228, -259, 676, 686, 681, 693, 719, 687, 720, 698, - 688, 731, 775, 716, 61, 790, 780, 763, 765, 685, - 734, -32, 77, 784, 789, 757, 743, 745, 751, 301, - 752, 748, -279, -279, -279, -279, 696, 749, 796, 753, - -279, -279, -279, 800, 244, 245, 246, 247, 248, 249, - 250, 546, 758, 807, 760, 766, -279, 761, 762, 774, - 776, 783, 717, 785, 786, 739, 792, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 301, 797, 798, 5, - 6, 7, 8, 799, 801, 750, 803, 9, 10, 11, - 5, 73, 7, 74, 804, 815, -279, 806, 9, 10, - 11, -279, 816, 13, 817, 833, 828, 845, 827, 716, - 546, -102, 837, 301, 13, -115, -115, -115, -115, -115, - -115, -115, 839, -115, -115, -115, -115, -115, 840, -115, - -115, -115, -115, -115, -115, -115, -115, -115, -115, -115, - -115, -115, 843, 19, -115, 864, -115, -115, 21, 847, - 850, 853, 865, -115, 19, 856, -115, 861, -438, 21, - 805, -115, -115, -115, 75, 39, 778, -115, -115, 194, - 420, 663, -115, -115, 383, 694, 616, -115, 441, -115, - -115, 436, 602, 434, -115, -115, 664, 324, -115, 614, - -115, -115, -115, -115, 607, -115, -279, -279, -279, -279, - -279, -279, -279, 846, -279, -279, -279, -279, -279, 848, - -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, - -279, -279, -279, 813, 814, -279, 465, -279, -279, 478, - 479, 588, 168, 578, -279, 740, 738, -279, 644, 576, - 561, 392, -279, -279, -279, 732, 677, 557, -279, -279, - 625, 0, 469, -279, -279, 455, 470, 0, -279, 0, - -279, -279, 0, 0, 0, -279, -279, 0, 0, -279, - 0, -279, 0, -279, -279, 301, -279, -279, -279, 0, - 0, 0, -279, -279, 0, -279, 0, 0, 0, -279, - 0, -279, -279, -279, -279, -279, -279, -279, -279, -279, - -279, -279, 0, -279, 0, 0, -279, 0, -279, -279, - 0, 0, 0, 0, 0, -279, 0, 0, -279, 0, - 0, 0, 0, -279, -279, -279, 0, 0, 0, -279, - -279, 0, 0, 0, -279, -279, 0, 0, 0, -279, - 0, -279, -279, 0, 0, 0, -279, -279, 0, 0, - -279, 0, -279, 666, -279, -279, 301, -279, -279, -279, - 0, 0, 0, -279, -279, 0, -279, 0, 0, 0, - -279, 0, -279, -279, -279, -279, -279, -279, -279, -279, - -279, -279, -279, 0, -279, 0, 0, -279, 0, -279, - -279, 0, 0, 0, 0, 0, -279, 0, 0, -279, - 0, 0, 0, 0, -279, -279, -279, 0, 0, 0, - -279, -279, 0, 0, 0, -279, -279, 0, 0, 0, - -279, 0, -279, -279, 0, 0, 0, -279, -279, 0, - 0, -279, 0, -279, -260, -279, -279, 767, -279, -279, - -279, 0, 0, 0, -279, -279, 0, -279, 0, 0, - 0, -279, 0, -279, -279, -279, -279, -279, -279, -279, - -279, -279, -279, -279, 0, -279, 0, 0, -279, 0, - -279, -279, 0, 0, 0, 0, 0, -279, 0, 0, - -279, 0, 0, 0, 0, -279, -279, -279, 0, 0, - 0, -279, -279, 0, 0, 0, -279, -279, 0, 0, - 0, -279, 0, -279, -279, 0, 0, 0, -279, -279, - 0, 0, -279, 0, -279, 0, -279, -279, 793, -279, - -289, -289, 0, 0, 0, -289, -289, 0, -289, 0, - 0, 0, -289, 0, -289, -289, -289, -289, -289, -289, - -289, -289, -289, -289, -289, 0, -289, 0, 0, -289, - 0, -289, -289, 0, 0, 0, 0, 0, -289, 0, - 0, -289, 0, 0, 0, 0, -289, -289, -289, 0, - 0, 0, -289, -289, 0, 0, 0, -289, -289, 0, - 0, 0, -289, 0, -289, -289, 0, 0, 0, -289, - -289, 0, 0, -289, 0, -289, 0, -289, -289, 223, - -289, 87, 5, 0, 7, 123, 88, 89, 0, 90, - 9, 10, 11, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 13, 91, 0, 0, - 92, 0, 93, 94, 0, 0, 0, 0, 0, 95, - 0, 0, 96, 0, 0, 0, 0, 97, 98, 99, - 0, 0, 0, 100, 101, 0, 0, 0, 102, 103, - 0, 0, 0, 104, 0, 105, 19, 0, 0, 0, - 106, 21, 0, 0, 107, 0, 0, 0, 108, 109, - 542, -85, 543, 43, 0, 0, 0, 88, 89, 236, - 90, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 0, 0, 0, 91, 0, - 0, 92, 0, 93, 94, 0, 0, 0, 0, 0, - 95, 0, 0, 96, 0, 0, 0, 0, 97, 98, - 99, 0, 0, 0, 100, 101, 0, 0, 0, 102, - 103, 0, 0, 0, 104, 0, 105, 44, 0, 0, - 0, 106, 45, 0, 0, 107, 0, 0, 615, 108, - 109, 542, 544, 543, 43, 0, 0, 0, 88, 89, - 0, 90, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 0, 0, 0, 0, 0, 91, - 0, 0, 92, 0, 93, 94, 0, 0, 0, 0, - 0, 95, 0, 0, 96, 0, 0, 0, 0, 97, - 98, 99, 0, 0, 0, 100, 101, 0, 0, 0, - 102, 103, 0, 0, 0, 104, 0, 105, 44, 0, - 0, 0, 106, 45, 0, 0, 107, 0, 0, -216, - 108, 109, 542, 544, 543, 43, 0, 0, 0, 88, - 89, 0, 90, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 0, 0, 0, 0, 0, 0, - 91, 0, 0, 92, 0, 93, 94, 0, 0, 0, - 0, 0, 95, 0, 0, 96, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 100, 101, 0, 0, - 0, 102, 103, 0, 0, 0, 104, 0, 105, 44, - 0, 0, 0, 106, 45, 0, 0, 107, 0, 0, - 730, 108, 109, 542, 544, 543, 43, 0, 0, 0, - 88, 89, 0, 90, 243, 244, 245, 246, 247, 248, - 249, 250, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 91, 0, 0, 92, 0, 93, 94, 0, 0, - 0, 0, 0, 95, 0, 0, 96, 0, 0, 0, - 0, 97, 98, 99, 0, 0, 0, 100, 101, 0, - 0, 0, 102, 103, 0, 0, 0, 104, 0, 105, - 44, 0, 0, 0, 106, 45, 0, 0, 107, 542, - 0, 87, 108, 109, 0, 544, 88, 89, 177, 90, - 0, -27, -27, -27, -27, 0, 0, 0, 0, -27, - -27, -27, 0, 0, 0, 0, 0, 91, 0, 0, - 92, 0, 93, 94, 178, -27, 0, 0, -153, 95, - 0, 0, 96, 0, -153, 0, 0, 97, 98, 99, - 0, 0, 0, 100, 101, 0, 0, 0, 102, 103, - 0, 0, 0, 104, 0, 105, 0, 179, 180, 0, - 106, 0, 0, 0, 107, -27, 0, 0, 108, 109, - -27, 544, 0, 0, 0, -153, 0, 0, 319, -153, - -27, -23, -23, -23, -23, 0, 0, 0, 0, -23, - -23, -23, 0, 0, 87, 0, 0, 0, 0, 88, - 89, 0, 90, 0, 178, -23, 301, 0, -153, -440, - -440, -440, -440, 0, -153, 0, 0, -440, -440, -440, - 91, 0, 0, 92, 0, 93, 94, 0, 0, 0, - 0, 0, 95, -440, 0, 96, 0, 179, 180, 0, - 97, 98, 99, 0, 0, -23, 100, 101, 0, 0, - -23, 102, 103, 0, 0, -153, 104, 0, 105, -153, - -23, 0, 0, 106, 0, 0, 0, 107, 0, 0, - 0, 108, 109, -440, 87, 299, 0, 0, -440, 88, - 89, 404, 90, 405, 5, 6, 7, 8, -440, 0, - 406, 0, 9, 10, 11, 0, 0, 0, 0, 0, - 91, 0, 0, 92, 0, 93, 94, 0, 13, 0, - 0, 0, 95, 0, 0, 96, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 100, 101, 0, 0, - 0, 102, 103, 0, 87, 0, 104, 0, 105, 88, - 89, 0, 90, 106, 0, 0, 0, 107, 19, 0, - 0, 108, 109, 21, 0, 378, 0, -339, 0, 0, - 91, 0, 0, 92, 0, 93, 94, 0, 0, 0, - 0, 0, 95, 0, 0, 96, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 100, 101, 0, 0, - 0, 102, 103, 0, 87, 0, 104, 0, 105, 88, - 89, 0, 90, 106, 0, 0, 0, 107, 0, 0, - 0, 108, 109, 0, 0, 430, 0, 0, 0, 0, - 91, 0, 0, 92, 0, 93, 94, 0, 0, 0, - 0, 0, 95, 0, 0, 96, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 100, 101, 0, 0, - 0, 102, 103, 0, 87, 0, 104, 0, 105, 88, - 89, 0, 90, 106, 0, 0, 0, 107, 0, 0, - 0, 108, 109, 0, 0, 466, 0, 0, 0, 0, - 91, 0, 0, 92, 0, 93, 94, 0, 0, 0, - 0, 0, 95, 0, 0, 96, 0, 0, 0, 0, - 97, 98, 99, 0, 0, 0, 100, 101, 0, 0, - 0, 102, 103, 0, 0, 0, 104, 0, 105, 0, - 0, 0, 0, 106, 0, 0, 0, 107, 0, 0, - 0, 108, 109, 0, 0, 647, 543, 700, 6, 7, - 8, 88, 89, 0, 90, 9, 10, 11, 701, 0, - 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, - 712, 13, 91, 0, 0, 92, 0, 93, 94, 0, - 0, 0, 0, 0, 95, 0, 0, 96, 0, 0, - 0, 0, 97, 98, 99, 0, 0, 0, 100, 101, - 0, 0, 0, 102, 103, 0, 0, 0, 104, 0, - 105, 713, 0, 0, 0, 106, 714, 0, 0, 107, - 0, 715, 0, 108, 109, 0, 336, 543, 43, 0, - 0, 0, 88, 89, 0, 90, 0, 0, 0, 701, - 0, 702, 703, 704, 705, 706, 707, 708, 709, 710, - 711, 712, 5, 91, 7, 123, 92, 0, 93, 94, - 9, 10, 11, 0, 0, 95, 0, 0, 96, 0, - 0, 0, 0, 97, 98, 99, 13, 0, 0, 100, - 101, 0, 87, 0, 102, 103, 0, 88, 89, 104, - 90, 105, 44, 0, 0, 0, 106, 45, 0, 0, - 107, 0, 715, 0, 108, 109, 0, 336, 91, 0, - 0, 92, 0, 93, 94, 0, 19, 0, 0, 0, - 95, 21, 0, 96, 0, 0, 0, 0, 97, 98, - 99, 0, 0, 0, 100, 101, 0, 0, 0, 102, - 103, 0, 0, 0, 104, 0, 105, 0, 0, 0, - 0, 106, 0, 0, 0, 107, 0, 0, 0, 108, - 109, 0, 449, 129, 130, 0, 131, 132, 0, 0, - 0, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 0, 0, 0, 0, 0, 0, 0, 87, 5, 152, - 7, 123, 88, 89, 0, 90, 9, 10, 11, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13, 91, 0, 0, 92, 0, 93, 94, - 0, 0, 0, 154, 0, 95, 0, 0, 96, 0, - 0, 0, 274, 97, 98, 99, 0, 0, 0, 100, - 101, 0, 87, 0, 102, 103, 0, 88, 89, 104, - 90, 105, 19, 0, 0, 0, 106, 21, 0, 0, - 107, 0, 0, 0, 108, 109, 0, 5, 91, 7, - 267, 92, 0, 93, 94, 9, 10, 11, 0, 0, - 95, 0, 0, 96, 0, 0, 0, 0, 97, 98, - 99, 13, 0, 0, 100, 101, 0, 87, 0, 102, - 103, 0, 88, 89, 104, 90, 105, 339, 0, 0, - 0, 106, 0, 0, 0, 107, 0, 0, 0, 108, - 109, 0, 0, 91, 0, 0, 92, 0, 93, 94, - 0, 19, 0, 0, 0, 95, 21, 0, 96, 0, - 0, 0, 0, 97, 98, 99, 0, 0, 0, 100, - 101, 0, 87, 0, 102, 103, 0, 88, 89, 104, - 90, 105, 0, 0, 0, 0, 106, 0, 0, 0, - 107, 0, 754, 0, 108, 109, 0, 0, 91, 0, - 0, 92, 0, 93, 94, 0, 87, 0, 0, 0, - 95, 88, 89, 96, 90, 0, 0, 0, 97, 98, - 99, 0, 0, 0, 100, 101, 0, 0, 0, 102, - 103, 0, 91, 0, 104, 92, 105, 93, 94, 0, - 0, 106, 0, 0, 95, 107, 0, 96, 0, 108, - 109, 0, 97, 98, 99, 0, 0, 0, 100, 101, - 0, 87, 0, 214, 103, 0, 88, 89, 104, 90, - 105, 0, 0, 0, 0, 106, 0, 0, 0, 107, - 0, 0, 0, 108, 109, 0, 0, 91, 0, 0, - 92, 0, 93, 94, 0, 0, 0, 0, 0, 95, - 0, 0, 96, 0, 0, 0, 0, 97, 98, 99, - 0, 0, 0, 100, 101, 0, 0, 0, 216, 103, - 0, 0, 0, 104, 0, 105, 0, 0, 0, 0, - 106, 0, 0, 0, 107, 0, 0, 501, 108, 109, - 5, 0, 7, 123, 0, 0, 0, 0, 9, 10, - 11, 0, 0, 0, 501, 0, 0, 5, 0, 7, - 123, 0, 0, 0, 13, 9, 10, 11, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13, 0, 0, 0, 4, 0, -119, 5, 6, - 7, 8, 0, 0, 0, 0, 9, 10, 11, 0, - 0, 0, 0, 0, 19, -392, -392, -392, 0, 21, - 0, 12, 13, 0, 502, -392, 0, 0, 0, 0, - 0, 19, -391, -391, -391, 0, 21, 0, 0, 0, - 0, 502, -391, 14, 15, -119, 0, 0, 0, 0, - 0, 0, 0, 0, -119, 0, 16, 17, 18, 0, - 0, 0, 19, 0, 0, 0, 20, 21, 22, 23, - 0, 4, 24, -119, 5, 6, 7, 8, 0, 0, - 0, 0, 9, 10, 11, 0, 0, 0, 0, 0, - 4, 0, -119, 5, 6, 7, 8, 0, 13, 0, - 0, 9, 10, 11, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 13, 0, 487, - 488, -119, 0, 404, 0, 0, 5, 6, 7, 8, - -119, 0, 406, 0, 9, 10, 11, 0, 19, 0, - -119, 0, 0, 21, 5, 73, 7, 74, 24, -119, - 13, 0, 9, 10, 11, 0, 0, 19, 0, 0, - 0, 0, 21, 5, 73, 7, 74, 24, 13, 0, - 0, 9, 10, 11, 5, 73, 7, 74, 0, 0, - 0, 0, 9, 10, 11, 0, 0, 13, 0, 0, - 19, 0, 0, 0, 0, 21, 0, 0, 13, -339, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, - 0, 0, 0, 21, 0, 0, 0, 0, 560, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 21, 0, 0, 0, 0, 593, 19, 0, - 0, 129, 130, 21, 131, 132, 0, 0, 764, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 0, 0, - 129, 130, 0, 131, 132, 0, 0, 152, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 0, 153, 0, - 0, 0, 0, 0, 0, 0, 342, 0, 0, 129, - 130, 154, 131, 132, 0, 0, 0, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 0, 0, 129, 130, - 154, 131, 132, 0, 0, 152, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 0, 65, 5, 73, 7, - 74, 0, 0, 0, 549, 9, 10, 11, 5, 154, - 7, 267, 0, 0, 0, 0, 9, 10, 11, 0, - 0, 13, 0, 0, 0, 5, 6, 7, 8, 0, - 0, 406, 13, 9, 10, 11, 0, 0, 154, 0, - 0, 0, 0, 0, 515, 0, 0, 0, 0, 13, - 0, 0, 0, 511, 262, 260, 0, 0, 0, 0, - 0, 19, 0, 0, 261, 262, 21, 0, 0, 0, - 0, 0, 19, 5, 6, 7, 8, 21, 0, 587, - 0, 9, 10, 11, 0, 0, 0, 0, 0, 19, - 5, 6, 7, 8, 21, 0, 0, 13, 9, 10, - 11, 0, 0, 0, 0, 0, 307, 0, 0, 0, - 0, 234, 235, 236, 13, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 0, - 0, 0, 0, 0, 781, 0, 0, 19, 0, 0, - 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 0, 0, 0, 21, - 234, 235, 236, 782, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 234, 235, - 236, 821, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 234, 235, 236, 0, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250 -}; - -static const short yycheck[] = { 52, - 53, 21, 189, 9, 10, 11, 76, 29, 30, 28, - 16, 17, 30, 72, 20, 225, 22, 23, 2, 3, - 2, 3, 157, 296, 255, 315, 55, 83, 83, 184, - 288, 303, 261, 440, 157, 53, 56, 377, 125, 78, - 60, 128, 530, 397, 407, 316, 592, 395, 67, 102, - 265, 176, 58, 185, 748, 102, 1, 76, 64, 50, - 9, 3, 4, 1, 1, 83, 747, 181, 27, 1, - 93, 94, 4, 5, 6, 7, 99, 39, 10, 39, - 12, 13, 14, 31, 102, 49, 50, 110, 1, 95, - 46, 39, 60, 228, 0, 477, 28, 10, 60, 481, - 64, 60, 61, 78, 610, 260, 153, 82, 295, 51, - 128, 0, 600, 794, 386, 39, 3, 77, 60, 27, - 7, 83, 83, 60, 83, 819, 82, 180, 77, 617, - 618, 73, 60, 814, 46, 153, 68, 818, 83, 820, - 78, 73, 78, 3, 4, 374, 152, 495, 829, 531, - 844, 83, 534, 77, 173, 194, 162, 163, 664, 165, - 166, 214, 66, 216, 51, 171, 185, 214, 383, 216, - 83, 3, 4, 60, 227, 83, 857, 309, 39, 3, - 4, 78, 229, 3, 672, 82, 208, 312, 210, 83, - 304, 51, 210, 3, 4, 218, 214, 83, 216, 79, - 314, 3, 4, 256, 476, 612, 320, 60, 68, 262, - 345, 229, 326, 73, 328, 79, 77, 763, 566, 582, - 211, 575, 213, 270, 230, 483, 265, 39, 51, 3, - 4, 51, 39, 7, 46, 60, 68, 60, 61, 46, - 60, 73, 27, 731, 68, 60, 586, 253, 254, 73, - 39, 83, 270, 60, 3, 4, 314, 46, 68, 83, - 280, 668, 320, 73, 317, 79, 68, 539, 82, 3, - 4, 73, 278, 83, 60, 60, 61, 51, 60, 61, - 78, 79, 511, 77, 3, 4, 60, 61, 7, 82, - 309, 39, 233, 234, 235, 77, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 568, 60, 583, 523, 604, 338, 451, 77, 549, 68, - 407, 408, 82, 78, 73, 77, 60, 82, 381, 9, - 82, 76, 51, 77, 68, 470, 608, 3, 610, 73, - 77, 60, 8, 390, 383, 401, 401, 470, 60, 61, - 83, 3, 4, 582, 73, 510, 585, 3, 4, 77, - 515, 768, 3, 4, 82, 77, 656, 49, 50, 51, - 52, 53, 390, 1, 394, 397, 4, 635, 6, 7, - 321, 78, 7, 401, 12, 13, 14, 39, 407, 408, - 408, 622, 664, 39, 31, 60, 61, 78, 77, 51, - 28, 82, 386, 82, 386, 51, 696, 3, 60, 3, - 51, 7, 77, 397, 60, 397, 60, 552, 82, 60, - 61, 73, 536, 37, 78, 539, 51, 73, 82, 68, - 78, 69, 70, 71, 82, 60, 61, 421, 78, 421, - 68, 79, 82, 449, 78, 73, 69, 70, 71, 471, - 78, 79, 60, 61, 472, 51, 79, 51, 78, 78, - 670, 77, 468, 82, 60, 61, 60, 61, 78, 491, - 492, 490, 82, 78, 492, 733, 78, 82, 537, 77, - 82, 503, 504, 51, 52, 53, 504, 60, 61, 699, - 83, 475, 511, 475, 77, 609, 610, 55, 56, 77, - 58, 59, 60, 61, 574, 527, 528, 78, 449, 10, - 528, 78, 79, 60, 61, 60, 61, 458, 77, 77, - 579, 580, 578, 578, 594, 69, 70, 71, 78, 79, - 64, 584, 538, 90, 91, 79, 77, 83, 544, 27, - 559, 570, 571, 9, 69, 70, 71, 84, 78, 60, - 664, 37, 79, 575, 79, 574, 77, 79, 564, 79, - 578, 77, 77, 582, 77, 79, 585, 39, 1, 77, - 77, 4, 5, 6, 7, 594, 6, 7, 851, 12, - 13, 14, 12, 13, 14, 795, 859, 77, 39, 530, - 77, 575, 84, 575, 27, 28, 77, 64, 31, 809, - 84, 811, 789, 544, 37, 4, 83, 6, 7, 64, - 60, 84, 618, 12, 13, 14, 77, 670, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 687, 28, - 5, 6, 7, 77, 37, 68, 79, 12, 13, 14, - 73, 82, 33, 78, 84, 78, 699, 78, 82, 82, - 83, 3, 77, 3, 660, 78, 39, 710, 39, 600, - 679, 82, 603, 39, 670, 84, 672, 55, 56, 68, - 58, 59, 60, 61, 73, 64, 617, 618, 60, 78, - 79, 79, 79, 39, 64, 77, 670, 82, 670, 79, - 84, 39, 745, 699, 714, 765, 749, 719, 720, 640, - 64, 39, 720, 756, 763, 711, 77, 60, 39, 1, - 78, 60, 4, 5, 6, 7, 657, 60, 771, 78, - 12, 13, 14, 776, 47, 48, 49, 50, 51, 52, - 53, 672, 7, 786, 39, 16, 28, 78, 78, 8, - 60, 78, 795, 78, 60, 686, 765, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 1, 64, 82, 4, - 5, 6, 7, 77, 17, 706, 78, 12, 13, 14, - 4, 5, 6, 7, 77, 77, 68, 78, 12, 13, - 14, 73, 8, 28, 77, 9, 77, 840, 78, 795, - 731, 83, 78, 1, 28, 3, 4, 5, 6, 7, - 8, 9, 78, 11, 12, 13, 14, 15, 60, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 82, 68, 32, 0, 34, 35, 73, 78, - 77, 77, 0, 41, 68, 78, 44, 78, 83, 73, - 781, 49, 50, 51, 78, 3, 748, 55, 56, 77, - 304, 609, 60, 61, 268, 654, 544, 65, 328, 67, - 68, 324, 536, 322, 72, 73, 609, 203, 76, 540, - 78, 79, 80, 81, 1, 83, 3, 4, 5, 6, - 7, 8, 9, 841, 11, 12, 13, 14, 15, 843, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 795, 795, 32, 380, 34, 35, 389, - 389, 520, 58, 500, 41, 687, 684, 44, 580, 493, - 475, 279, 49, 50, 51, 679, 622, 470, 55, 56, - 552, -1, 385, 60, 61, 345, 385, -1, 65, -1, - 67, 68, -1, -1, -1, 72, 73, -1, -1, 76, - -1, 78, -1, 80, 81, 1, 83, 3, 4, -1, - -1, -1, 8, 9, -1, 11, -1, -1, -1, 15, - -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, -1, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, -1, -1, 55, - 56, -1, -1, -1, 60, 61, -1, -1, -1, 65, - -1, 67, 68, -1, -1, -1, 72, 73, -1, -1, - 76, -1, 78, 79, 80, 81, 1, 83, 3, 4, - -1, -1, -1, 8, 9, -1, 11, -1, -1, -1, - 15, -1, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, -1, 29, -1, -1, 32, -1, 34, - 35, -1, -1, -1, -1, -1, 41, -1, -1, 44, - -1, -1, -1, -1, 49, 50, 51, -1, -1, -1, - 55, 56, -1, -1, -1, 60, 61, -1, -1, -1, - 65, -1, 67, 68, -1, -1, -1, 72, 73, -1, - -1, 76, -1, 78, 79, 80, 81, 1, 83, 3, - 4, -1, -1, -1, 8, 9, -1, 11, -1, -1, - -1, 15, -1, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, -1, 29, -1, -1, 32, -1, - 34, 35, -1, -1, -1, -1, -1, 41, -1, -1, - 44, -1, -1, -1, -1, 49, 50, 51, -1, -1, - -1, 55, 56, -1, -1, -1, 60, 61, -1, -1, - -1, 65, -1, 67, 68, -1, -1, -1, 72, 73, - -1, -1, 76, -1, 78, -1, 80, 81, 1, 83, - 3, 4, -1, -1, -1, 8, 9, -1, 11, -1, - -1, -1, 15, -1, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, -1, 29, -1, -1, 32, - -1, 34, 35, -1, -1, -1, -1, -1, 41, -1, - -1, 44, -1, -1, -1, -1, 49, 50, 51, -1, - -1, -1, 55, 56, -1, -1, -1, 60, 61, -1, - -1, -1, 65, -1, 67, 68, -1, -1, -1, 72, - 73, -1, -1, 76, -1, 78, -1, 80, 81, 1, - 83, 3, 4, -1, 6, 7, 8, 9, -1, 11, - 12, 13, 14, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 28, 29, -1, -1, - 32, -1, 34, 35, -1, -1, -1, -1, -1, 41, - -1, -1, 44, -1, -1, -1, -1, 49, 50, 51, - -1, -1, -1, 55, 56, -1, -1, -1, 60, 61, - -1, -1, -1, 65, -1, 67, 68, -1, -1, -1, - 72, 73, -1, -1, 76, -1, -1, -1, 80, 81, - 1, 83, 3, 4, -1, -1, -1, 8, 9, 38, - 11, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, -1, -1, -1, 29, -1, - -1, 32, -1, 34, 35, -1, -1, -1, -1, -1, - 41, -1, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, -1, -1, -1, 60, - 61, -1, -1, -1, 65, -1, 67, 68, -1, -1, - -1, 72, 73, -1, -1, 76, -1, -1, 79, 80, - 81, 1, 83, 3, 4, -1, -1, -1, 8, 9, - -1, 11, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, -1, -1, -1, -1, -1, 29, - -1, -1, 32, -1, 34, 35, -1, -1, -1, -1, - -1, 41, -1, -1, 44, -1, -1, -1, -1, 49, - 50, 51, -1, -1, -1, 55, 56, -1, -1, -1, - 60, 61, -1, -1, -1, 65, -1, 67, 68, -1, - -1, -1, 72, 73, -1, -1, 76, -1, -1, 79, - 80, 81, 1, 83, 3, 4, -1, -1, -1, 8, - 9, -1, 11, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, -1, -1, -1, -1, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, -1, -1, -1, 65, -1, 67, 68, - -1, -1, -1, 72, 73, -1, -1, 76, -1, -1, - 79, 80, 81, 1, 83, 3, 4, -1, -1, -1, - 8, 9, -1, 11, 46, 47, 48, 49, 50, 51, - 52, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 29, -1, -1, 32, -1, 34, 35, -1, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, - -1, 49, 50, 51, -1, -1, -1, 55, 56, -1, - -1, -1, 60, 61, -1, -1, -1, 65, -1, 67, - 68, -1, -1, -1, 72, 73, -1, -1, 76, 1, - -1, 3, 80, 81, -1, 83, 8, 9, 1, 11, - -1, 4, 5, 6, 7, -1, -1, -1, -1, 12, - 13, 14, -1, -1, -1, -1, -1, 29, -1, -1, - 32, -1, 34, 35, 27, 28, -1, -1, 31, 41, - -1, -1, 44, -1, 37, -1, -1, 49, 50, 51, - -1, -1, -1, 55, 56, -1, -1, -1, 60, 61, - -1, -1, -1, 65, -1, 67, -1, 60, 61, -1, - 72, -1, -1, -1, 76, 68, -1, -1, 80, 81, - 73, 83, -1, -1, -1, 78, -1, -1, 1, 82, - 83, 4, 5, 6, 7, -1, -1, -1, -1, 12, - 13, 14, -1, -1, 3, -1, -1, -1, -1, 8, - 9, -1, 11, -1, 27, 28, 1, -1, 31, 4, - 5, 6, 7, -1, 37, -1, -1, 12, 13, 14, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, 28, -1, 44, -1, 60, 61, -1, - 49, 50, 51, -1, -1, 68, 55, 56, -1, -1, - 73, 60, 61, -1, -1, 78, 65, -1, 67, 82, - 83, -1, -1, 72, -1, -1, -1, 76, -1, -1, - -1, 80, 81, 68, 3, 84, -1, -1, 73, 8, - 9, 1, 11, 3, 4, 5, 6, 7, 83, -1, - 10, -1, 12, 13, 14, -1, -1, -1, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, 28, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, -1, 3, -1, 65, -1, 67, 8, - 9, -1, 11, 72, -1, -1, -1, 76, 68, -1, - -1, 80, 81, 73, -1, 84, -1, 77, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, -1, 3, -1, 65, -1, 67, 8, - 9, -1, 11, 72, -1, -1, -1, 76, -1, -1, - -1, 80, 81, -1, -1, 84, -1, -1, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, -1, 3, -1, 65, -1, 67, 8, - 9, -1, 11, 72, -1, -1, -1, 76, -1, -1, - -1, 80, 81, -1, -1, 84, -1, -1, -1, -1, - 29, -1, -1, 32, -1, 34, 35, -1, -1, -1, - -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, - 49, 50, 51, -1, -1, -1, 55, 56, -1, -1, - -1, 60, 61, -1, -1, -1, 65, -1, 67, -1, - -1, -1, -1, 72, -1, -1, -1, 76, -1, -1, - -1, 80, 81, -1, -1, 84, 3, 4, 5, 6, - 7, 8, 9, -1, 11, 12, 13, 14, 15, -1, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, -1, -1, 32, -1, 34, 35, -1, - -1, -1, -1, -1, 41, -1, -1, 44, -1, -1, - -1, -1, 49, 50, 51, -1, -1, -1, 55, 56, - -1, -1, -1, 60, 61, -1, -1, -1, 65, -1, - 67, 68, -1, -1, -1, 72, 73, -1, -1, 76, - -1, 78, -1, 80, 81, -1, 83, 3, 4, -1, - -1, -1, 8, 9, -1, 11, -1, -1, -1, 15, - -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 4, 29, 6, 7, 32, -1, 34, 35, - 12, 13, 14, -1, -1, 41, -1, -1, 44, -1, - -1, -1, -1, 49, 50, 51, 28, -1, -1, 55, - 56, -1, 3, -1, 60, 61, -1, 8, 9, 65, - 11, 67, 68, -1, -1, -1, 72, 73, -1, -1, - 76, -1, 78, -1, 80, 81, -1, 83, 29, -1, - -1, 32, -1, 34, 35, -1, 68, -1, -1, -1, - 41, 73, -1, 44, -1, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, -1, -1, -1, 60, - 61, -1, -1, -1, 65, -1, 67, -1, -1, -1, - -1, 72, -1, -1, -1, 76, -1, -1, -1, 80, - 81, -1, 83, 3, 4, -1, 6, 7, -1, -1, - -1, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - -1, -1, -1, -1, -1, -1, -1, 3, 4, 39, - 6, 7, 8, 9, -1, 11, 12, 13, 14, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 28, 29, -1, -1, 32, -1, 34, 35, - -1, -1, -1, 73, -1, 41, -1, -1, 44, -1, - -1, -1, 82, 49, 50, 51, -1, -1, -1, 55, - 56, -1, 3, -1, 60, 61, -1, 8, 9, 65, - 11, 67, 68, -1, -1, -1, 72, 73, -1, -1, - 76, -1, -1, -1, 80, 81, -1, 4, 29, 6, - 7, 32, -1, 34, 35, 12, 13, 14, -1, -1, - 41, -1, -1, 44, -1, -1, -1, -1, 49, 50, - 51, 28, -1, -1, 55, 56, -1, 3, -1, 60, - 61, -1, 8, 9, 65, 11, 67, 68, -1, -1, - -1, 72, -1, -1, -1, 76, -1, -1, -1, 80, - 81, -1, -1, 29, -1, -1, 32, -1, 34, 35, - -1, 68, -1, -1, -1, 41, 73, -1, 44, -1, - -1, -1, -1, 49, 50, 51, -1, -1, -1, 55, - 56, -1, 3, -1, 60, 61, -1, 8, 9, 65, - 11, 67, -1, -1, -1, -1, 72, -1, -1, -1, - 76, -1, 78, -1, 80, 81, -1, -1, 29, -1, - -1, 32, -1, 34, 35, -1, 3, -1, -1, -1, - 41, 8, 9, 44, 11, -1, -1, -1, 49, 50, - 51, -1, -1, -1, 55, 56, -1, -1, -1, 60, - 61, -1, 29, -1, 65, 32, 67, 34, 35, -1, - -1, 72, -1, -1, 41, 76, -1, 44, -1, 80, - 81, -1, 49, 50, 51, -1, -1, -1, 55, 56, - -1, 3, -1, 60, 61, -1, 8, 9, 65, 11, - 67, -1, -1, -1, -1, 72, -1, -1, -1, 76, - -1, -1, -1, 80, 81, -1, -1, 29, -1, -1, - 32, -1, 34, 35, -1, -1, -1, -1, -1, 41, - -1, -1, 44, -1, -1, -1, -1, 49, 50, 51, - -1, -1, -1, 55, 56, -1, -1, -1, 60, 61, - -1, -1, -1, 65, -1, 67, -1, -1, -1, -1, - 72, -1, -1, -1, 76, -1, -1, 1, 80, 81, - 4, -1, 6, 7, -1, -1, -1, -1, 12, 13, - 14, -1, -1, -1, 1, -1, -1, 4, -1, 6, - 7, -1, -1, -1, 28, 12, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, -1, -1, -1, 1, -1, 3, 4, 5, - 6, 7, -1, -1, -1, -1, 12, 13, 14, -1, - -1, -1, -1, -1, 68, 69, 70, 71, -1, 73, - -1, 27, 28, -1, 78, 79, -1, -1, -1, -1, - -1, 68, 69, 70, 71, -1, 73, -1, -1, -1, - -1, 78, 79, 49, 50, 51, -1, -1, -1, -1, - -1, -1, -1, -1, 60, -1, 62, 63, 64, -1, - -1, -1, 68, -1, -1, -1, 72, 73, 74, 75, - -1, 1, 78, 3, 4, 5, 6, 7, -1, -1, - -1, -1, 12, 13, 14, -1, -1, -1, -1, -1, - 1, -1, 3, 4, 5, 6, 7, -1, 28, -1, - -1, 12, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 28, -1, 49, - 50, 51, -1, 1, -1, -1, 4, 5, 6, 7, - 60, -1, 10, -1, 12, 13, 14, -1, 68, -1, - 51, -1, -1, 73, 4, 5, 6, 7, 78, 60, - 28, -1, 12, 13, 14, -1, -1, 68, -1, -1, - -1, -1, 73, 4, 5, 6, 7, 78, 28, -1, - -1, 12, 13, 14, 4, 5, 6, 7, -1, -1, - -1, -1, 12, 13, 14, -1, -1, 28, -1, -1, - 68, -1, -1, -1, -1, 73, -1, -1, 28, 77, - -1, -1, -1, -1, -1, -1, -1, -1, 68, -1, - -1, -1, -1, 73, -1, -1, -1, -1, 78, -1, - -1, -1, -1, -1, -1, -1, -1, 68, -1, -1, - -1, -1, 73, -1, -1, -1, -1, 78, 68, -1, - -1, 3, 4, 73, 6, 7, -1, -1, 78, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, -1, -1, - 3, 4, -1, 6, 7, -1, -1, 39, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, -1, 60, -1, - -1, -1, -1, -1, -1, -1, 39, -1, -1, 3, - 4, 73, 6, 7, -1, -1, -1, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, -1, -1, 3, 4, - 73, 6, 7, -1, -1, 39, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, -1, 3, 4, 5, 6, - 7, -1, -1, -1, 39, 12, 13, 14, 4, 73, - 6, 7, -1, -1, -1, -1, 12, 13, 14, -1, - -1, 28, -1, -1, -1, 4, 5, 6, 7, -1, - -1, 10, 28, 12, 13, 14, -1, -1, 73, -1, - -1, -1, -1, -1, 51, -1, -1, -1, -1, 28, - -1, -1, -1, 60, 61, 51, -1, -1, -1, -1, - -1, 68, -1, -1, 60, 61, 73, -1, -1, -1, - -1, -1, 68, 4, 5, 6, 7, 73, -1, 10, - -1, 12, 13, 14, -1, -1, -1, -1, -1, 68, - 4, 5, 6, 7, 73, -1, -1, 28, 12, 13, - 14, -1, -1, -1, -1, -1, 31, -1, -1, -1, - -1, 36, 37, 38, 28, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, - -1, -1, -1, -1, 10, -1, -1, 68, -1, -1, - -1, -1, 73, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 68, -1, -1, -1, -1, 73, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 36, 37, 38, -1, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman - - This program 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 1, or (at your option) - any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) -#include -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#include -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -#include - #pragma alloca -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#define YYLEX yylex(&yylval, &yylloc) -#else -#define YYLEX yylex(&yylval) -#endif -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (from, to, count) - char *from; - char *to; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_bcopy (char *from, char *to, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 169 "bison.simple" -int -yyparse() -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), -#ifdef YYLSP_NEEDED - &yyls1, size * sizeof (*yylsp), -#endif - &yystacksize); - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symboles being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 228 "objc-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids an empty source file"); - objc_finish (); - ; - break;} -case 2: -#line 233 "objc-parse.y" -{ - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! global_bindings_p ()) - poplevel (0, 0, 0); - objc_finish (); - ; - break;} -case 3: -#line 247 "objc-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 5: -#line 248 "objc-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 10: -#line 256 "objc-parse.y" -{ STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - assemble_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 11: -#line 267 "objc-parse.y" -{ if (pedantic) - error ("ANSI C forbids data definition with no type or storage class"); - else if (!flag_traditional) - warning ("data definition has no type or storage class"); ; - break;} -case 12: -#line 272 "objc-parse.y" -{; - break;} -case 13: -#line 274 "objc-parse.y" -{; - break;} -case 14: -#line 276 "objc-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 15: -#line 278 "objc-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 18: -#line 282 "objc-parse.y" -{ if (pedantic) - pedwarn ("ANSI C does not allow extra `;' outside of a function"); ; - break;} -case 19: -#line 288 "objc-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 20: -#line 292 "objc-parse.y" -{ store_parm_decls (); ; - break;} -case 21: -#line 294 "objc-parse.y" -{ finish_function (0); ; - break;} -case 22: -#line 296 "objc-parse.y" -{ ; - break;} -case 23: -#line 298 "objc-parse.y" -{ if (! start_function (yyvsp[-2].ttype, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 24: -#line 302 "objc-parse.y" -{ store_parm_decls (); ; - break;} -case 25: -#line 304 "objc-parse.y" -{ finish_function (0); ; - break;} -case 26: -#line 306 "objc-parse.y" -{ ; - break;} -case 27: -#line 308 "objc-parse.y" -{ if (! start_function (NULL_TREE, yyvsp[0].ttype, 0)) - YYERROR1; - reinit_parse_for_function (); ; - break;} -case 28: -#line 312 "objc-parse.y" -{ store_parm_decls (); ; - break;} -case 29: -#line 314 "objc-parse.y" -{ finish_function (0); ; - break;} -case 30: -#line 316 "objc-parse.y" -{ ; - break;} -case 35: -#line 327 "objc-parse.y" -{ yyval.code = ADDR_EXPR; ; - break;} -case 36: -#line 329 "objc-parse.y" -{ yyval.code = NEGATE_EXPR; ; - break;} -case 37: -#line 331 "objc-parse.y" -{ yyval.code = CONVERT_EXPR; ; - break;} -case 38: -#line 333 "objc-parse.y" -{ yyval.code = PREINCREMENT_EXPR; ; - break;} -case 39: -#line 335 "objc-parse.y" -{ yyval.code = PREDECREMENT_EXPR; ; - break;} -case 40: -#line 337 "objc-parse.y" -{ yyval.code = BIT_NOT_EXPR; ; - break;} -case 41: -#line 339 "objc-parse.y" -{ yyval.code = TRUTH_NOT_EXPR; ; - break;} -case 42: -#line 343 "objc-parse.y" -{ yyval.ttype = build_compound_expr (yyvsp[0].ttype); ; - break;} -case 43: -#line 348 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 45: -#line 354 "objc-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 46: -#line 356 "objc-parse.y" -{ chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 48: -#line 362 "objc-parse.y" -{ yyval.ttype = build_indirect_ref (yyvsp[0].ttype, "unary *"); ; - break;} -case 49: -#line 365 "objc-parse.y" -{ yyvsp[0].itype = pedantic; - pedantic = 0; ; - break;} -case 50: -#line 368 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - pedantic = yyvsp[-2].itype; ; - break;} -case 51: -#line 371 "objc-parse.y" -{ yyval.ttype = build_unary_op (yyvsp[-1].code, yyvsp[0].ttype, 0); - overflow_warning (yyval.ttype); ; - break;} -case 52: -#line 375 "objc-parse.y" -{ tree label = lookup_label (yyvsp[0].ttype); - if (label == 0) - yyval.ttype = null_pointer_node; - else - { - TREE_USED (label) = 1; - yyval.ttype = build1 (ADDR_EXPR, ptr_type_node, label); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 53: -#line 401 "objc-parse.y" -{ if (TREE_CODE (yyvsp[0].ttype) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (yyvsp[0].ttype, 1))) - error ("`sizeof' applied to a bit-field"); - yyval.ttype = c_sizeof (TREE_TYPE (yyvsp[0].ttype)); ; - break;} -case 54: -#line 406 "objc-parse.y" -{ yyval.ttype = c_sizeof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 55: -#line 408 "objc-parse.y" -{ yyval.ttype = c_alignof_expr (yyvsp[0].ttype); ; - break;} -case 56: -#line 410 "objc-parse.y" -{ yyval.ttype = c_alignof (groktypename (yyvsp[-1].ttype)); ; - break;} -case 57: -#line 412 "objc-parse.y" -{ yyval.ttype = build_unary_op (REALPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 58: -#line 414 "objc-parse.y" -{ yyval.ttype = build_unary_op (IMAGPART_EXPR, yyvsp[0].ttype, 0); ; - break;} -case 60: -#line 420 "objc-parse.y" -{ tree type = groktypename (yyvsp[-2].ttype); - yyval.ttype = build_c_cast (type, yyvsp[0].ttype); ; - break;} -case 61: -#line 423 "objc-parse.y" -{ tree type = groktypename (yyvsp[-5].ttype); - char *name; - if (pedantic) - pedwarn ("ANSI C forbids constructor expressions"); - if (TYPE_NAME (type) != 0) - { - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (TYPE_NAME (type)); - else - name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - } - else - name = ""; - yyval.ttype = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)), - NULL_PTR, 0, 0, name); - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) - { - int failure = complete_array_type (type, yyval.ttype, 1); - if (failure) - abort (); - } - ; - break;} -case 63: -#line 450 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 64: -#line 452 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 65: -#line 454 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 66: -#line 456 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 67: -#line 458 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 68: -#line 460 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 69: -#line 462 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 70: -#line 464 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 71: -#line 466 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 72: -#line 468 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 73: -#line 470 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 74: -#line 472 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (yyvsp[-1].code, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 75: -#line 474 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ANDIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 76: -#line 476 "objc-parse.y" -{ yyval.ttype = parser_build_binary_op (TRUTH_ORIF_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 77: -#line 478 "objc-parse.y" -{ yyval.ttype = build_conditional_expr (yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 78: -#line 480 "objc-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, NOP_EXPR, yyvsp[0].ttype); - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, MODIFY_EXPR); ; - break;} -case 79: -#line 483 "objc-parse.y" -{ yyval.ttype = build_modify_expr (yyvsp[-2].ttype, yyvsp[-1].code, yyvsp[0].ttype); - /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE (yyval.ttype, ERROR_MARK); ; - break;} -case 80: -#line 490 "objc-parse.y" -{ - tree context; - - yyval.ttype = lastiddecl; - if (!yyval.ttype || yyval.ttype == error_mark_node) - { - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - tree decl; - - if (objc_receiver_context - && ! (objc_receiver_context - && strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super"))) - /* we have a message to super */ - yyval.ttype = get_super_receiver (); - else if (objc_method_context - && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype))) - { - if (is_private (decl)) - yyval.ttype = error_mark_node; - else - yyval.ttype = build_ivar_reference (yyvsp[0].ttype); - } - else - { - /* Ordinary implicit function declaration. */ - yyval.ttype = implicitly_declare (yyvsp[0].ttype); - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - } - else if (current_function_decl == 0) - { - error ("`%s' undeclared here (not in a function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = error_mark_node; - } - else - { - tree decl; - - if (objc_receiver_context - && ! strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super")) - /* we have a message to super */ - yyval.ttype = get_super_receiver (); - else if (objc_method_context - && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype))) - { - if (is_private (decl)) - yyval.ttype = error_mark_node; - else - yyval.ttype = build_ivar_reference (yyvsp[0].ttype); - } - else - { - if (IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) != current_function_decl) - { - error ("`%s' undeclared (first use this function)", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - yyval.ttype = error_mark_node; - /* Prevent repeated error messages. */ - IDENTIFIER_GLOBAL_VALUE (yyvsp[0].ttype) = error_mark_node; - IDENTIFIER_ERROR_LOCUS (yyvsp[0].ttype) = current_function_decl; - } - } - } - else if (TREE_TYPE (yyval.ttype) == error_mark_node) - yyval.ttype = error_mark_node; - else if (C_DECL_ANTICIPATED (yyval.ttype)) - { - /* The first time we see a build-in function used, - if it has not been declared. */ - C_DECL_ANTICIPATED (yyval.ttype) = 0; - if (yychar == YYEMPTY) - yychar = YYLEX; - if (yychar == '(') - { - /* Omit the implicit declaration we - would ordinarily do, so we don't lose - the actual built in type. - But print a diagnostic for the mismatch. */ - if (objc_method_context - && is_ivar (objc_ivar_chain, yyvsp[0].ttype)) - error ("Instance variable `%s' implicitly declared as function", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - else - if (TREE_CODE (yyval.ttype) != FUNCTION_DECL) - error ("`%s' implicitly declared as function", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE (yyval.ttype))) - != TYPE_MODE (integer_type_node)) - && (TREE_TYPE (TREE_TYPE (yyval.ttype)) - != void_type_node)) - pedwarn ("type mismatch in implicit declaration for built-in function `%s'", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - /* If it really returns void, change that to int. */ - if (TREE_TYPE (TREE_TYPE (yyval.ttype)) == void_type_node) - TREE_TYPE (yyval.ttype) - = build_function_type (integer_type_node, - TYPE_ARG_TYPES (TREE_TYPE (yyval.ttype))); - } - else - pedwarn ("built-in function `%s' used without declaration", - IDENTIFIER_POINTER (DECL_NAME (yyval.ttype))); - - /* Do what we would ordinarily do when a fn is used. */ - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - } - else - { - assemble_external (yyval.ttype); - TREE_USED (yyval.ttype) = 1; - /* we have a definition - still check if iVariable */ - - if (!objc_receiver_context - || (objc_receiver_context - && strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "super"))) - { - tree decl; - - if (objc_method_context - && (decl = is_ivar (objc_ivar_chain, yyvsp[0].ttype))) - { - if (IDENTIFIER_LOCAL_VALUE (yyvsp[0].ttype)) - warning ("local declaration of `%s' hides instance variable", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - else - { - if (is_private (decl)) - yyval.ttype = error_mark_node; - else - yyval.ttype = build_ivar_reference (yyvsp[0].ttype); - } - } - } - else /* we have a message to super */ - yyval.ttype = get_super_receiver (); - } - - if (TREE_CODE (yyval.ttype) == CONST_DECL) - { - yyval.ttype = DECL_INITIAL (yyval.ttype); - /* This is to prevent an enum whose value is 0 - from being considered a null pointer constant. */ - yyval.ttype = build1 (NOP_EXPR, TREE_TYPE (yyval.ttype), yyval.ttype); - TREE_CONSTANT (yyval.ttype) = 1; - } - ; - break;} -case 82: -#line 652 "objc-parse.y" -{ yyval.ttype = combine_strings (yyvsp[0].ttype); ; - break;} -case 83: -#line 654 "objc-parse.y" -{ char class = TREE_CODE_CLASS (TREE_CODE (yyvsp[-1].ttype)); - if (class == 'e' || class == '1' - || class == '2' || class == '<') - C_SET_EXP_ORIGINAL_CODE (yyvsp[-1].ttype, ERROR_MARK); - yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 84: -#line 660 "objc-parse.y" -{ yyval.ttype = error_mark_node; ; - break;} -case 85: -#line 662 "objc-parse.y" -{ if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - /* We must force a BLOCK for this level - so that, if it is not expanded later, - there is a way to turn off the entire subtree of blocks - that are contained in it. */ - keep_next_level (); - push_iterator_stack (); - push_label_level (); - yyval.ttype = expand_start_stmt_expr (); ; - break;} -case 86: -#line 676 "objc-parse.y" -{ tree rtl_exp; - if (pedantic) - pedwarn ("ANSI C forbids braced-groups within expressions"); - pop_iterator_stack (); - pop_label_level (); - rtl_exp = expand_end_stmt_expr (yyvsp[-2].ttype); - /* The statements have side effects, so the group does. */ - TREE_SIDE_EFFECTS (rtl_exp) = 1; - - /* Make a BIND_EXPR for the BLOCK already made. */ - yyval.ttype = build (BIND_EXPR, TREE_TYPE (rtl_exp), - NULL_TREE, rtl_exp, yyvsp[-1].ttype); - /* Remove the block from the tree at this point. - It gets put back at the proper place - when the BIND_EXPR is expanded. */ - delete_block (yyvsp[-1].ttype); - ; - break;} -case 87: -#line 694 "objc-parse.y" -{ yyval.ttype = build_function_call (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 88: -#line 696 "objc-parse.y" -{ yyval.ttype = build_array_ref (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 89: -#line 698 "objc-parse.y" -{ - if (doing_objc_thang) - { - if (is_public (yyvsp[-2].ttype, yyvsp[0].ttype)) - yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype); - else - yyval.ttype = error_mark_node; - } - else - yyval.ttype = build_component_ref (yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 90: -#line 710 "objc-parse.y" -{ - tree expr = build_indirect_ref (yyvsp[-2].ttype, "->"); - - if (doing_objc_thang) - { - if (is_public (expr, yyvsp[0].ttype)) - yyval.ttype = build_component_ref (expr, yyvsp[0].ttype); - else - yyval.ttype = error_mark_node; - } - else - yyval.ttype = build_component_ref (expr, yyvsp[0].ttype); - ; - break;} -case 91: -#line 724 "objc-parse.y" -{ yyval.ttype = build_unary_op (POSTINCREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 92: -#line 726 "objc-parse.y" -{ yyval.ttype = build_unary_op (POSTDECREMENT_EXPR, yyvsp[-1].ttype, 0); ; - break;} -case 93: -#line 728 "objc-parse.y" -{ yyval.ttype = build_message_expr (yyvsp[0].ttype); ; - break;} -case 94: -#line 730 "objc-parse.y" -{ yyval.ttype = build_selector_expr (yyvsp[0].ttype); ; - break;} -case 95: -#line 732 "objc-parse.y" -{ yyval.ttype = build_protocol_expr (yyvsp[0].ttype); ; - break;} -case 96: -#line 734 "objc-parse.y" -{ yyval.ttype = build_encode_expr (yyvsp[0].ttype); ; - break;} -case 97: -#line 736 "objc-parse.y" -{ yyval.ttype = build_objc_string_object (yyvsp[0].ttype); ; - break;} -case 99: -#line 743 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 101: -#line 751 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 104: -#line 759 "objc-parse.y" -{ c_mark_varargs (); - if (pedantic) - pedwarn ("ANSI C does not permit use of `varargs.h'"); ; - break;} -case 105: -#line 769 "objc-parse.y" -{ ; - break;} -case 110: -#line 781 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 111: -#line 785 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 112: -#line 789 "objc-parse.y" -{ shadow_tag_warned (yyvsp[-1].ttype, 1); - pedwarn ("empty declaration"); ; - break;} -case 113: -#line 792 "objc-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 114: -#line 801 "objc-parse.y" -{ ; - break;} -case 119: -#line 816 "objc-parse.y" -{ yyval.itype = suspend_momentary (); - pending_xref_error (); - declspec_stack = tree_cons (NULL_TREE, current_declspecs, - declspec_stack); - current_declspecs = yyvsp[0].ttype; ; - break;} -case 120: -#line 825 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 121: -#line 829 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-2].itype); ; - break;} -case 122: -#line 833 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 123: -#line 837 "objc-parse.y" -{ current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 124: -#line 841 "objc-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 125: -#line 843 "objc-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 126: -#line 852 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 127: -#line 854 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 128: -#line 858 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 129: -#line 860 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 130: -#line 862 "objc-parse.y" -{ if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 131: -#line 874 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 132: -#line 877 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 133: -#line 879 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = 1; ; - break;} -case 134: -#line 882 "objc-parse.y" -{ if (extra_warnings && TREE_STATIC (yyvsp[-1].ttype)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); - TREE_STATIC (yyval.ttype) = TREE_STATIC (yyvsp[-1].ttype); ; - break;} -case 135: -#line 896 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 136: -#line 898 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, tree_cons (NULL_TREE, yyvsp[-1].ttype, yyvsp[-2].ttype)); ; - break;} -case 137: -#line 902 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 138: -#line 904 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 141: -#line 914 "objc-parse.y" -{ /* For a typedef name, record the meaning, not the name. - In case of `foo foo, bar;'. */ - yyval.ttype = lookup_name (yyvsp[0].ttype); ; - break;} -case 142: -#line 918 "objc-parse.y" -{ yyval.ttype = get_static_reference (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 143: -#line 920 "objc-parse.y" -{ yyval.ttype = get_object_reference (yyvsp[0].ttype); ; - break;} -case 144: -#line 922 "objc-parse.y" -{ yyval.ttype = TREE_TYPE (yyvsp[-1].ttype); ; - break;} -case 145: -#line 924 "objc-parse.y" -{ yyval.ttype = groktypename (yyvsp[-1].ttype); ; - break;} -case 153: -#line 946 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 154: -#line 948 "objc-parse.y" -{ if (TREE_CHAIN (yyvsp[-1].ttype)) yyvsp[-1].ttype = combine_strings (yyvsp[-1].ttype); - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 155: -#line 955 "objc-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 156: -#line 958 "objc-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 157: -#line 961 "objc-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 158: -#line 968 "objc-parse.y" -{ yyval.ttype = start_decl (yyvsp[-3].ttype, current_declspecs, 1); ; - break;} -case 159: -#line 971 "objc-parse.y" -{ decl_attributes (yyvsp[-1].ttype, yyvsp[-3].ttype); - finish_decl (yyvsp[-1].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 160: -#line 974 "objc-parse.y" -{ tree d = start_decl (yyvsp[-2].ttype, current_declspecs, 0); - decl_attributes (d, yyvsp[0].ttype); - finish_decl (d, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 161: -#line 982 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 162: -#line 984 "objc-parse.y" -{ yyval.ttype = yyvsp[-2].ttype; ; - break;} -case 163: -#line 989 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 164: -#line 991 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 165: -#line 996 "objc-parse.y" -{ if (strcmp (IDENTIFIER_POINTER (yyvsp[0].ttype), "packed")) - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[0].ttype)); - yyval.ttype = yyvsp[0].ttype; ; - break;} -case 166: -#line 1001 "objc-parse.y" -{ /* If not "mode (m)", then issue warning. */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "mode") != 0) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 167: -#line 1011 "objc-parse.y" -{ /* if not "aligned(n)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-3].ttype), "aligned") != 0 - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-3].ttype)); - yyval.ttype = yyvsp[-3].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); ; - break;} -case 168: -#line 1022 "objc-parse.y" -{ /* if not "format(...)", then issue warning */ - if (strcmp (IDENTIFIER_POINTER (yyvsp[-7].ttype), "format") != 0 - || TREE_CODE (yyvsp[-3].ttype) != INTEGER_CST - || TREE_CODE (yyvsp[-1].ttype) != INTEGER_CST) - { - warning ("`%s' attribute directive ignored", - IDENTIFIER_POINTER (yyvsp[-7].ttype)); - yyval.ttype = yyvsp[-7].ttype; - } - else - yyval.ttype = tree_cons (yyvsp[-7].ttype, - tree_cons (yyvsp[-5].ttype, - tree_cons (yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE), - NULL_TREE), - NULL_TREE); ; - break;} -case 170: -#line 1042 "objc-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - if (pedantic) - pedwarn ("ANSI C forbids empty initializer braces"); ; - break;} -case 171: -#line 1046 "objc-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-1].ttype)); ; - break;} -case 172: -#line 1048 "objc-parse.y" -{ yyval.ttype = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (yyvsp[-2].ttype)); ; - break;} -case 173: -#line 1050 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 174: -#line 1057 "objc-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 175: -#line 1059 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 176: -#line 1064 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 177: -#line 1066 "objc-parse.y" -{ yyval.ttype = tree_cons (yyvsp[-2].ttype, yyvsp[0].ttype, yyvsp[-4].ttype); ; - break;} -case 178: -#line 1071 "objc-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 179: -#line 1086 "objc-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 180: -#line 1092 "objc-parse.y" -{ push_c_function_context (); - if (! start_function (current_declspecs, yyvsp[0].ttype, 1)) - { - pop_c_function_context (); - YYERROR1; - } - reinit_parse_for_function (); - store_parm_decls (); ; - break;} -case 181: -#line 1107 "objc-parse.y" -{ finish_function (1); - pop_c_function_context (); ; - break;} -case 184: -#line 1123 "objc-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 185: -#line 1125 "objc-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 186: -#line 1130 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 187: -#line 1132 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 188: -#line 1134 "objc-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 191: -#line 1146 "objc-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 192: -#line 1151 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 193: -#line 1153 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 194: -#line 1155 "objc-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 196: -#line 1164 "objc-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 197: -#line 1169 "objc-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 198: -#line 1171 "objc-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 199: -#line 1173 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 200: -#line 1175 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 202: -#line 1181 "objc-parse.y" -{ yyval.ttype = start_struct (RECORD_TYPE, yyvsp[-1].ttype); - /* Start scope of tag before parsing components. */ - ; - break;} -case 203: -#line 1185 "objc-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); - /* Really define the structure. */ - ; - break;} -case 204: -#line 1189 "objc-parse.y" -{ yyval.ttype = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 205: -#line 1192 "objc-parse.y" -{ yyval.ttype = xref_tag (RECORD_TYPE, yyvsp[0].ttype); ; - break;} -case 206: -#line 1194 "objc-parse.y" -{ yyval.ttype = start_struct (UNION_TYPE, yyvsp[-1].ttype); ; - break;} -case 207: -#line 1196 "objc-parse.y" -{ yyval.ttype = finish_struct (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 208: -#line 1198 "objc-parse.y" -{ yyval.ttype = finish_struct (start_struct (UNION_TYPE, NULL_TREE), - yyvsp[-1].ttype); ; - break;} -case 209: -#line 1201 "objc-parse.y" -{ yyval.ttype = xref_tag (UNION_TYPE, yyvsp[0].ttype); ; - break;} -case 210: -#line 1203 "objc-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (yyvsp[-1].ttype); ; - break;} -case 211: -#line 1206 "objc-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 212: -#line 1209 "objc-parse.y" -{ yyvsp[0].itype = suspend_momentary (); - yyval.ttype = start_enum (NULL_TREE); ; - break;} -case 213: -#line 1212 "objc-parse.y" -{ yyval.ttype = finish_enum (yyvsp[-3].ttype, nreverse (yyvsp[-2].ttype)); - resume_momentary (yyvsp[-4].itype); ; - break;} -case 214: -#line 1215 "objc-parse.y" -{ yyval.ttype = xref_tag (ENUMERAL_TYPE, yyvsp[0].ttype); ; - break;} -case 218: -#line 1226 "objc-parse.y" -{ if (pedantic) pedwarn ("comma at end of enumerator list"); ; - break;} -case 219: -#line 1231 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 220: -#line 1233 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - pedwarn ("no semicolon at end of struct or union"); ; - break;} -case 221: -#line 1238 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 222: -#line 1240 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[-1].ttype); ; - break;} -case 223: -#line 1242 "objc-parse.y" -{ if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); ; - break;} -case 224: -#line 1246 "objc-parse.y" -{ - tree interface = lookup_interface (yyvsp[-1].ttype); - - if (interface) - yyval.ttype = get_class_ivars (interface); - else - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (yyvsp[-1].ttype)); - yyval.ttype = NULL_TREE; - } - ; - break;} -case 225: -#line 1271 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 226: -#line 1276 "objc-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 227: -#line 1281 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - current_declspecs = TREE_VALUE (declspec_stack); - declspec_stack = TREE_CHAIN (declspec_stack); - resume_momentary (yyvsp[-1].itype); ; - break;} -case 228: -#line 1286 "objc-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids member declarations with no members"); - shadow_tag(yyvsp[0].ttype); - yyval.ttype = NULL_TREE; ; - break;} -case 229: -#line 1291 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 231: -#line 1297 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 232: -#line 1302 "objc-parse.y" -{ yyval.ttype = grokfield (yyvsp[-3].filename, yyvsp[-2].lineno, yyvsp[-1].ttype, current_declspecs, NULL_TREE); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 233: -#line 1306 "objc-parse.y" -{ yyval.ttype = grokfield (yyvsp[-5].filename, yyvsp[-4].lineno, yyvsp[-3].ttype, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 234: -#line 1309 "objc-parse.y" -{ yyval.ttype = grokfield (yyvsp[-4].filename, yyvsp[-3].lineno, NULL_TREE, current_declspecs, yyvsp[-1].ttype); - decl_attributes (yyval.ttype, yyvsp[0].ttype); ; - break;} -case 236: -#line 1321 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[0].ttype, yyvsp[-2].ttype); ; - break;} -case 237: -#line 1327 "objc-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 238: -#line 1329 "objc-parse.y" -{ yyval.ttype = build_enumerator (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 239: -#line 1334 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 240: -#line 1336 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 241: -#line 1341 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 243: -#line 1347 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 244: -#line 1349 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 245: -#line 1354 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 246: -#line 1356 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, yyvsp[0].ttype, yyvsp[-1].ttype); ; - break;} -case 247: -#line 1361 "objc-parse.y" -{ yyval.ttype = yyvsp[-1].ttype; ; - break;} -case 248: -#line 1364 "objc-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 249: -#line 1366 "objc-parse.y" -{ yyval.ttype = make_pointer_declarator (yyvsp[0].ttype, NULL_TREE); ; - break;} -case 250: -#line 1368 "objc-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 251: -#line 1370 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 252: -#line 1372 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, yyvsp[-2].ttype, NULL_TREE); ; - break;} -case 253: -#line 1374 "objc-parse.y" -{ yyval.ttype = build_nt (CALL_EXPR, NULL_TREE, yyvsp[0].ttype, NULL_TREE); ; - break;} -case 254: -#line 1376 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 255: -#line 1378 "objc-parse.y" -{ yyval.ttype = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); ; - break;} -case 262: -#line 1400 "objc-parse.y" -{ emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - if (objc_method_context) - add_objc_decls (); - ; - break;} -case 264: -#line 1415 "objc-parse.y" -{ if (pedantic) - pedwarn ("ANSI C forbids label declarations"); ; - break;} -case 267: -#line 1426 "objc-parse.y" -{ tree link; - for (link = yyvsp[-1].ttype; link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - ; - break;} -case 268: -#line 1440 "objc-parse.y" -{; - break;} -case 270: -#line 1445 "objc-parse.y" -{ yyval.ttype = convert (void_type_node, integer_zero_node); ; - break;} -case 271: -#line 1447 "objc-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), 1, 0); - yyval.ttype = poplevel (1, 1, 0); - pop_momentary (); ; - break;} -case 272: -#line 1452 "objc-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - pop_momentary (); ; - break;} -case 273: -#line 1457 "objc-parse.y" -{ emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 0); - yyval.ttype = poplevel (kept_level_p (), 0, 0); - pop_momentary (); ; - break;} -case 276: -#line 1474 "objc-parse.y" -{ emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_start_cond (truthvalue_conversion (yyvsp[-1].ttype), 0); - yyvsp[-3].itype = stmt_count; - if_stmt_file = yyvsp[-5].filename; - if_stmt_line = yyvsp[-4].lineno; - position_after_white_space (); ; - break;} -case 277: -#line 1487 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - expand_start_loop_continue_elsewhere (1); - position_after_white_space (); ; - break;} -case 278: -#line 1494 "objc-parse.y" -{ expand_loop_continue_here (); ; - break;} -case 279: -#line 1498 "objc-parse.y" -{ yyval.filename = input_filename; ; - break;} -case 280: -#line 1502 "objc-parse.y" -{ yyval.lineno = lineno; ; - break;} -case 281: -#line 1507 "objc-parse.y" -{ ; - break;} -case 282: -#line 1512 "objc-parse.y" -{ ; - break;} -case 283: -#line 1517 "objc-parse.y" -{ ; - break;} -case 285: -#line 1523 "objc-parse.y" -{ int next; - position_after_white_space (); - next = getc (finput); - ungetc (next, finput); - if (pedantic && next == '}') - pedwarn ("ANSI C forbids label at end of compound statement"); - ; - break;} -case 286: -#line 1535 "objc-parse.y" -{ stmt_count++; ; - break;} -case 288: -#line 1538 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - iterator_expand (yyvsp[-1].ttype); - clear_momentary (); ; - break;} -case 289: -#line 1543 "objc-parse.y" -{ expand_start_else (); - yyvsp[-1].itype = stmt_count; - position_after_white_space (); ; - break;} -case 290: -#line 1547 "objc-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[-3].itype) - warning ("empty body in an else-statement"); ; - break;} -case 291: -#line 1551 "objc-parse.y" -{ expand_end_cond (); - if (extra_warnings && stmt_count == yyvsp[0].itype) - warning_with_file_and_line (if_stmt_file, if_stmt_line, - "empty body in an if-statement"); ; - break;} -case 292: -#line 1559 "objc-parse.y" -{ expand_end_cond (); ; - break;} -case 293: -#line 1561 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-2].filename, yyvsp[-1].lineno); - /* The emit_nop used to come before emit_line_note, - but that made the nop seem like part of the preceding line. - And that was confusing when the preceding line was - inside of an if statement and was not really executed. - I think it ought to work to put the nop after the line number. - We will see. --rms, July 15, 1991. */ - emit_nop (); ; - break;} -case 294: -#line 1571 "objc-parse.y" -{ /* Don't start the loop till we have succeeded - in parsing the end test. This is to make sure - that we end every loop we start. */ - expand_start_loop (1); - emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-1].ttype)); - position_after_white_space (); ; - break;} -case 295: -#line 1580 "objc-parse.y" -{ expand_end_loop (); ; - break;} -case 296: -#line 1583 "objc-parse.y" -{ emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-2].ttype)); - expand_end_loop (); - clear_momentary (); ; - break;} -case 297: -#line 1590 "objc-parse.y" -{ expand_end_loop (); - clear_momentary (); ; - break;} -case 298: -#line 1594 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - /* See comment in `while' alternative, above. */ - emit_nop (); - if (yyvsp[-1].ttype) c_expand_expr_stmt (yyvsp[-1].ttype); - /* Next step is to call expand_start_loop_continue_elsewhere, - but wait till after we parse the entire for (...). - Otherwise, invalid input might cause us to call that - fn without calling expand_end_loop. */ - ; - break;} -case 299: -#line 1606 "objc-parse.y" -{ yyvsp[0].lineno = lineno; - yyval.filename = input_filename; ; - break;} -case 300: -#line 1609 "objc-parse.y" -{ - /* Start the loop. Doing this after parsing - all the expressions ensures we will end the loop. */ - expand_start_loop_continue_elsewhere (1); - /* Emit the end-test, with a line number. */ - emit_line_note (yyvsp[-2].filename, yyvsp[-3].lineno); - if (yyvsp[-4].ttype) - expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion (yyvsp[-4].ttype)); - /* Don't let the tree nodes for $9 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - yyvsp[-3].lineno = lineno; - yyvsp[-2].filename = input_filename; - position_after_white_space (); ; - break;} -case 301: -#line 1625 "objc-parse.y" -{ /* Emit the increment expression, with a line number. */ - emit_line_note (yyvsp[-4].filename, yyvsp[-5].lineno); - expand_loop_continue_here (); - if (yyvsp[-3].ttype) - c_expand_expr_stmt (yyvsp[-3].ttype); - pop_momentary (); - expand_end_loop (); ; - break;} -case 302: -#line 1633 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - c_expand_start_case (yyvsp[-1].ttype); - /* Don't let the tree nodes for $3 be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - position_after_white_space (); ; - break;} -case 303: -#line 1641 "objc-parse.y" -{ expand_end_case (yyvsp[-3].ttype); - pop_momentary (); ; - break;} -case 304: -#line 1644 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if ( ! expand_exit_something ()) - error ("break statement not within loop or switch"); ; - break;} -case 305: -#line 1649 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - if (! expand_continue_loop (NULL_PTR)) - error ("continue statement not within a loop"); ; - break;} -case 306: -#line 1654 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-3].filename, yyvsp[-2].lineno); - c_expand_return (NULL_TREE); ; - break;} -case 307: -#line 1658 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - c_expand_return (yyvsp[-1].ttype); ; - break;} -case 308: -#line 1662 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-7].filename, yyvsp[-6].lineno); - STRIP_NOPS (yyvsp[-2].ttype); - if ((TREE_CODE (yyvsp[-2].ttype) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (yyvsp[-2].ttype, 0)) == STRING_CST) - || TREE_CODE (yyvsp[-2].ttype) == STRING_CST) - expand_asm (yyvsp[-2].ttype); - else - error ("argument of `asm' is not a constant string"); ; - break;} -case 309: -#line 1673 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-9].filename, yyvsp[-8].lineno); - c_expand_asm_operands (yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, NULL_TREE, - yyvsp[-6].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 310: -#line 1680 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-11].filename, yyvsp[-10].lineno); - c_expand_asm_operands (yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, NULL_TREE, - yyvsp[-8].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 311: -#line 1688 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-13].filename, yyvsp[-12].lineno); - c_expand_asm_operands (yyvsp[-8].ttype, yyvsp[-6].ttype, yyvsp[-4].ttype, yyvsp[-2].ttype, - yyvsp[-10].ttype == ridpointers[(int)RID_VOLATILE], - input_filename, lineno); ; - break;} -case 312: -#line 1694 "objc-parse.y" -{ tree decl; - stmt_count++; - emit_line_note (yyvsp[-4].filename, yyvsp[-3].lineno); - decl = lookup_label (yyvsp[-1].ttype); - if (decl != 0) - { - TREE_USED (decl) = 1; - expand_goto (decl); - } - ; - break;} -case 313: -#line 1705 "objc-parse.y" -{ stmt_count++; - emit_line_note (yyvsp[-5].filename, yyvsp[-4].lineno); - expand_computed_goto (convert (ptr_type_node, yyvsp[-1].ttype)); ; - break;} -case 316: -#line 1718 "objc-parse.y" -{ - /* The value returned by this action is */ - /* 1 if everything is OK */ - /* 0 in case of error or already bound iterator */ - - yyval.itype = 0; - if (TREE_CODE (yyvsp[-1].ttype) != VAR_DECL) - error ("invalid `for (ITERATOR)' syntax"); - if (! ITERATOR_P (yyvsp[-1].ttype)) - error ("`%s' is not an iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else if (ITERATOR_BOUND_P (yyvsp[-1].ttype)) - error ("`for (%s)' inside expansion of same iterator", - IDENTIFIER_POINTER (DECL_NAME (yyvsp[-1].ttype))); - else - { - yyval.itype = 1; - iterator_for_loop_start (yyvsp[-1].ttype); - } - ; - break;} -case 317: -#line 1739 "objc-parse.y" -{ - if (yyvsp[-1].itype) - iterator_for_loop_end (yyvsp[-3].ttype); - ; - break;} -case 318: -#line 1771 "objc-parse.y" -{ register tree value = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value != error_mark_node) - { - tree duplicate; - int success = pushcase (value, label, &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 319: -#line 1795 "objc-parse.y" -{ register tree value1 = check_case_value (yyvsp[-3].ttype); - register tree value2 = check_case_value (yyvsp[-1].ttype); - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - stmt_count++; - - if (value1 != error_mark_node && value2 != error_mark_node) - { - tree duplicate; - int success = pushcase_range (value1, value2, label, - &duplicate); - if (success == 1) - error ("case label not within a switch statement"); - else if (success == 2) - { - error ("duplicate case value"); - error_with_decl (duplicate, "this is the first entry for that value"); - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 4) - warning ("empty case range"); - else if (success == 5) - error ("case label within scope of cleanup or variable array"); - } - position_after_white_space (); ; - break;} -case 320: -#line 1823 "objc-parse.y" -{ - tree duplicate; - register tree label - = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - int success = pushcase (NULL_TREE, label, &duplicate); - stmt_count++; - if (success == 1) - error ("default label not within a switch statement"); - else if (success == 2) - { - error ("multiple default labels in one switch"); - error_with_decl (duplicate, "this is the first default label"); - } - position_after_white_space (); ; - break;} -case 321: -#line 1838 "objc-parse.y" -{ tree label = define_label (input_filename, lineno, yyvsp[-1].ttype); - stmt_count++; - emit_nop (); - if (label) - expand_label (label); - position_after_white_space (); ; - break;} -case 322: -#line 1850 "objc-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 323: -#line 1852 "objc-parse.y" -{ emit_line_note (input_filename, lineno); ; - break;} -case 324: -#line 1857 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 326: -#line 1864 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 329: -#line 1871 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, yyvsp[0].ttype); ; - break;} -case 330: -#line 1876 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); ; - break;} -case 331: -#line 1881 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), NULL_TREE); ; - break;} -case 332: -#line 1883 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, combine_strings (yyvsp[0].ttype), yyvsp[-2].ttype); ; - break;} -case 333: -#line 1889 "objc-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (0); ; - break;} -case 334: -#line 1893 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 336: -#line 1901 "objc-parse.y" -{ tree parm; - if (pedantic) - pedwarn ("ANSI C forbids forward parameter declarations"); - /* Mark the forward decls as such. */ - for (parm = getdecls (); parm; parm = TREE_CHAIN (parm)) - TREE_ASM_WRITTEN (parm) = 1; - clear_parm_order (); ; - break;} -case 337: -#line 1909 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; ; - break;} -case 338: -#line 1911 "objc-parse.y" -{ yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); ; - break;} -case 339: -#line 1917 "objc-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 340: -#line 1919 "objc-parse.y" -{ yyval.ttype = get_parm_info (0); - if (pedantic) - pedwarn ("ANSI C requires a named argument before `...'"); - ; - break;} -case 341: -#line 1924 "objc-parse.y" -{ yyval.ttype = get_parm_info (1); ; - break;} -case 342: -#line 1926 "objc-parse.y" -{ yyval.ttype = get_parm_info (0); ; - break;} -case 343: -#line 1931 "objc-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 344: -#line 1933 "objc-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 345: -#line 1940 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 346: -#line 1942 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 347: -#line 1944 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 348: -#line 1946 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype) ; ; - break;} -case 349: -#line 1948 "objc-parse.y" -{ yyval.ttype = build_tree_list (yyvsp[-1].ttype, yyvsp[0].ttype); ; - break;} -case 350: -#line 1955 "objc-parse.y" -{ pushlevel (0); - clear_parm_order (); - declare_parm_level (1); ; - break;} -case 351: -#line 1959 "objc-parse.y" -{ yyval.ttype = yyvsp[0].ttype; - parmlist_tags_warning (); - poplevel (0, 0, 0); ; - break;} -case 353: -#line 1967 "objc-parse.y" -{ tree t; - for (t = yyvsp[-1].ttype; t; t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == NULL_TREE) - error ("`...' in old-style identifier list"); - yyval.ttype = tree_cons (NULL_TREE, NULL_TREE, yyvsp[-1].ttype); ; - break;} -case 354: -#line 1977 "objc-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 355: -#line 1979 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 356: -#line 1985 "objc-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 357: -#line 1987 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 363: -#line 1999 "objc-parse.y" -{ - if (objc_implementation_context) - { - finish_class (objc_implementation_context); - objc_ivar_chain = NULL_TREE; - objc_implementation_context = NULL_TREE; - } - else - warning ("`@end' must appear in an implementation context"); - ; - break;} -case 364: -#line 2014 "objc-parse.y" -{ yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); ; - break;} -case 365: -#line 2016 "objc-parse.y" -{ yyval.ttype = chainon (yyvsp[-2].ttype, build_tree_list (NULL_TREE, yyvsp[0].ttype)); ; - break;} -case 366: -#line 2021 "objc-parse.y" -{ - objc_declare_class (yyvsp[-1].ttype); - ; - break;} -case 367: -#line 2027 "objc-parse.y" -{ - objc_declare_alias (yyvsp[-2].ttype, yyvsp[-1].ttype); - ; - break;} -case 368: -#line 2033 "objc-parse.y" -{ - objc_interface_context = objc_ivar_context - = start_class (CLASS_INTERFACE_TYPE, yyvsp[-2].ttype, NULL_TREE, yyvsp[-1].ttype); - objc_public_flag = 0; - ; - break;} -case 369: -#line 2039 "objc-parse.y" -{ - continue_class (objc_interface_context); - ; - break;} -case 370: -#line 2044 "objc-parse.y" -{ - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 371: -#line 2050 "objc-parse.y" -{ - objc_interface_context - = start_class (CLASS_INTERFACE_TYPE, yyvsp[-1].ttype, NULL_TREE, yyvsp[0].ttype); - continue_class (objc_interface_context); - ; - break;} -case 372: -#line 2057 "objc-parse.y" -{ - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 373: -#line 2063 "objc-parse.y" -{ - objc_interface_context = objc_ivar_context - = start_class (CLASS_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[-1].ttype); - objc_public_flag = 0; - ; - break;} -case 374: -#line 2069 "objc-parse.y" -{ - continue_class (objc_interface_context); - ; - break;} -case 375: -#line 2074 "objc-parse.y" -{ - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 376: -#line 2080 "objc-parse.y" -{ - objc_interface_context - = start_class (CLASS_INTERFACE_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); - continue_class (objc_interface_context); - ; - break;} -case 377: -#line 2087 "objc-parse.y" -{ - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 378: -#line 2093 "objc-parse.y" -{ - objc_implementation_context = objc_ivar_context - = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-1].ttype, NULL_TREE, NULL_TREE); - objc_public_flag = 0; - ; - break;} -case 379: -#line 2099 "objc-parse.y" -{ - objc_ivar_chain - = continue_class (objc_implementation_context); - ; - break;} -case 380: -#line 2105 "objc-parse.y" -{ - objc_implementation_context - = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[0].ttype, NULL_TREE, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); - ; - break;} -case 381: -#line 2113 "objc-parse.y" -{ - objc_implementation_context = objc_ivar_context - = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); - objc_public_flag = 0; - ; - break;} -case 382: -#line 2119 "objc-parse.y" -{ - objc_ivar_chain - = continue_class (objc_implementation_context); - ; - break;} -case 383: -#line 2125 "objc-parse.y" -{ - objc_implementation_context - = start_class (CLASS_IMPLEMENTATION_TYPE, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); - ; - break;} -case 384: -#line 2133 "objc-parse.y" -{ - objc_interface_context - = start_class (CATEGORY_INTERFACE_TYPE, yyvsp[-4].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); - continue_class (objc_interface_context); - ; - break;} -case 385: -#line 2140 "objc-parse.y" -{ - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 386: -#line 2146 "objc-parse.y" -{ - objc_implementation_context - = start_class (CATEGORY_IMPLEMENTATION_TYPE, yyvsp[-3].ttype, yyvsp[-1].ttype, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); - ; - break;} -case 387: -#line 2156 "objc-parse.y" -{ - remember_protocol_qualifiers (); - objc_interface_context - = start_protocol(PROTOCOL_INTERFACE_TYPE, yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 388: -#line 2162 "objc-parse.y" -{ - forget_protocol_qualifiers(); - finish_protocol(objc_interface_context); - objc_interface_context = NULL_TREE; - ; - break;} -case 389: -#line 2171 "objc-parse.y" -{ - yyval.ttype = NULL_TREE; - ; - break;} -case 390: -#line 2175 "objc-parse.y" -{ - if (yyvsp[-2].code == LT_EXPR && yyvsp[0].code == GT_EXPR) - yyval.ttype = yyvsp[-1].ttype; - else - YYERROR1; - ; - break;} -case 393: -#line 2189 "objc-parse.y" -{ objc_public_flag = 2; ; - break;} -case 394: -#line 2190 "objc-parse.y" -{ objc_public_flag = 0; ; - break;} -case 395: -#line 2191 "objc-parse.y" -{ objc_public_flag = 1; ; - break;} -case 396: -#line 2196 "objc-parse.y" -{ - yyval.ttype = NULL_TREE; - ; - break;} -case 398: -#line 2201 "objc-parse.y" -{ - if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); - ; - break;} -case 399: -#line 2219 "objc-parse.y" -{ - yyval.ttype = yyvsp[0].ttype; - resume_momentary (yyvsp[-1].itype); - ; - break;} -case 400: -#line 2224 "objc-parse.y" -{ - yyval.ttype = yyvsp[0].ttype; - resume_momentary (yyvsp[-1].itype); - ; - break;} -case 401: -#line 2229 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 402: -#line 2234 "objc-parse.y" -{ yyval.ttype = NULL_TREE; ; - break;} -case 405: -#line 2241 "objc-parse.y" -{ - yyval.ttype = add_instance_variable (objc_ivar_context, - objc_public_flag, - yyvsp[0].ttype, current_declspecs, - NULL_TREE); - ; - break;} -case 406: -#line 2248 "objc-parse.y" -{ - yyval.ttype = add_instance_variable (objc_ivar_context, - objc_public_flag, - yyvsp[-2].ttype, current_declspecs, yyvsp[0].ttype); - ; - break;} -case 407: -#line 2254 "objc-parse.y" -{ - yyval.ttype = add_instance_variable (objc_ivar_context, - objc_public_flag, - NULL_TREE, - current_declspecs, yyvsp[0].ttype); - ; - break;} -case 408: -#line 2264 "objc-parse.y" -{ - remember_protocol_qualifiers (); - if (objc_implementation_context) - objc_inherit_code = CLASS_METHOD_DECL; - else - fatal ("method definition not in class context"); - ; - break;} -case 409: -#line 2272 "objc-parse.y" -{ - forget_protocol_qualifiers (); - add_class_method (objc_implementation_context, yyvsp[0].ttype); - start_method_def (yyvsp[0].ttype); - objc_method_context = yyvsp[0].ttype; - ; - break;} -case 410: -#line 2279 "objc-parse.y" -{ - continue_method_def (); - ; - break;} -case 411: -#line 2283 "objc-parse.y" -{ - finish_method_def (); - objc_method_context = NULL_TREE; - ; - break;} -case 412: -#line 2289 "objc-parse.y" -{ - remember_protocol_qualifiers (); - if (objc_implementation_context) - objc_inherit_code = INSTANCE_METHOD_DECL; - else - fatal ("method definition not in class context"); - ; - break;} -case 413: -#line 2297 "objc-parse.y" -{ - forget_protocol_qualifiers (); - add_instance_method (objc_implementation_context, yyvsp[0].ttype); - start_method_def (yyvsp[0].ttype); - objc_method_context = yyvsp[0].ttype; - ; - break;} -case 414: -#line 2304 "objc-parse.y" -{ - continue_method_def (); - ; - break;} -case 415: -#line 2308 "objc-parse.y" -{ - finish_method_def (); - objc_method_context = NULL_TREE; - ; - break;} -case 417: -#line 2320 "objc-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 422: -#line 2327 "objc-parse.y" -{yyval.ttype = NULL_TREE; ; - break;} -case 426: -#line 2337 "objc-parse.y" -{ - objc_inherit_code = CLASS_METHOD_DECL; - ; - break;} -case 427: -#line 2341 "objc-parse.y" -{ - add_class_method (objc_interface_context, yyvsp[0].ttype); - ; - break;} -case 429: -#line 2347 "objc-parse.y" -{ - objc_inherit_code = INSTANCE_METHOD_DECL; - ; - break;} -case 430: -#line 2351 "objc-parse.y" -{ - add_instance_method (objc_interface_context, yyvsp[0].ttype); - ; - break;} -case 432: -#line 2359 "objc-parse.y" -{ - yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-2].ttype, yyvsp[0].ttype, NULL_TREE); - ; - break;} -case 433: -#line 2364 "objc-parse.y" -{ - yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[0].ttype, NULL_TREE); - ; - break;} -case 434: -#line 2369 "objc-parse.y" -{ - yyval.ttype = build_method_decl (objc_inherit_code, yyvsp[-3].ttype, yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 435: -#line 2374 "objc-parse.y" -{ - yyval.ttype = build_method_decl (objc_inherit_code, NULL_TREE, yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 444: -#line 2404 "objc-parse.y" -{ resume_momentary (yyvsp[-2].itype); ; - break;} -case 445: -#line 2406 "objc-parse.y" -{ shadow_tag (yyvsp[-1].ttype); ; - break;} -case 446: -#line 2408 "objc-parse.y" -{ pedwarn ("empty declaration"); ; - break;} -case 447: -#line 2413 "objc-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 448: -#line 2415 "objc-parse.y" -{ push_parm_decl (yyvsp[0].ttype); ; - break;} -case 449: -#line 2423 "objc-parse.y" -{ yyval.ttype = build_tree_list (current_declspecs, yyvsp[0].ttype) ; ; - break;} -case 450: -#line 2425 "objc-parse.y" -{ yyval.ttype = build_tree_list (current_declspecs, yyvsp[0].ttype) ; ; - break;} -case 451: -#line 2427 "objc-parse.y" -{ yyval.ttype = build_tree_list (current_declspecs, yyvsp[0].ttype) ; ; - break;} -case 452: -#line 2432 "objc-parse.y" -{ - yyval.ttype = NULL_TREE; - ; - break;} -case 453: -#line 2436 "objc-parse.y" -{ - /* oh what a kludge! */ - yyval.ttype = (tree)1; - ; - break;} -case 454: -#line 2441 "objc-parse.y" -{ - pushlevel (0); - ; - break;} -case 455: -#line 2445 "objc-parse.y" -{ - /* returns a tree list node generated by get_parm_info */ - yyval.ttype = yyvsp[0].ttype; - poplevel (0, 0, 0); - ; - break;} -case 458: -#line 2460 "objc-parse.y" -{ - yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 463: -#line 2473 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 464: -#line 2474 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 465: -#line 2475 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 466: -#line 2476 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 467: -#line 2477 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 468: -#line 2478 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 469: -#line 2479 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 470: -#line 2480 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 471: -#line 2481 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 472: -#line 2482 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 473: -#line 2483 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 474: -#line 2484 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 475: -#line 2485 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 476: -#line 2486 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 477: -#line 2487 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 478: -#line 2488 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 479: -#line 2489 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 480: -#line 2490 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 481: -#line 2491 "objc-parse.y" -{ yyval.ttype = get_identifier (token_buffer); ; - break;} -case 484: -#line 2497 "objc-parse.y" -{ - yyval.ttype = build_keyword_decl (yyvsp[-5].ttype, yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 485: -#line 2502 "objc-parse.y" -{ - yyval.ttype = build_keyword_decl (yyvsp[-2].ttype, NULL_TREE, yyvsp[0].ttype); - ; - break;} -case 486: -#line 2507 "objc-parse.y" -{ - yyval.ttype = build_keyword_decl (NULL_TREE, yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 487: -#line 2512 "objc-parse.y" -{ - yyval.ttype = build_keyword_decl (NULL_TREE, NULL_TREE, yyvsp[0].ttype); - ; - break;} -case 491: -#line 2525 "objc-parse.y" -{ - yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 492: -#line 2533 "objc-parse.y" -{ - if (TREE_CHAIN (yyvsp[0].ttype) == NULL_TREE) - /* just return the expr., remove a level of indirection */ - yyval.ttype = TREE_VALUE (yyvsp[0].ttype); - else - /* we have a comma expr., we will collapse later */ - yyval.ttype = yyvsp[0].ttype; - ; - break;} -case 493: -#line 2545 "objc-parse.y" -{ - yyval.ttype = build_tree_list (yyvsp[-2].ttype, yyvsp[0].ttype); - ; - break;} -case 494: -#line 2549 "objc-parse.y" -{ - yyval.ttype = build_tree_list (NULL_TREE, yyvsp[0].ttype); - ; - break;} -case 496: -#line 2557 "objc-parse.y" -{ - yyval.ttype = get_class_reference (yyvsp[0].ttype); - ; - break;} -case 497: -#line 2564 "objc-parse.y" -{ objc_receiver_context = 1; ; - break;} -case 498: -#line 2566 "objc-parse.y" -{ objc_receiver_context = 0; ; - break;} -case 499: -#line 2568 "objc-parse.y" -{ - yyval.ttype = build_tree_list (yyvsp[-3].ttype, yyvsp[-1].ttype); - ; - break;} -case 503: -#line 2581 "objc-parse.y" -{ - yyval.ttype = chainon (yyvsp[-1].ttype, yyvsp[0].ttype); - ; - break;} -case 504: -#line 2588 "objc-parse.y" -{ - yyval.ttype = build_tree_list (yyvsp[-1].ttype, NULL_TREE); - ; - break;} -case 505: -#line 2592 "objc-parse.y" -{ - yyval.ttype = build_tree_list (NULL_TREE, NULL_TREE); - ; - break;} -case 506: -#line 2599 "objc-parse.y" -{ - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 507: -#line 2606 "objc-parse.y" -{ - yyval.ttype = yyvsp[-1].ttype; - ; - break;} -case 508: -#line 2615 "objc-parse.y" -{ - yyval.ttype = groktypename (yyvsp[-1].ttype); - ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 440 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} -#line 2620 "objc-parse.y" - diff --git a/gnu/usr.bin/gcc2/cc1obj/objc-tree.def b/gnu/usr.bin/gcc2/cc1obj/objc-tree.def deleted file mode 100644 index d7d38622d51..00000000000 --- a/gnu/usr.bin/gcc2/cc1obj/objc-tree.def +++ /dev/null @@ -1,36 +0,0 @@ -/* This file contains the definitions and documentation for the - additional tree codes used in the Objective C front end (see tree.def - for the standard codes). - Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* Objective-C types. */ -DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", "t", 0) -DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type", "t", 0) -DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", "t", 0) -DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type","t",0) -DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", "t", 0) - -/* Objective-C decls. */ -DEFTREECODE (KEYWORD_DECL, "keyword_decl", "d", 0) -DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", "d", 0) -DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", "d", 0) - -/* Objective-C constants. */ -DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", "c", 3) diff --git a/gnu/usr.bin/gcc2/cc1plus/Makefile b/gnu/usr.bin/gcc2/cc1plus/Makefile deleted file mode 100644 index 45676575ac5..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Id: Makefile,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $ - -PROG= cc1plus - -SRCS= cp-parse.c cp-decl.c cp-decl2.c cp-typeck.c cp-type2.c \ - cp-tree.c cp-ptree.c cp-cvt.c cp-search.c cp-lex.c \ - cp-gc.c cp-call.c cp-class.c cp-init.c cp-method.c \ - cp-except.c cp-expr.c cp-pt.c cp-edsel.c cp-xref.c \ - cp-spew.c - -.include <../Makefile.cc1> diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-call.c b/gnu/usr.bin/gcc2/cc1plus/cp-call.c deleted file mode 100644 index 7ef22e98a84..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-call.c +++ /dev/null @@ -1,2826 +0,0 @@ -/* Functions related to invoking methods and overloaded functions. - Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-call.c,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $"; -#endif /* not lint */ - -/* High-level class interface. */ - -#include "config.h" -#include "tree.h" -#include -#include "cp-tree.h" -#include "flags.h" - -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern void sorry (); - -extern int inhibit_warnings; -extern int flag_assume_nonnull_objects; -extern tree ctor_label, dtor_label; - -/* From cp-typeck.c: */ -extern tree unary_complex_lvalue (); - -/* Compute the ease with which a conversion can be performed - between an expected and the given type. */ -static int convert_harshness (); - -#define EVIL_HARSHNESS(ARG) ((ARG) & 1) -#define ELLIPSIS_HARSHNESS(ARG) ((ARG) & 2) -#define USER_HARSHNESS(ARG) ((ARG) & 4) -#define CONTRAVARIANT_HARSHNESS(ARG) ((ARG) & 8) -#define BASE_DERIVED_HARSHNESS(ARG) ((ARG) & 16) -#define INT_TO_BD_HARSHNESS(ARG) (((ARG) << 5) | 16) -#define INT_FROM_BD_HARSHNESS(ARG) ((ARG) >> 5) -#define INT_TO_EASY_HARSHNESS(ARG) ((ARG) << 5) -#define INT_FROM_EASY_HARSHNESS(ARG) ((ARG) >> 5) -#define ONLY_EASY_HARSHNESS(ARG) (((ARG) & 31) == 0) -#define CONST_HARSHNESS(ARG) ((ARG) & 2048) - -/* Ordering function for overload resolution. */ -int -rank_for_overload (x, y) - struct candidate *x, *y; -{ - if (y->evil - x->evil) - return y->evil - x->evil; - if (CONST_HARSHNESS (y->harshness[0]) ^ CONST_HARSHNESS (x->harshness[0])) - return y->harshness[0] - x->harshness[0]; - if (y->ellipsis - x->ellipsis) - return y->ellipsis - x->ellipsis; - if (y->user - x->user) - return y->user - x->user; - if (y->b_or_d - x->b_or_d) - return y->b_or_d - x->b_or_d; - return y->easy - x->easy; -} - -/* TYPE is the type we wish to convert to. PARM is the parameter - we have to work with. We use a somewhat arbitrary cost function - to measure this conversion. */ -static int -convert_harshness (type, parmtype, parm) - register tree type, parmtype; - tree parm; -{ - register enum tree_code codel = TREE_CODE (type); - register enum tree_code coder = TREE_CODE (parmtype); - -#ifdef GATHER_STATISTICS - n_convert_harshness++; -#endif - - if (TYPE_MAIN_VARIANT (parmtype) == TYPE_MAIN_VARIANT (type)) - return 0; - - if (coder == ERROR_MARK) - return 1; - - if (codel == POINTER_TYPE - && (coder == METHOD_TYPE || coder == FUNCTION_TYPE)) - { - tree p1, p2; - int harshness, new_harshness; - - /* Get to the METHOD_TYPE or FUNCTION_TYPE that this might be. */ - type = TREE_TYPE (type); - - if (coder != TREE_CODE (type)) - return 1; - - harshness = 0; - - /* We allow the default conversion between function type - and pointer-to-function type for free. */ - if (type == parmtype) - return 0; - - /* Compare return types. */ - p1 = TREE_TYPE (type); - p2 = TREE_TYPE (parmtype); - new_harshness = convert_harshness (p1, p2, NULL_TREE); - if (new_harshness & 1) - return 1; - - if (BASE_DERIVED_HARSHNESS (new_harshness)) - { - tree binfo; - - /* This only works for pointers. */ - if (TREE_CODE (p1) != POINTER_TYPE - && TREE_CODE (p1) != REFERENCE_TYPE) - return 1; - - p1 = TREE_TYPE (p1); - p2 = TREE_TYPE (p2); - if (CONTRAVARIANT_HARSHNESS (new_harshness)) - binfo = get_binfo (p2, p1, 0); - else - binfo = get_binfo (p1, p2, 0); - - if (! BINFO_OFFSET_ZEROP (binfo)) - { - static int explained = 0; - if (CONTRAVARIANT_HARSHNESS (new_harshness)) - message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p2, p1); - else - message_2_types (sorry, "cannot cast `%d' to `%d' at function call site", p1, p2); - - if (! explained++) - sorry ("(because pointer values change during conversion)"); - return 1; - } - } - - harshness |= new_harshness; - - p1 = TYPE_ARG_TYPES (type); - p2 = TYPE_ARG_TYPES (parmtype); - while (p1 && TREE_VALUE (p1) != void_type_node - && p2 && TREE_VALUE (p2) != void_type_node) - { - new_harshness = convert_harshness (TREE_VALUE (p1), TREE_VALUE (p2), NULL_TREE); - if (EVIL_HARSHNESS (new_harshness)) - return 1; - - if (BASE_DERIVED_HARSHNESS (new_harshness)) - { - /* This only works for pointers and references. */ - if (TREE_CODE (TREE_VALUE (p1)) != POINTER_TYPE - && TREE_CODE (TREE_VALUE (p1)) != REFERENCE_TYPE) - return 1; - new_harshness ^= CONTRAVARIANT_HARSHNESS (new_harshness); - harshness |= new_harshness; - } - /* This trick allows use to accumulate easy type - conversions without messing up the bits that encode - info about more involved things. */ - else if (ONLY_EASY_HARSHNESS (new_harshness)) - harshness += new_harshness; - else - harshness |= new_harshness; - p1 = TREE_CHAIN (p1); - p2 = TREE_CHAIN (p2); - } - if (p1 == p2) - return harshness; - if (p2) - return p1 ? 1 : (harshness | ELLIPSIS_HARSHNESS (-1)); - if (p1) - return harshness | (TREE_PURPOSE (p1) == NULL_TREE); - } - else if (codel == POINTER_TYPE && coder == OFFSET_TYPE) - { - /* XXX: Note this is set a few times, but it's never actually - used! (bpk) */ - int harshness; - - /* Get to the OFFSET_TYPE that this might be. */ - type = TREE_TYPE (type); - - if (coder != TREE_CODE (type)) - return 1; - - harshness = 0; - - if (TYPE_OFFSET_BASETYPE (type) == TYPE_OFFSET_BASETYPE (parmtype)) - harshness = 0; - else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (type), - TYPE_OFFSET_BASETYPE (parmtype))) - harshness = INT_TO_BD_HARSHNESS (1); - else if (UNIQUELY_DERIVED_FROM_P (TYPE_OFFSET_BASETYPE (parmtype), - TYPE_OFFSET_BASETYPE (type))) - harshness = CONTRAVARIANT_HARSHNESS (-1); - else - return 1; - /* Now test the OFFSET_TYPE's target compatibility. */ - type = TREE_TYPE (type); - parmtype = TREE_TYPE (parmtype); - } - - if (coder == UNKNOWN_TYPE) - { - if (codel == FUNCTION_TYPE - || codel == METHOD_TYPE - || (codel == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))) - return 0; - return 1; - } - - if (coder == VOID_TYPE) - return 1; - - if (codel == ENUMERAL_TYPE || codel == INTEGER_TYPE) - { - /* Control equivalence of ints an enums. */ - - if (codel == ENUMERAL_TYPE - && flag_int_enum_equivalence == 0) - { - /* Enums can be converted to ints, but not vice-versa. */ - if (coder != ENUMERAL_TYPE - || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (parmtype)) - return 1; - } - - /* else enums and ints (almost) freely interconvert. */ - - if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) - { - int easy = TREE_UNSIGNED (type) ^ TREE_UNSIGNED (parmtype); - if (codel != coder) - easy += 1; - if (TYPE_MODE (type) != TYPE_MODE (parmtype)) - easy += 2; - return INT_TO_EASY_HARSHNESS (easy); - } - else if (coder == REAL_TYPE) - return INT_TO_EASY_HARSHNESS (4); - } - - if (codel == REAL_TYPE) - if (coder == REAL_TYPE) - /* Shun converting between float and double if a choice exists. */ - { - if (TYPE_MODE (type) != TYPE_MODE (parmtype)) - return INT_TO_EASY_HARSHNESS (2); - return 0; - } - else if (coder == INTEGER_TYPE || coder == ENUMERAL_TYPE) - return INT_TO_EASY_HARSHNESS (4); - - /* convert arrays which have not previously been converted. */ - if (codel == ARRAY_TYPE) - codel = POINTER_TYPE; - if (coder == ARRAY_TYPE) - coder = POINTER_TYPE; - - /* Conversions among pointers */ - if (codel == POINTER_TYPE && coder == POINTER_TYPE) - { - register tree ttl = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - register tree ttr = TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)); - int penalty = 4 * (ttl != ttr); - /* Anything converts to void *. void * converts to anything. - Since these may be `const void *' (etc.) use VOID_TYPE - instead of void_type_node. - Otherwise, the targets must be the same, - except that we do allow (at some cost) conversion - between signed and unsinged pointer types. */ - - if ((TREE_CODE (ttl) == METHOD_TYPE - || TREE_CODE (ttl) == FUNCTION_TYPE) - && TREE_CODE (ttl) == TREE_CODE (ttr)) - { - if (comptypes (ttl, ttr, -1)) - return INT_TO_EASY_HARSHNESS (penalty); - return 1; - } - - if (!(TREE_CODE (ttl) == VOID_TYPE - || TREE_CODE (ttr) == VOID_TYPE - || (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (ttr) - && (ttl = unsigned_type (ttl), - ttr = unsigned_type (ttr), - penalty = 10, 0)) - || (comp_target_types (ttl, ttr, 0)))) - return 1; - - if (penalty == 10) - return INT_TO_EASY_HARSHNESS (10); - if (ttr == ttl) - return INT_TO_BD_HARSHNESS (0); - - if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) - { - int b_or_d = get_base_distance (ttl, ttr, 0, 0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (ttr, ttl, 0, 0); - if (b_or_d < 0) - return 1; - return CONTRAVARIANT_HARSHNESS (-1); - } - return INT_TO_BD_HARSHNESS (b_or_d); - } - /* If converting from a `class*' to a `void*', make it - less favorable than any inheritance relationship. */ - if (TREE_CODE (ttl) == VOID_TYPE && IS_AGGR_TYPE (ttr)) - return INT_TO_BD_HARSHNESS (CLASSTYPE_MAX_DEPTH (ttr)+1); - return INT_TO_EASY_HARSHNESS (penalty); - } - - if (codel == POINTER_TYPE && coder == INTEGER_TYPE) - { - /* This is not a bad match, but don't let it beat - integer-enum combinations. */ - if (parm && integer_zerop (parm)) - return INT_TO_EASY_HARSHNESS (4); - } - - /* C++: one of the types must be a reference type. */ - { - tree ttl, ttr; - register tree intype = TYPE_MAIN_VARIANT (parmtype); - register enum tree_code form = TREE_CODE (intype); - int penalty; - - if (codel == REFERENCE_TYPE || coder == REFERENCE_TYPE) - { - ttl = TYPE_MAIN_VARIANT (type); - - if (codel == REFERENCE_TYPE) - { - ttl = TREE_TYPE (ttl); - - /* When passing a non-const argument into a const reference, - dig it a little, so a non-const reference is preferred over - this one. (mrs) */ - if (parm && TREE_READONLY (ttl) && ! TREE_READONLY (parm)) - penalty = 2; - else - penalty = 0; - - ttl = TYPE_MAIN_VARIANT (ttl); - - if (form == OFFSET_TYPE) - { - intype = TREE_TYPE (intype); - form = TREE_CODE (intype); - } - - if (form == REFERENCE_TYPE) - { - intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype)); - - if (ttl == intype) - return 0; - penalty = 2; - } - else - { - /* Can reference be built up? */ - if (ttl == intype && penalty == 0) { - /* Because the READONLY bits and VOLATILE bits are not - always in the type, this extra check is necessary. The - problem should be fixed someplace else, and this extra - code removed. - - Also, if type if a reference, the readonly bits could - either be in the outer type (with reference) or on the - inner type (the thing being referenced). (mrs) */ - if (parm - && ((TREE_READONLY (parm) - && ! (TYPE_READONLY (type) - || (TREE_CODE (type) == REFERENCE_TYPE - && TYPE_READONLY (TREE_TYPE (type))))) - || (TREE_SIDE_EFFECTS (parm) - && ! (TYPE_VOLATILE (type) - || (TREE_CODE (type) == REFERENCE_TYPE - && TYPE_VOLATILE (TREE_TYPE (type))))))) - - penalty = 2; - else - return 0; - } - else - penalty = 2; - } - } - else if (form == REFERENCE_TYPE) - { - if (parm) - { - tree tmp = convert_from_reference (parm); - intype = TYPE_MAIN_VARIANT (TREE_TYPE (tmp)); - } - else - { - intype = parmtype; - do - { - intype = TREE_TYPE (intype); - } - while (TREE_CODE (intype) == REFERENCE_TYPE); - intype = TYPE_MAIN_VARIANT (intype); - } - - if (ttl == intype) - return 0; - else - penalty = 2; - } - - if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype)) - { - ttl = unsigned_type (ttl); - intype = unsigned_type (intype); - penalty += 2; - } - - ttr = intype; - - /* If the initializer is not an lvalue, then it does not - matter if we make life easier for the programmer - by creating a temporary variable with which to - hold the result. */ - if (parm && (coder == INTEGER_TYPE - || coder == ENUMERAL_TYPE - || coder == REAL_TYPE) - && ! lvalue_p (parm)) - return (convert_harshness (ttl, ttr, NULL_TREE) - | INT_TO_EASY_HARSHNESS (penalty)); - - if (ttl == ttr) - { - if (penalty) - return INT_TO_EASY_HARSHNESS (penalty); - return INT_TO_BD_HARSHNESS (0); - } - - /* Pointers to voids always convert for pointers. But - make them less natural than more specific matches. */ - if (TREE_CODE (ttl) == POINTER_TYPE && TREE_CODE (ttr) == POINTER_TYPE) - if (TREE_TYPE (ttl) == void_type_node - || TREE_TYPE (ttr) == void_type_node) - return INT_TO_EASY_HARSHNESS (penalty+1); - - if (parm && codel != REFERENCE_TYPE) - return (convert_harshness (ttl, ttr, NULL_TREE) - | INT_TO_EASY_HARSHNESS (penalty)); - - /* Here it does matter. If this conversion is from - derived to base, allow it. Otherwise, types must - be compatible in the strong sense. */ - if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) - { - int b_or_d = get_base_distance (ttl, ttr, 0, 0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (ttr, ttl, 0, 0); - if (b_or_d < 0) - return 1; - return CONTRAVARIANT_HARSHNESS (-1); - } - /* Say that this conversion is relatively painless. - If it turns out that there is a user-defined X(X&) - constructor, then that will be invoked, but that's - preferable to dealing with other user-defined conversions - that may produce surprising results. */ - return INT_TO_BD_HARSHNESS (b_or_d); - } - - if (comp_target_types (ttl, intype, 1)) - return INT_TO_EASY_HARSHNESS (penalty); - } - } - if (codel == RECORD_TYPE && coder == RECORD_TYPE) - { - int b_or_d = get_base_distance (type, parmtype, 0, 0); - if (b_or_d < 0) - { - b_or_d = get_base_distance (parmtype, type, 0, 0); - if (b_or_d < 0) - return 1; - return CONTRAVARIANT_HARSHNESS (-1); - } - return INT_TO_BD_HARSHNESS (b_or_d); - } - return 1; -} - -/* Algorithm: Start out with no strikes against. For each argument - which requires a (subjective) hard conversion (such as between - floating point and integer), issue a strike. If there are the same - number of formal and actual parameters in the list, there will be at - least on strike, otherwise an exact match would have been found. If - there are not the same number of arguments in the type lists, we are - not dead yet: a `...' means that we can have more parms then were - declared, and if we wind up in the default argument section of the - list those can be used as well. If an exact match could be found for - one of those cases, return it immediately. Otherwise, rank the fields - so that fields with fewer strikes are tried first. - - Conversions between builtin and user-defined types are allowed, but - no function involving such a conversion is preferred to one which - does not require such a conversion. Furthermore, such conversions - must be unique. */ - -void -compute_conversion_costs (function, tta_in, cp, arglen) - tree function; - tree tta_in; - struct candidate *cp; - int arglen; -{ - tree ttf_in = TYPE_ARG_TYPES (TREE_TYPE (function)); - tree ttf = ttf_in; - tree tta = tta_in; - - /* Start out with no strikes against. */ - int evil_strikes = 0; - int ellipsis_strikes = 0; - int user_strikes = 0; - int b_or_d_strikes = 0; - int easy_strikes = 0; - - int strike_index = 0, win, lose; - -#ifdef GATHER_STATISTICS - n_compute_conversion_costs++; -#endif - - cp->function = function; - cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE; - cp->u.bad_arg = 0; /* optimistic! */ - - bzero (cp->harshness, (arglen+1) * sizeof (short)); - - while (ttf && tta) - { - int harshness; - - if (ttf == void_list_node) - break; - - if (type_unknown_p (TREE_VALUE (tta))) - { - /* Must perform some instantiation here. */ - tree rhs = TREE_VALUE (tta); - tree lhstype = TREE_VALUE (ttf); - - /* Keep quiet about possible contravariance violations. */ - int old_inhibit_warnings = inhibit_warnings; - inhibit_warnings = 1; - - /* @@ This is to undo what `grokdeclarator' does to - parameter types. It really should go through - something more general. */ - - TREE_TYPE (tta) = unknown_type_node; - rhs = instantiate_type (lhstype, rhs, 0); - inhibit_warnings = old_inhibit_warnings; - - if (TREE_CODE (rhs) == ERROR_MARK) - harshness = 1; - else - { - harshness = convert_harshness (lhstype, TREE_TYPE (rhs), rhs); - /* harshness |= 2; */ - } - } - else - harshness = convert_harshness (TREE_VALUE (ttf), TREE_TYPE (TREE_VALUE (tta)), TREE_VALUE (tta)); - - cp->harshness[strike_index] = harshness; - if (EVIL_HARSHNESS (harshness) - || CONTRAVARIANT_HARSHNESS (harshness)) - { - cp->u.bad_arg = strike_index; - evil_strikes = 1; - } - else if (ELLIPSIS_HARSHNESS (harshness)) - { - ellipsis_strikes += 1; - } -#if 0 - /* This is never set by `convert_harshness'. */ - else if (USER_HARSHNESS (harshness)) - { - user_strikes += 1; - } -#endif - else if (BASE_DERIVED_HARSHNESS (harshness)) - { - b_or_d_strikes += INT_FROM_BD_HARSHNESS (harshness); - } - else - easy_strikes += INT_FROM_EASY_HARSHNESS (harshness); - ttf = TREE_CHAIN (ttf); - tta = TREE_CHAIN (tta); - strike_index += 1; - } - - if (tta) - { - /* ran out of formals, and parmlist is fixed size. */ - if (ttf /* == void_type_node */) - { - cp->evil = 1; - cp->u.bad_arg = -1; - return; - } - } - else if (ttf && ttf != void_list_node) - { - /* ran out of actuals, and no defaults. */ - if (TREE_PURPOSE (ttf) == NULL_TREE) - { - cp->evil = 1; - cp->u.bad_arg = -2; - return; - } - /* Store index of first default. */ - cp->harshness[arglen] = strike_index+1; - } - else cp->harshness[arglen] = 0; - - /* Argument list lengths work out, so don't need to check them again. */ - if (evil_strikes) - { - /* We do not check for derived->base conversions here, since in - no case would they give evil strike counts, unless such conversions - are somehow ambiguous. */ - - /* See if any user-defined conversions apply. - But make sure that we do not loop. */ - static int dont_convert_types = 0; - - if (dont_convert_types) - { - cp->evil = 1; - return; - } - - win = 0; /* Only get one chance to win. */ - ttf = TYPE_ARG_TYPES (TREE_TYPE (function)); - tta = tta_in; - strike_index = 0; - evil_strikes = 0; - - while (ttf && tta) - { - if (ttf == void_list_node) - break; - - lose = cp->harshness[strike_index]; - if (EVIL_HARSHNESS (lose) - || CONTRAVARIANT_HARSHNESS (lose)) - { - tree actual_type = TREE_TYPE (TREE_VALUE (tta)); - tree formal_type = TREE_VALUE (ttf); - - dont_convert_types = 1; - - if (TREE_CODE (formal_type) == REFERENCE_TYPE) - formal_type = TREE_TYPE (formal_type); - if (TREE_CODE (actual_type) == REFERENCE_TYPE) - actual_type = TREE_TYPE (actual_type); - - if (formal_type != error_mark_node - && actual_type != error_mark_node) - { - formal_type = TYPE_MAIN_VARIANT (formal_type); - actual_type = TYPE_MAIN_VARIANT (actual_type); - - if (TYPE_HAS_CONSTRUCTOR (formal_type)) - { - /* If it has a constructor for this type, try to use it. */ - if (convert_to_aggr (formal_type, TREE_VALUE (tta), 0, 1) - != error_mark_node) - { - /* @@ There is no way to save this result yet. - @@ So success is NULL_TREE for now. */ - win++; - } - } - if (TYPE_LANG_SPECIFIC (actual_type) && TYPE_HAS_CONVERSION (actual_type)) - { - if (TREE_CODE (formal_type) == INTEGER_TYPE - && TYPE_HAS_INT_CONVERSION (actual_type)) - win++; - else if (TREE_CODE (formal_type) == REAL_TYPE - && TYPE_HAS_REAL_CONVERSION (actual_type)) - win++; - else - { - tree conv = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_VALUE (tta), 0); - if (conv) - { - if (conv == error_mark_node) - win += 2; - else - win++; - } - else if (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE) - { - conv = build_type_conversion (CALL_EXPR, formal_type, TREE_VALUE (tta), 0); - if (conv) - { - if (conv == error_mark_node) - win += 2; - else - win++; - } - } - } - } - } - dont_convert_types = 0; - - if (win == 1) - { - user_strikes += 1; - cp->harshness[strike_index] = USER_HARSHNESS (-1); - win = 0; - } - else - { - if (cp->u.bad_arg > strike_index) - cp->u.bad_arg = strike_index; - - evil_strikes = win ? 2 : 1; - break; - } - } - - ttf = TREE_CHAIN (ttf); - tta = TREE_CHAIN (tta); - strike_index += 1; - } - } - - /* Const member functions get a small penalty because defaulting - to const is less useful than defaulting to non-const. */ - /* This is bogus, it does not correspond to anything in the ARM. - This code will be fixed when this entire section is rewritten - to conform to the ARM. (mrs) */ - if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) - { - if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (ttf_in)))) - { - cp->harshness[0] += INT_TO_EASY_HARSHNESS (1); - ++easy_strikes; - } - else - { - /* Calling a non-const member function from a const member function - is probably invalid, but for now we let it only draw a warning. - We indicate that such a mismatch has occurred by setting the - harshness to a maximum value. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (tta_in))) == POINTER_TYPE - && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (TREE_VALUE (tta_in)))))) - cp->harshness[0] |= CONST_HARSHNESS (-1); - } - } - - cp->evil = evil_strikes; - cp->ellipsis = ellipsis_strikes; - cp->user = user_strikes; - cp->b_or_d = b_or_d_strikes; - cp->easy = easy_strikes; -} - -/* When one of several possible overloaded functions and/or methods - can be called, choose the best candidate for overloading. - - BASETYPE is the context from which we start method resolution - or NULL if we are comparing overloaded functions. - CANDIDATES is the array of candidates we have to choose from. - N_CANDIDATES is the length of CANDIDATES. - PARMS is a TREE_LIST of parameters to the function we'll ultimately - choose. It is modified in place when resolving methods. It is not - modified in place when resolving overloaded functions. - LEN is the length of the parameter list. */ - -static struct candidate * -ideal_candidate (basetype, candidates, n_candidates, parms, len) - tree basetype; - struct candidate *candidates; - int n_candidates; - tree parms; - int len; -{ - struct candidate *cp = candidates + n_candidates; - int index, i; - tree ttf; - - qsort (candidates, /* char *base */ - n_candidates, /* int nel */ - sizeof (struct candidate), /* int width */ - rank_for_overload); /* int (*compar)() */ - - /* If the best candidate requires user-defined conversions, - and its user-defined conversions are a strict subset - of all other candidates requiring user-defined conversions, - then it is, in fact, the best. */ - for (i = -1; cp + i != candidates; i--) - if (cp[i].user == 0) - break; - - if (i < -1) - { - tree ttf0; - - /* Check that every other candidate requires those conversions - as a strict subset of their conversions. */ - if (cp[i].user == cp[-1].user) - goto non_subset; - - /* Look at subset relationship more closely. */ - while (i != -1) - { - for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), - ttf0 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)), - index = 0; - index < len; - ttf = TREE_CHAIN (ttf), ttf0 = TREE_CHAIN (ttf0), index++) - if (USER_HARSHNESS (cp[i].harshness[index])) - { - /* If our "best" candidate also needs a conversion, - it must be the same one. */ - if (USER_HARSHNESS (cp[-1].harshness[index]) - && TREE_VALUE (ttf) != TREE_VALUE (ttf0)) - goto non_subset; - } - i++; - } - /* The best was the best. */ - return cp - 1; - non_subset: - /* Use other rules for determining "bestness". */ - ; - } - - /* If the best two candidates we find require user-defined - conversions, we may need to report and error message. */ - if (cp[-1].user && cp[-2].user - && (cp[-1].b_or_d || cp[-2].b_or_d == 0)) - { - /* If the best two methods found involved user-defined - type conversions, then we must see whether one - of them is exactly what we wanted. If not, then - we have an ambiguity. */ - int best = 0; - tree tta = parms; - tree f1; -#if 0 - /* for LUCID */ - tree p1; -#endif - - /* Stash all of our parameters in safe places - so that we can perform type conversions in place. */ - while (tta) - { - TREE_PURPOSE (tta) = TREE_VALUE (tta); - tta = TREE_CHAIN (tta); - } - - i = 0; - do - { - int exact_conversions = 0; - - i -= 1; - tta = parms; - if (DECL_STATIC_FUNCTION_P (cp[i].function)) - tta = TREE_CHAIN (tta); - /* special note, we don't go through len parameters, because we - may only need len-1 parameters because of a call to a static - member. */ - for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), index = 0; - tta; - tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) - { - if (USER_HARSHNESS (cp[i].harshness[index])) - { - tree this_parm = build_type_conversion (CALL_EXPR, TREE_VALUE (ttf), TREE_PURPOSE (tta), 2); - if (basetype != NULL_TREE) - TREE_VALUE (tta) = this_parm; - if (this_parm) - { - if (TREE_CODE (this_parm) != CONVERT_EXPR - && (TREE_CODE (this_parm) != NOP_EXPR - || comp_target_types (TREE_TYPE (this_parm), - TREE_TYPE (TREE_OPERAND (this_parm, 0)), 1))) - exact_conversions += 1; - } - else if (PROMOTES_TO_AGGR_TYPE (TREE_VALUE (ttf), REFERENCE_TYPE)) - { - /* To get here we had to have succeeded via - a constructor. */ - TREE_VALUE (tta) = TREE_PURPOSE (tta); - exact_conversions += 1; - } - } - } - if (exact_conversions == cp[i].user) - { - if (best == 0) - { - best = i; - f1 = cp[best].function; -#if 0 - /* For LUCID */ - p1 = TYPE_ARG_TYPES (TREE_TYPE (f1)); -#endif - } - else - { - /* Don't complain if next best is from base class. */ - tree f2 = cp[i].function; - - if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE - && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE - && BASE_DERIVED_HARSHNESS (cp[i].harshness[0]) - && cp[best].harshness[0] < cp[i].harshness[0]) - { -#if 0 - tree p2 = TYPE_ARG_TYPES (TREE_TYPE (f2)); - /* For LUCID. */ - if (! compparms (TREE_CHAIN (p1), TREE_CHAIN (p2), 1)) - goto ret0; - else -#endif - continue; - } - else - { - /* Ensure that there's nothing ambiguous about these - two fns. */ - int identical = 1; - for (index = 0; index < len; index++) - { - /* Type conversions must be piecewise equivalent. */ - if (USER_HARSHNESS (cp[best].harshness[index]) - != USER_HARSHNESS (cp[i].harshness[index])) - goto ret0; - /* If there's anything we like better about the - other function, consider it ambiguous. */ - if (cp[i].harshness[index] < cp[best].harshness[index]) - goto ret0; - /* If any single one it diffent, then the whole is - not identical. */ - if (cp[i].harshness[index] != cp[best].harshness[index]) - identical = 0; - } - - /* If we can't tell the difference between the two, it - is ambiguous. */ - if (identical) - goto ret0; - - /* If we made it to here, it means we're satisfied that - BEST is still best. */ - continue; - } - } - } - } while (cp + i != candidates); - - if (best) - { - int exact_conversions = cp[best].user; - tta = parms; - if (DECL_STATIC_FUNCTION_P (cp[best].function)) - tta = TREE_CHAIN (parms); - for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[best].function)), index = 0; - exact_conversions > 0; - tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) - { - if (USER_HARSHNESS (cp[best].harshness[index])) - { - /* We must now fill in the slot we left behind. - @@ This could be optimized to use the value previously - @@ computed by build_type_conversion in some cases. */ - if (basetype != NULL_TREE) - TREE_VALUE (tta) = convert (TREE_VALUE (ttf), TREE_PURPOSE (tta)); - exact_conversions -= 1; - } - else TREE_VALUE (tta) = TREE_PURPOSE (tta); - } - return cp + best; - } - goto ret0; - } - /* If the best two candidates we find both use default parameters, - we may need to report and error. Don't need to worry if next-best - candidate is forced to use user-defined conversion when best is not. */ - if (cp[-2].user == 0 - && cp[-1].harshness[len] != 0 && cp[-2].harshness[len] != 0) - { - tree tt1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)); - tree tt2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function)); - unsigned i = cp[-1].harshness[len]; - - if (cp[-2].harshness[len] < i) - i = cp[-2].harshness[len]; - while (--i > 0) - { - if (TYPE_MAIN_VARIANT (TREE_VALUE (tt1)) - != TYPE_MAIN_VARIANT (TREE_VALUE (tt2))) - /* These lists are not identical, so we can choose our best candidate. */ - return cp - 1; - tt1 = TREE_CHAIN (tt1); - tt2 = TREE_CHAIN (tt2); - } - /* To get here, both lists had the same parameters up to the defaults - which were used. This is an ambiguous request. */ - goto ret0; - } - - /* Otherwise, return our best candidate. Note that if we get candidates - from independent base classes, we have an ambiguity, even if one - argument list look a little better than another one. */ - if (cp[-1].b_or_d && basetype && TYPE_USES_MULTIPLE_INHERITANCE (basetype)) - { - int i = n_candidates - 1, best = i; - tree base1 = NULL_TREE; - - if (TREE_CODE (TREE_TYPE (candidates[i].function)) == FUNCTION_TYPE) - return cp - 1; - - for (; i >= 0 && candidates[i].user == 0 && candidates[i].evil == 0; i--) - { - if (TREE_CODE (TREE_TYPE (candidates[i].function)) == METHOD_TYPE) - { - tree newbase = DECL_CLASS_CONTEXT (candidates[i].function); - - if (base1 != NULL_TREE) - { - /* newbase could be a base or a parent of base1 */ - if (newbase != base1 && ! UNIQUELY_DERIVED_FROM_P (newbase, base1) - && ! UNIQUELY_DERIVED_FROM_P (base1, newbase)) - { - error_with_aggr_type (basetype, "ambiguous request for function from distinct base classes of type `%s'"); - error (" first candidate is `%s'", - fndecl_as_string (0, candidates[best].function, 1)); - error (" second candidate is `%s'", - fndecl_as_string (0, candidates[i].function, 1)); - cp[-1].evil = 1; - return cp - 1; - } - } - else - { - best = i; - base1 = newbase; - } - } - else return cp - 1; - } - } - - /* Don't accept a candidate as being ideal if it's indistinguishable - from another candidate. */ - if (rank_for_overload (cp-1, cp-2) == 0) - { - /* If the types are distinguishably different (like - `long' vs. `unsigned long'), that's ok. But if they are arbitrarily - different, such as `int (*)(void)' vs. `void (*)(int)', - that's not ok. */ - tree p1 = TYPE_ARG_TYPES (TREE_TYPE (cp[-1].function)); - tree p2 = TYPE_ARG_TYPES (TREE_TYPE (cp[-2].function)); - while (p1 && p2) - { - if (TREE_CODE (TREE_VALUE (p1)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_VALUE (p1))) == FUNCTION_TYPE - && TREE_VALUE (p1) != TREE_VALUE (p2)) - return 0; - p1 = TREE_CHAIN (p1); - p2 = TREE_CHAIN (p2); - } - if (p1 || p2) - return 0; - } - - return cp - 1; - - ret0: - /* In the case where there is no ideal candidate, restore - TREE_VALUE slots of PARMS from TREE_PURPOSE slots. */ - while (parms) - { - TREE_VALUE (parms) = TREE_PURPOSE (parms); - parms = TREE_CHAIN (parms); - } - return 0; -} - -/* Assume that if the class referred to is not in the - current class hierarchy, that it may be remote. - PARENT is assumed to be of aggregate type here. */ -static int -may_be_remote (parent) - tree parent; -{ - if (TYPE_OVERLOADS_METHOD_CALL_EXPR (parent) == 0) - return 0; - - if (current_class_type == NULL_TREE) - return 0; - if (parent == current_class_type) - return 0; - - if (UNIQUELY_DERIVED_FROM_P (parent, current_class_type)) - return 0; - return 1; -} - -tree -build_vfield_ref (datum, type) - tree datum, type; -{ - tree rval; - int old_assume_nonnull_objects = flag_assume_nonnull_objects; - - if (datum == error_mark_node) - return error_mark_node; - - /* Vtable references are always made from non-null objects. */ - flag_assume_nonnull_objects = 1; - if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) - datum = convert_from_reference (datum); - - if (! TYPE_USES_COMPLEX_INHERITANCE (type)) - rval = build (COMPONENT_REF, TREE_TYPE (CLASSTYPE_VFIELD (type)), - datum, CLASSTYPE_VFIELD (type)); - else - rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), 0, 0); - flag_assume_nonnull_objects = old_assume_nonnull_objects; - - return rval; -} - -/* Build a call to a member of an object. I.e., one that overloads - operator ()(), or is a pointer-to-function or pointer-to-method. */ -static tree -build_field_call (basetype_path, instance_ptr, name, parms, err_name) - tree basetype_path; - tree instance_ptr, name, parms; - char *err_name; -{ - tree field, instance; - - if (instance_ptr == current_class_decl) - { - /* Check to see if we really have a reference to an instance variable - with `operator()()' overloaded. */ - field = IDENTIFIER_CLASS_VALUE (name); - - if (field == NULL_TREE) - { - error ("`this' has no member named `%s'", err_name); - return error_mark_node; - } - - if (TREE_CODE (field) == FIELD_DECL) - { - /* If it's a field, try overloading operator (), - or calling if the field is a pointer-to-function. */ - instance = build_component_ref_1 (C_C_D, field, 0); - if (instance == error_mark_node) - return error_mark_node; - - if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance)) - && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (instance))) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE); - - if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) - return build_function_call (instance, parms); - else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) - return build_function_call (instance, tree_cons (NULL_TREE, current_class_decl, parms)); - } - return NULL_TREE; - } - - /* Check to see if this is not really a reference to an instance variable - with `operator()()' overloaded. */ - field = lookup_field (basetype_path, name, 1, 0); - - /* This can happen if the reference was ambiguous - or for visibility violations. */ - if (field == error_mark_node) - return error_mark_node; - if (field) - { - tree basetype; - tree ftype = TREE_TYPE (field); - - if (TYPE_LANG_SPECIFIC (ftype) && TYPE_OVERLOADS_CALL_EXPR (ftype)) - { - /* Make the next search for this field very short. */ - basetype = DECL_FIELD_CONTEXT (field); - instance_ptr = convert_pointer_to (basetype, instance_ptr); - - instance = build_indirect_ref (instance_ptr, NULL); - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, - build_component_ref_1 (instance, field, 0), - parms, NULL_TREE); - } - if (TREE_CODE (ftype) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (ftype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (ftype)) == METHOD_TYPE) - { - /* This is a member which is a pointer to function. */ - tree ref - = build_component_ref_1 (build_indirect_ref (instance_ptr, - NULL), - field, LOOKUP_COMPLAIN); - if (ref == error_mark_node) - return error_mark_node; - return build_function_call (ref, parms); - } - } - else if (TREE_CODE (ftype) == METHOD_TYPE) - { - error ("invalid call via pointer-to-member function"); - return error_mark_node; - } - else - return NULL_TREE; - } - return NULL_TREE; -} - -tree -find_scoped_type (type, inner_name, inner_types) - tree type, inner_name, inner_types; -{ - tree tags = CLASSTYPE_TAGS (type); - - while (tags) - { - /* The TREE_PURPOSE of an enum tag (which becomes a member of the - enclosing class) is set to the name for the enum type. So, if - inner_name is `bar', and we strike `baz' for `enum bar { baz }', - then this test will be true. */ - if (TREE_PURPOSE (tags) == inner_name) - { - if (inner_types == NULL_TREE) - return DECL_NESTED_TYPENAME (TYPE_NAME (TREE_VALUE (tags))); - return resolve_scope_to_name (TREE_VALUE (tags), inner_types); - } - tags = TREE_CHAIN (tags); - } - - /* Look for a TYPE_DECL. */ - for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags)) - if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name) - { - /* Code by raeburn. */ - if (inner_types == NULL_TREE) - return DECL_NESTED_TYPENAME (tags); - return resolve_scope_to_name (TREE_TYPE (tags), inner_types); - } - - return NULL_TREE; -} - -/* Resolve an expression NAME1::NAME2::...::NAMEn to - the name that names the above nested type. INNER_TYPES - is a chain of nested type names (held together by SCOPE_REFs); - OUTER_TYPE is the type we know to enclose INNER_TYPES. - Returns NULL_TREE if there is an error. */ -tree -resolve_scope_to_name (outer_type, inner_types) - tree outer_type, inner_types; -{ - register tree tmp; - tree inner_name; - - if (outer_type == NULL_TREE && current_class_type != NULL_TREE) - { - /* We first try to look for a nesting in our current class context, - then try any enclosing classes. */ - tree type = current_class_type; - - while (type && (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE)) - { - tree rval = resolve_scope_to_name (type, inner_types); - - if (rval != NULL_TREE) - return rval; - type = DECL_CONTEXT (TYPE_NAME (type)); - } - } - - if (TREE_CODE (inner_types) == SCOPE_REF) - { - inner_name = TREE_OPERAND (inner_types, 0); - inner_types = TREE_OPERAND (inner_types, 1); - } - else - { - inner_name = inner_types; - inner_types = NULL_TREE; - } - - if (outer_type == NULL_TREE) - { - /* If we have something that's already a type by itself, - use that. */ - if (IDENTIFIER_HAS_TYPE_VALUE (inner_name)) - { - if (inner_types) - return resolve_scope_to_name (IDENTIFIER_TYPE_VALUE (inner_name), - inner_types); - return inner_name; - } - return NULL_TREE; - } - - if (! IS_AGGR_TYPE (outer_type)) - return NULL_TREE; - - /* Look for member classes or enums. */ - tmp = find_scoped_type (outer_type, inner_name, inner_types); - - /* If it's not a type in this class, then go down into the - base classes and search there. */ - if (! tmp && TYPE_BINFO (outer_type)) - { - tree binfos = TYPE_BINFO_BASETYPES (outer_type); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tmp = find_scoped_type (BINFO_TYPE (base_binfo), - inner_name, inner_types); - if (tmp) - return tmp; - } - tmp = NULL_TREE; - } - - return tmp; -} - -/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'. - This is how virtual function calls are avoided. */ -tree -build_scoped_method_call (exp, scopes, name, parms) - tree exp; - tree scopes; - tree name; - tree parms; -{ - /* Because this syntactic form does not allow - a pointer to a base class to be `stolen', - we need not protect the derived->base conversion - that happens here. - - @@ But we do have to check visibility privileges later. */ - tree basename = resolve_scope_to_name (NULL_TREE, scopes); - tree basetype, binfo, decl; - tree type = TREE_TYPE (exp); - - if (type == error_mark_node - || basename == NULL_TREE - || ! is_aggr_typedef (basename, 1)) - return error_mark_node; - - if (! IS_AGGR_TYPE (type)) - { - error ("base object of scoped method call is not of aggregate type"); - return error_mark_node; - } - - basetype = IDENTIFIER_TYPE_VALUE (basename); - - if (binfo = binfo_or_else (basetype, type)) - { - if (binfo == error_mark_node) - return error_mark_node; - if (TREE_CODE (exp) == INDIRECT_REF) - decl = build_indirect_ref (convert_pointer_to (binfo, - build_unary_op (ADDR_EXPR, exp, 0)), NULL); - else - decl = build_scoped_ref (exp, scopes); - - /* Call to a destructor. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - /* Explicit call to destructor. */ - name = TREE_OPERAND (name, 0); - if (! is_aggr_typedef (name, 1)) - return error_mark_node; - if (TREE_TYPE (decl) != IDENTIFIER_TYPE_VALUE (name)) - { - error_with_aggr_type (TREE_TYPE (decl), - "qualified type `%s' does not match destructor type `%s'", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl))) - error_with_aggr_type (TREE_TYPE (decl), "type `%s' has no destructor"); - return build_delete (TREE_TYPE (decl), decl, integer_two_node, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, - 0, 0); - } - - /* Call to a method. */ - return build_method_call (decl, name, parms, NULL_TREE, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); - } - return error_mark_node; -} - -/* Build something of the form ptr->method (args) - or object.method (args). This can also build - calls to constructors, and find friends. - - Member functions always take their class variable - as a pointer. - - INSTANCE is a class instance. - - NAME is the NAME field of the struct, union, or class - whose type is that of INSTANCE. - - PARMS help to figure out what that NAME really refers to. - - BASETYPE_PATH, if non-NULL, tells which basetypes of INSTANCE - we should be traversed before starting our search. We need - this information to get protected accesses correct. - - FLAGS is the logical disjunction of zero or more LOOKUP_ - flags. See cp-tree.h for more info. - - If this is all OK, calls build_function_call with the resolved - member function. - - This function must also handle being called to perform - initialization, promotion/coercion of arguments, and - instantiation of default parameters. - - Note that NAME may refer to an instance variable name. If - `operator()()' is defined for the type of that field, then we return - that result. */ -tree -build_method_call (instance, name, parms, basetype_path, flags) - tree instance, name, parms, basetype_path; - int flags; -{ - register tree function, fntype, value_type; - register tree basetype, save_basetype; - register tree baselink, result, method_name, parmtypes, parm; - tree last; - int pass; - enum visibility_type visibility; - - /* Range of cases for vtable optimization. */ - enum vtable_needs { not_needed, maybe_needed, unneeded, needed }; - enum vtable_needs need_vtbl = not_needed; - - char *err_name; - char *name_kind; - int ever_seen = 0; - tree instance_ptr = NULL_TREE; - int all_virtual = flag_all_virtual; - int static_call_context = 0; - tree saw_private = NULL_TREE; - tree saw_protected = NULL_TREE; - - /* Keep track of `const' and `volatile' objects. */ - int constp, volatilep; - -#ifdef GATHER_STATISTICS - n_build_method_call++; -#endif - - if (instance == error_mark_node - || name == error_mark_node - || parms == error_mark_node - || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node)) - return error_mark_node; - - /* This is the logic that magically deletes the second argument to - operator delete, if it is not needed. */ - if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2) - { - tree save_last = TREE_CHAIN (parms); - tree result; - /* get rid of unneeded argument */ - TREE_CHAIN (parms) = NULL_TREE; - result = build_method_call (instance, name, parms, basetype_path, - (LOOKUP_SPECULATIVELY|flags) - &~LOOKUP_COMPLAIN); - /* If it works, return it. */ - if (result && result != error_mark_node) - return build_method_call (instance, name, parms, basetype_path, flags); - /* If it doesn't work, two argument delete must work */ - TREE_CHAIN (parms) = save_last; - } - -#if 0 - /* C++ 2.1 does not allow this, but ANSI probably will. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - error ("invalid call to destructor, use qualified name `%s::~%s'", - IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (name)); - return error_mark_node; - } -#else - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - flags |= LOOKUP_DESTRUCTOR; - name = TREE_OPERAND (name, 0); - if (! is_aggr_typedef (name, 1)) - return error_mark_node; - if (parms) - error ("destructors take no parameters"); - basetype = IDENTIFIER_TYPE_VALUE (name); - if (! TYPE_HAS_DESTRUCTOR (basetype)) - { -#if 0 /* ARM says tp->~T() without T::~T() is valid. */ - error_with_aggr_type (basetype, "type `%s' has no destructor"); -#endif - /* A destructive destructor wouldn't be a bad idea, but let's - not bother for now. */ - return build_c_cast (void_type_node, instance); - } - instance = default_conversion (instance); - if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - instance_ptr = instance; - else - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - return build_delete (build_pointer_type (basetype), - instance_ptr, integer_two_node, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0); - } -#endif - - /* Initialize name for error reporting. */ - if (IDENTIFIER_TYPENAME_P (name)) - err_name = "type conversion operator"; - else if (IDENTIFIER_OPNAME_P (name)) - { - char *p = operator_name_string (name); - err_name = (char *)alloca (strlen (p) + 10); - sprintf (err_name, "operator %s", p); - } - else if (TREE_CODE (name) == SCOPE_REF) - err_name = IDENTIFIER_POINTER (TREE_OPERAND (name, 1)); - else - err_name = IDENTIFIER_POINTER (name); - - if (IDENTIFIER_OPNAME_P (name)) - GNU_xref_call (current_function_decl, IDENTIFIER_POINTER (name)); - else - GNU_xref_call (current_function_decl, err_name); - - if (instance == NULL_TREE) - { - basetype = NULL_TREE; - /* Check cases where this is really a call to raise - an exception. */ - if (current_class_type && TREE_CODE (name) == IDENTIFIER_NODE) - { - basetype = purpose_member (name, CLASSTYPE_TAGS (current_class_type)); - if (basetype) - basetype = TREE_VALUE (basetype); - } - else if (TREE_CODE (name) == SCOPE_REF - && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) - { - if (! is_aggr_typedef (TREE_OPERAND (name, 0), 1)) - return error_mark_node; - basetype = purpose_member (TREE_OPERAND (name, 1), - CLASSTYPE_TAGS (IDENTIFIER_TYPE_VALUE (TREE_OPERAND (name, 0)))); - if (basetype) - basetype = TREE_VALUE (basetype); - } - - if (basetype != NULL_TREE) - ; - /* call to a constructor... */ - else if (IDENTIFIER_HAS_TYPE_VALUE (name)) - { - basetype = IDENTIFIER_TYPE_VALUE (name); - name = constructor_name (basetype); - } - else - { - tree typedef_name = lookup_name (name, 1); - if (typedef_name && TREE_CODE (typedef_name) == TYPE_DECL) - { - /* Canonicalize the typedef name. */ - basetype = TREE_TYPE (typedef_name); - name = TYPE_IDENTIFIER (basetype); - } - else - { - error ("no constructor named `%s' in visible scope", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - } - - if (! IS_AGGR_TYPE (basetype)) - { - non_aggr_error: - if ((flags & LOOKUP_COMPLAIN) && TREE_CODE (basetype) != ERROR_MARK) - error ("request for member `%s' in something not a structure or union", err_name); - - return error_mark_node; - } - } - else if (instance == C_C_D || instance == current_class_decl) - { - /* When doing initialization, we side-effect the TREE_TYPE of - C_C_D, hence we cannot set up BASETYPE from CURRENT_CLASS_TYPE. */ - basetype = TREE_TYPE (C_C_D); - - /* Anything manifestly `this' in constructors and destructors - has a known type, so virtual function tables are not needed. */ - if (TYPE_VIRTUAL_P (basetype) - && !(flags & LOOKUP_NONVIRTUAL)) - need_vtbl = (dtor_label || ctor_label) - ? unneeded : maybe_needed; - - instance = C_C_D; - instance_ptr = current_class_decl; - result = build_field_call (TYPE_BINFO (current_class_type), - instance_ptr, name, parms, err_name); - - if (result) - return result; - } - else if (TREE_CODE (instance) == RESULT_DECL) - { - basetype = TREE_TYPE (instance); - /* Should we ever have to make a virtual function reference - from a RESULT_DECL, know that it must be of fixed type - within the scope of this function. */ - if (!(flags & LOOKUP_NONVIRTUAL) && TYPE_VIRTUAL_P (basetype)) - need_vtbl = maybe_needed; - instance_ptr = build1 (ADDR_EXPR, TYPE_POINTER_TO (basetype), instance); - } - else if (instance == current_exception_object) - { - instance_ptr = build1 (ADDR_EXPR, TYPE_POINTER_TO (current_exception_type), - TREE_OPERAND (current_exception_object, 0)); - mark_addressable (TREE_OPERAND (current_exception_object, 0)); - result = build_field_call (TYPE_BINFO (current_exception_type), - instance_ptr, name, parms, err_name); - if (result) - return result; - error ("exception member `%s' cannot be invoked", err_name); - return error_mark_node; - } - else - { - /* The MAIN_VARIANT of the type that `instance_ptr' winds up being. */ - tree inst_ptr_basetype; - - static_call_context = (TREE_CODE (instance) == NOP_EXPR - && TREE_OPERAND (instance, 0) == error_mark_node); - - /* the base type of an instance variable is pointer to class */ - basetype = TREE_TYPE (instance); - - if (TREE_CODE (basetype) == REFERENCE_TYPE) - { - basetype = TYPE_MAIN_VARIANT (TREE_TYPE (basetype)); - if (! IS_AGGR_TYPE (basetype)) - goto non_aggr_error; - /* Call to convert not needed because we are remaining - within the same type. */ - instance_ptr = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), instance); - inst_ptr_basetype = basetype; - } - else - { - if (TREE_CODE (basetype) == POINTER_TYPE) - { - basetype = TREE_TYPE (basetype); - instance_ptr = instance; - } - - if (! IS_AGGR_TYPE (basetype)) - goto non_aggr_error; - - if (! instance_ptr) - { - if ((lvalue_p (instance) - && (instance_ptr = build_unary_op (ADDR_EXPR, instance, 0))) - || (instance_ptr = unary_complex_lvalue (ADDR_EXPR, instance))) - { - if (instance_ptr == error_mark_node) - return error_mark_node; - } - else if (TREE_CODE (instance) == NOP_EXPR - || TREE_CODE (instance) == CONSTRUCTOR) - { - /* A cast is not an lvalue. Initialize a fresh temp - with the value we are casting from, and proceed with - that temporary. We can't cast to a reference type, - so that simplifies the initialization to something - we can manage. */ - tree temp = get_temp_name (TREE_TYPE (instance), 0); - if (IS_AGGR_TYPE (TREE_TYPE (instance))) - expand_aggr_init (temp, instance, 0); - else - { - store_init_value (temp, instance); - expand_decl_init (temp); - } - instance = temp; - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - } - else - { - if (TREE_CODE (instance) != CALL_EXPR) - my_friendly_abort (125); - if (TYPE_NEEDS_CONSTRUCTOR (basetype)) - instance = build_cplus_new (basetype, instance, 0); - else - { - instance = get_temp_name (basetype, 0); - TREE_ADDRESSABLE (instance) = 1; - } - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - } - /* @@ Should we call comp_target_types here? */ - inst_ptr_basetype = TREE_TYPE (TREE_TYPE (instance_ptr)); - if (TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (inst_ptr_basetype)) - basetype = inst_ptr_basetype; - else - { - instance_ptr = convert (TYPE_POINTER_TO (basetype), instance_ptr); - if (instance_ptr == error_mark_node) - return error_mark_node; - } - } - else - inst_ptr_basetype = TREE_TYPE (TREE_TYPE (instance_ptr)); - } - - if (basetype_path == NULL_TREE) - basetype_path = TYPE_BINFO (inst_ptr_basetype); - - result = build_field_call (basetype_path, instance_ptr, name, parms, err_name); - if (result) - return result; - - if (!(flags & LOOKUP_NONVIRTUAL) && TYPE_VIRTUAL_P (basetype)) - { - if (TREE_SIDE_EFFECTS (instance_ptr)) - { - /* This action is needed because the instance is needed - for providing the base of the virtual function table. - Without using a SAVE_EXPR, the function we are building - may be called twice, or side effects on the instance - variable (such as a post-increment), may happen twice. */ - instance_ptr = save_expr (instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL); - } - else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - { - /* This happens when called for operator new (). */ - instance = build_indirect_ref (instance, NULL); - } - - need_vtbl = maybe_needed; - } - } - - if (TYPE_SIZE (basetype) == 0) - { - /* This is worth complaining about, I think. */ - error_with_aggr_type (basetype, "cannot lookup method in incomplete type `%s'"); - return error_mark_node; - } - - save_basetype = basetype; - -#if 0 - if (all_virtual == 1 - && (! strncmp (IDENTIFIER_POINTER (name), OPERATOR_METHOD_FORMAT, - OPERATOR_METHOD_LENGTH) - || instance_ptr == NULL_TREE - || (TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype) == 0))) - all_virtual = 0; -#endif - - last = NULL_TREE; - for (parmtypes = NULL_TREE, parm = parms; parm; parm = TREE_CHAIN (parm)) - { - tree t = TREE_TYPE (TREE_VALUE (parm)); - if (TREE_CODE (t) == OFFSET_TYPE) - { - /* Convert OFFSET_TYPE entities to their normal selves. */ - TREE_VALUE (parm) = resolve_offset_ref (TREE_VALUE (parm)); - t = TREE_TYPE (TREE_VALUE (parm)); - } - if (TREE_CODE (t) == ARRAY_TYPE) - { - /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place. - This eliminates needless calls to `compute_conversion_costs'. */ - TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm)); - t = TREE_TYPE (TREE_VALUE (parm)); - } - if (t == error_mark_node) - return error_mark_node; - last = build_tree_list (NULL_TREE, t); - parmtypes = chainon (parmtypes, last); - } - - if (instance) - { - constp = TREE_READONLY (instance); - volatilep = TREE_THIS_VOLATILE (instance); - parms = tree_cons (NULL_TREE, instance_ptr, parms); - } - else - { - /* Raw constructors are always in charge. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype) - && ! (flags & LOOKUP_HAS_IN_CHARGE)) - { - flags |= LOOKUP_HAS_IN_CHARGE; - parms = tree_cons (NULL_TREE, integer_one_node, parms); - parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes); - } - - if (flag_this_is_variable > 0) - { - constp = 0; - volatilep = 0; - parms = tree_cons (NULL_TREE, build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node), parms); - } - else - { - constp = 0; - volatilep = 0; - instance_ptr = build_new (NULL_TREE, basetype, void_type_node, 0); - if (instance_ptr == error_mark_node) - return error_mark_node; - instance_ptr = save_expr (instance_ptr); - TREE_CALLS_NEW (instance_ptr) = 1; - instance = build_indirect_ref (instance_ptr, NULL); - - /* If it's a default argument initialized from a ctor, what we get - from instance_ptr will match the arglist for the FUNCTION_DECL - of the constructor. */ - if (parms && TREE_CODE (TREE_VALUE (parms)) == CALL_EXPR - && TREE_OPERAND (TREE_VALUE (parms), 1) - && TREE_CALLS_NEW (TREE_VALUE (TREE_OPERAND (TREE_VALUE (parms), 1)))) - parms = build_tree_list (NULL_TREE, instance_ptr); - else - parms = tree_cons (NULL_TREE, instance_ptr, parms); - } - } - parmtypes = tree_cons (NULL_TREE, - build_pointer_type (build_type_variant (basetype, constp, volatilep)), - parmtypes); - if (last == NULL_TREE) - last = parmtypes; - - /* Look up function name in the structure type definition. */ - - if ((IDENTIFIER_HAS_TYPE_VALUE (name) - && IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))) - || name == constructor_name (basetype)) - { - tree tmp = NULL_TREE; - if (IDENTIFIER_TYPE_VALUE (name) == basetype - || name == constructor_name (basetype)) - tmp = TYPE_BINFO (basetype); - else - tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0); - - if (tmp != NULL_TREE) - { - name_kind = "constructor"; - - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype) - && ! (flags & LOOKUP_HAS_IN_CHARGE)) - { - /* Constructors called for initialization - only are never in charge. */ - tree tmplist; - - flags |= LOOKUP_HAS_IN_CHARGE; - tmplist = tree_cons (NULL_TREE, integer_zero_node, - TREE_CHAIN (parms)); - TREE_CHAIN (parms) = tmplist; - tmplist = tree_cons (NULL_TREE, integer_type_node, TREE_CHAIN (parmtypes)); - TREE_CHAIN (parmtypes) = tmplist; - } - basetype = BINFO_TYPE (tmp); - } - else - name_kind = "method"; - } - else name_kind = "method"; - - if (basetype_path == NULL_TREE) - basetype_path = TYPE_BINFO (basetype); - result = lookup_fnfields (basetype_path, name, - (flags & LOOKUP_COMPLAIN)); - if (result == error_mark_node) - return error_mark_node; - - - /* Now, go look for this method name. We do not find destructors here. - - Putting `void_list_node' on the end of the parmtypes - fakes out `build_decl_overload' into doing the right thing. */ - TREE_CHAIN (last) = void_list_node; - method_name = build_decl_overload (name, parmtypes, - 1 + (name == constructor_name (save_basetype))); - TREE_CHAIN (last) = NULL_TREE; - - for (pass = 0; pass < 2; pass++) - { - struct candidate *candidates; - struct candidate *cp; - int len; - unsigned best = 1; - - /* This increments every time we go up the type hierarchy. - The idea is to prefer a function of the derived class if possible. */ - int b_or_d = 0; - - baselink = result; - - if (pass > 0) - { - candidates - = (struct candidate *) alloca ((ever_seen+1) - * sizeof (struct candidate)); - cp = candidates; - len = list_length (parms); - - /* First see if a global function has a shot at it. */ - if (flags & LOOKUP_GLOBAL) - { - tree friend_parms; - tree parm = TREE_VALUE (parms); - - if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE) - friend_parms = parms; - else if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE) - { - tree new_type; - parm = build_indirect_ref (parm, "friendifying parms (compiler error)"); - new_type = build_reference_type (TREE_TYPE (parm)); - /* It is possible that this should go down a layer. */ - new_type = build_type_variant (new_type, - TREE_READONLY (parm), - TREE_THIS_VOLATILE (parm)); - parm = convert (new_type, parm); - friend_parms = tree_cons (NULL_TREE, parm, TREE_CHAIN (parms)); - } - else - my_friendly_abort (167); - - cp->harshness - = (unsigned short *)alloca ((len+1) * sizeof (short)); - result = build_overload_call (name, friend_parms, 0, cp); - /* If it turns out to be the one we were actually looking for - (it was probably a friend function), the return the - good result. */ - if (TREE_CODE (result) == CALL_EXPR) - return result; - - while (cp->evil == 0) - { - /* non-standard uses: set the field to 0 to indicate - we are using a non-member function. */ - cp->u.field = 0; - if (cp->harshness[len] == 0 - && cp->harshness[len] == 0 - && cp->user == 0 && cp->b_or_d == 0 - && cp->easy < best) - best = cp->easy; - cp += 1; - } - } - } - - while (baselink) - { - /* We have a hit (of sorts). If the parameter list is - "error_mark_node", or some variant thereof, it won't - match any methods. Since we have verified that the is - some method vaguely matching this one (in name at least), - silently return. - - Don't stop for friends, however. */ - tree basetypes = TREE_PURPOSE (baselink); - - function = TREE_VALUE (baselink); - if (TREE_CODE (basetypes) == TREE_LIST) - basetypes = TREE_VALUE (basetypes); - basetype = BINFO_TYPE (basetypes); - - /* Cast the instance variable to the appropriate type. */ - TREE_VALUE (parmtypes) = TYPE_POINTER_TO (basetype); - - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))) - function = DECL_CHAIN (function); - - for (; function; function = DECL_CHAIN (function)) - { -#ifdef GATHER_STATISTICS - n_inner_fields_searched++; -#endif - ever_seen++; - - /* Not looking for friends here. */ - if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE - && ! DECL_STATIC_FUNCTION_P (function)) - continue; - - if (pass == 0 - && DECL_ASSEMBLER_NAME (function) == method_name) - { - if (flags & LOOKUP_PROTECT) - { - visibility = compute_visibility (basetypes, function); - if (visibility == visibility_protected - && flags & LOOKUP_PROTECTED_OK) - visibility = visibility_public; - } - - if ((flags & LOOKUP_PROTECT) == 0 - || visibility == visibility_public) - goto found_and_ok; - else if (visibility == visibility_private) - saw_private = function; - else if (visibility == visibility_protected) - saw_protected = function; - /* If we fail on the exact match, we have - an immediate failure. */ - goto found; - } - if (pass > 0) - { - tree these_parms = parms; - -#ifdef GATHER_STATISTICS - n_inner_fields_searched++; -#endif - cp->harshness - = (unsigned short *)alloca ((len+1) * sizeof (short)); - if (DECL_STATIC_FUNCTION_P (function)) - these_parms = TREE_CHAIN (these_parms); - compute_conversion_costs (function, these_parms, cp, len); - cp->b_or_d += b_or_d; - if (cp->evil == 0) - { - cp->u.field = function; - cp->function = function; - if (flags & LOOKUP_PROTECT) - { - enum visibility_type this_v; - this_v = compute_visibility (basetypes, function); - if (this_v == visibility_protected - && (flags & LOOKUP_PROTECTED_OK)) - this_v = visibility_public; - if (this_v != visibility_public) - { - if (this_v == visibility_private) - saw_private = function; - else - saw_protected = function; - continue; - } - } - - /* No "two-level" conversions. */ - if (flags & LOOKUP_NO_CONVERSION && cp->user != 0) - continue; - - /* If we used default parameters, we must - check to see whether anyone else might - use them also, and report a possible - ambiguity. */ - if (! TYPE_USES_MULTIPLE_INHERITANCE (save_basetype) - && cp->harshness[len] == 0 - && CONST_HARSHNESS (cp->harshness[0]) == 0 - && cp->user == 0 && cp->b_or_d == 0 - && cp->easy < best) - { - if (! DECL_STATIC_FUNCTION_P (function)) - TREE_VALUE (parms) = cp->arg; - if (best == 1) - goto found_and_maybe_warn; - } - cp++; - } - } - } - /* Now we have run through one link's member functions. - arrange to head-insert this link's links. */ - baselink = next_baselink (baselink); - b_or_d += 1; - } - if (pass == 0) - { - /* No exact match could be found. Now try to find match - using default conversions. */ - if ((flags & LOOKUP_GLOBAL) && IDENTIFIER_GLOBAL_VALUE (name)) - if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL) - ever_seen += 1; - else if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TREE_LIST) - ever_seen += list_length (IDENTIFIER_GLOBAL_VALUE (name)); - - if (ever_seen == 0) - { - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_SPECULATIVELY) - return NULL_TREE; - if (flags & LOOKUP_GLOBAL) - error ("no global or non-hidden member function `%s' defined", err_name); - else - error_with_aggr_type (save_basetype, "no non-hidden member function `%s::%s' defined", err_name); - return error_mark_node; - } - continue; - } - - if (cp - candidates != 0) - { - /* Rank from worst to best. Then cp will point to best one. - Private fields have their bits flipped. For unsigned - numbers, this should make them look very large. - If the best alternate has a (signed) negative value, - then all we ever saw were private members. */ - if (cp - candidates > 1) - { - cp = ideal_candidate (save_basetype, candidates, - cp - candidates, parms, len); - if (cp == (struct candidate *)0) - { - error ("ambiguous type conversion requested for %s `%s'", - name_kind, err_name); - return error_mark_node; - } - if (cp->evil) - return error_mark_node; - } - else if (cp[-1].evil == 2) - { - error ("ambiguous type conversion requested for %s `%s'", - name_kind, err_name); - return error_mark_node; - } - else cp--; - - /* The global function was the best, so use it. */ - if (cp->u.field == 0) - { - /* We must convert the instance pointer into a reference type. - Global overloaded functions can only either take - aggregate objects (which come for free from references) - or reference data types anyway. */ - TREE_VALUE (parms) = copy_node (instance_ptr); - TREE_TYPE (TREE_VALUE (parms)) = build_reference_type (TREE_TYPE (TREE_TYPE (instance_ptr))); - return build_function_call (cp->function, parms); - } - - function = cp->function; - if (! DECL_STATIC_FUNCTION_P (function)) - TREE_VALUE (parms) = cp->arg; - goto found_and_maybe_warn; - } - - if ((flags & ~LOOKUP_GLOBAL) & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY)) - { - char *tag_name, *buf; - - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_SPECULATIVELY) - return NULL_TREE; - - if (DECL_STATIC_FUNCTION_P (cp->function)) - parms = TREE_CHAIN (parms); - if (ever_seen) - { - if (((HOST_WIDE_INT)saw_protected|(HOST_WIDE_INT)saw_private) == 0) - { - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - if (static_call_context && TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) - error_with_aggr_type (TREE_TYPE (TREE_TYPE (instance_ptr)), - "object missing in call to `%s::%s'", - err_name); - else - report_type_mismatch (cp, parms, name_kind, err_name); - } - else - { - char buf[80]; - char *msg; - tree seen = saw_private; - - if (saw_private) - { - if (saw_protected) - msg = "%s `%%s' (and the like) are private or protected"; - else - msg = "the %s `%%s' is private"; - } - else - { - msg = "the %s `%%s' is protected"; - seen = saw_protected; - } - sprintf (buf, msg, name_kind); - error_with_decl (seen, buf); - error ("within this context"); - } - return error_mark_node; - } - - if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN)) - == LOOKUP_COMPLAIN) - { - if (TREE_CODE (save_basetype) == RECORD_TYPE) - tag_name = "structure"; - else - tag_name = "union"; - - buf = (char *)alloca (30 + strlen (err_name)); - strcpy (buf, "%s has no method named `%s'"); - error (buf, tag_name, err_name); - return error_mark_node; - } - return NULL_TREE; - } - continue; - - found_and_maybe_warn: - if (CONST_HARSHNESS (cp->harshness[0])) - { - if (flags & LOOKUP_COMPLAIN) - { - error_with_decl (cp->function, "non-const member function `%s'"); - error ("called for const object at this point in file"); - } - /* Not good enough for a match. */ - else - return error_mark_node; - } - goto found_and_ok; - } - /* Silently return error_mark_node. */ - return error_mark_node; - - found: - if (visibility == visibility_private) - { - if (flags & LOOKUP_COMPLAIN) - { - error_with_file_and_line (DECL_SOURCE_FILE (function), - DECL_SOURCE_LINE (function), - TREE_PRIVATE (function) - ? "%s `%s' is private" - : "%s `%s' is from private base class", - name_kind, - lang_printable_name (function)); - error ("within this context"); - } - return error_mark_node; - } - else if (visibility == visibility_protected) - { - if (flags & LOOKUP_COMPLAIN) - { - error_with_file_and_line (DECL_SOURCE_FILE (function), - DECL_SOURCE_LINE (function), - TREE_PROTECTED (function) - ? "%s `%s' is protected" - : "%s `%s' has protected visibility from this point", - name_kind, - lang_printable_name (function)); - error ("within this context"); - } - return error_mark_node; - } - my_friendly_abort (1); - - found_and_ok: - - /* From here on down, BASETYPE is the type that INSTANCE_PTR's - type (if it exists) is a pointer to. */ - function = DECL_MAIN_VARIANT (function); - /* Declare external function if necessary. */ - assemble_external (function); - - fntype = TREE_TYPE (function); - if (TREE_CODE (fntype) == POINTER_TYPE) - fntype = TREE_TYPE (fntype); - basetype = DECL_CLASS_CONTEXT (function); - - /* If we are referencing a virtual function from an object - of effectively static type, then there is no need - to go through the virtual function table. */ - if (need_vtbl == maybe_needed) - { - int fixed_type = resolves_to_fixed_type_p (instance, 0); - - if (all_virtual == 1 - && DECL_VINDEX (function) - && may_be_remote (basetype)) - need_vtbl = needed; - else if (DECL_VINDEX (function)) - need_vtbl = fixed_type ? unneeded : needed; - else - need_vtbl = not_needed; - } - - if (TREE_CODE (fntype) == METHOD_TYPE && static_call_context - && !DECL_CONSTRUCTOR_P (function)) - { - /* Let's be nice to the user for now, and give reasonable - default behavior. */ - instance_ptr = current_class_decl; - if (instance_ptr) - { - if (basetype != current_class_type) - { - tree binfo = get_binfo (basetype, current_class_type, 1); - if (binfo == NULL_TREE) - { - error_not_base_type (function, current_class_type); - return error_mark_node; - } - else if (basetype == error_mark_node) - return error_mark_node; - } - } - else if (! TREE_STATIC (function)) - { - error_with_aggr_type (basetype, "cannot call member function `%s::%s' without object", - err_name); - return error_mark_node; - } - } - - value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node; - - if (TYPE_SIZE (value_type) == 0) - { - if (flags & LOOKUP_COMPLAIN) - incomplete_type_error (0, value_type); - return error_mark_node; - } - - /* We do not pass FUNCTION into `convert_arguments', because by - now everything should be ok. If not, then we have a serious error. */ - if (DECL_STATIC_FUNCTION_P (function)) - parms = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype), - TREE_CHAIN (parms), NULL_TREE, LOOKUP_NORMAL); - else if (need_vtbl == unneeded) - { - int sub_flags = DECL_CONSTRUCTOR_P (function) ? flags : LOOKUP_NORMAL; - basetype = TREE_TYPE (instance); - if (TYPE_METHOD_BASETYPE (TREE_TYPE (function)) != TYPE_MAIN_VARIANT (basetype) - && TYPE_USES_COMPLEX_INHERITANCE (basetype)) - { - basetype = DECL_CLASS_CONTEXT (function); - instance_ptr = convert_pointer_to (basetype, instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL); - } - parms = tree_cons (NULL_TREE, instance_ptr, - convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE, sub_flags)); - } - else - { - if ((flags & LOOKUP_NONVIRTUAL) == 0) - basetype = DECL_CONTEXT (function); - - /* First parm could be integer_zerop with casts like - ((Object*)0)->Object::IsA() */ - if (!integer_zerop (TREE_VALUE (parms))) - { - instance_ptr = convert_pointer_to (build_type_variant (basetype, constp, volatilep), - TREE_VALUE (parms)); - if (TREE_CODE (instance_ptr) == COND_EXPR) - { - instance_ptr = save_expr (instance_ptr); - instance = build_indirect_ref (instance_ptr, NULL); - } - else if (TREE_CODE (instance_ptr) == NOP_EXPR - && TREE_CODE (TREE_OPERAND (instance_ptr, 0)) == ADDR_EXPR - && TREE_OPERAND (TREE_OPERAND (instance_ptr, 0), 0) == instance) - ; - /* The call to `convert_pointer_to' may return error_mark_node. */ - else if (TREE_CODE (instance_ptr) == ERROR_MARK) - return instance_ptr; - else if (instance == NULL_TREE - || TREE_CODE (instance) != INDIRECT_REF - || TREE_OPERAND (instance, 0) != instance_ptr) - instance = build_indirect_ref (instance_ptr, NULL); - } - parms = tree_cons (NULL_TREE, instance_ptr, - convert_arguments (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE, LOOKUP_NORMAL)); - } - -#if 0 - /* Constructors do not overload method calls. */ - else if (TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype) - && name != TYPE_IDENTIFIER (basetype) - && (TREE_CODE (function) != FUNCTION_DECL - || strncmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)), - OPERATOR_METHOD_FORMAT, - OPERATOR_METHOD_LENGTH)) -#if 0 - && (may_be_remote (basetype) - || (C_C_D ? TREE_TYPE (instance) != current_class_type : 1)) -#else - /* This change by Larry Ketcham. */ - && (may_be_remote (basetype) || instance != C_C_D) -#endif - ) - { - tree fn_as_int; - - parms = TREE_CHAIN (parms); - - if (!all_virtual && TREE_CODE (function) == FUNCTION_DECL) - fn_as_int = build_unary_op (ADDR_EXPR, function, 0); - else - fn_as_int = convert (TREE_TYPE (default_conversion (function)), DECL_VINDEX (function)); - if (all_virtual == 1) - fn_as_int = convert (integer_type_node, fn_as_int); - - result = build_opfncall (METHOD_CALL_EXPR, LOOKUP_NORMAL, instance, fn_as_int, parms); - - if (result == NULL_TREE) - { - compiler_error ("could not overload `operator->()(...)'"); - return error_mark_node; - } - else if (result == error_mark_node) - return error_mark_node; - -#if 0 - /* Do this if we want the result of operator->() to inherit - the type of the function it is subbing for. */ - TREE_TYPE (result) = value_type; -#endif - - return result; - } -#endif - - if (need_vtbl == needed) - { - function = build_vfn_ref (&TREE_VALUE (parms), instance, DECL_VINDEX (function)); - TREE_TYPE (function) = build_pointer_type (fntype); - } - - if (TREE_CODE (function) == FUNCTION_DECL) - GNU_xref_call (current_function_decl, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function))); - - if (TREE_CODE (function) == FUNCTION_DECL) - { - if (DECL_INLINE (function)) - function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); - else - { - assemble_external (function); - TREE_USED (function) = 1; - function = default_conversion (function); - } - } - else - function = default_conversion (function); - - result = - build_nt (CALL_EXPR, function, parms, NULL_TREE); - - TREE_TYPE (result) = value_type; - TREE_SIDE_EFFECTS (result) = 1; - TREE_RAISES (result) - = TYPE_RAISES_EXCEPTIONS (fntype) || (parms && TREE_RAISES (parms)); - return result; -} - -/* Similar to `build_method_call', but for overloaded non-member functions. - The name of this function comes through NAME. The name depends - on PARMS. - - Note that this function must handle simple `C' promotions, - as well as variable numbers of arguments (...), and - default arguments to boot. - - If the overloading is successful, we return a tree node which - contains the call to the function. - - If overloading produces candidates which are probable, but not definite, - we hold these candidates. If FINAL_CP is non-zero, then we are free - to assume that final_cp points to enough storage for all candidates that - this function might generate. The `harshness' array is preallocated for - the first candidate, but not for subsequent ones. - - Note that the DECL_RTL of FUNCTION must be made to agree with this - function's new name. */ - -tree -build_overload_call_real (fnname, parms, complain, final_cp, buildxxx) - tree fnname, parms; - int complain; - struct candidate *final_cp; - int buildxxx; -{ - /* must check for overloading here */ - tree overload_name, functions, function, parm; - tree parmtypes = NULL_TREE, last = NULL_TREE; - register tree outer; - int length; - int parmlength = list_length (parms); - - struct candidate *candidates, *cp; - - if (final_cp) - { - final_cp[0].evil = 0; - final_cp[0].user = 0; - final_cp[0].b_or_d = 0; - final_cp[0].easy = 0; - final_cp[0].function = 0; - /* end marker. */ - final_cp[1].evil = 1; - } - - for (parm = parms; parm; parm = TREE_CHAIN (parm)) - { - register tree t = TREE_TYPE (TREE_VALUE (parm)); - - if (t == error_mark_node) - { - if (final_cp) - final_cp->evil = 1; - return error_mark_node; - } - if (TREE_CODE (t) == ARRAY_TYPE || TREE_CODE (t) == OFFSET_TYPE) - { - /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place. - Also convert OFFSET_TYPE entities to their normal selves. - This eliminates needless calls to `compute_conversion_costs'. */ - TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm)); - t = TREE_TYPE (TREE_VALUE (parm)); - } - last = build_tree_list (NULL_TREE, t); - parmtypes = chainon (parmtypes, last); - } - if (last) - TREE_CHAIN (last) = void_list_node; - else - parmtypes = void_list_node; - overload_name = build_decl_overload (fnname, parmtypes, 0); - - /* Now check to see whether or not we can win. - Note that if we are called from `build_method_call', - then we cannot have a mis-match, because we would have - already found such a winning case. */ - - if (IDENTIFIER_GLOBAL_VALUE (overload_name)) - if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST) - return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms); - - functions = IDENTIFIER_GLOBAL_VALUE (fnname); - - if (functions == NULL_TREE) - { - if (complain) - error ("only member functions apply"); - if (final_cp) - final_cp->evil = 1; - return error_mark_node; - } - - if (TREE_CODE (functions) == FUNCTION_DECL) - { - functions = DECL_MAIN_VARIANT (functions); - if (final_cp) - { - /* We are just curious whether this is a viable alternative or not. */ - compute_conversion_costs (functions, parms, final_cp, parmlength); - return functions; - } - else - return build_function_call (functions, parms); - } - - if (TREE_VALUE (functions) == NULL_TREE) - { - if (complain) - error ("function `%s' declared overloaded, but no instances of that function declared", - IDENTIFIER_POINTER (TREE_PURPOSE (functions))); - if (final_cp) - final_cp->evil = 1; - return error_mark_node; - } - - if (TREE_CODE (TREE_VALUE (functions)) == TREE_LIST) - { - register tree outer; - length = 0; - - /* The list-of-lists should only occur for class things. */ - my_friendly_assert (functions == IDENTIFIER_CLASS_VALUE (fnname), 168); - - for (outer = functions; outer; outer = TREE_CHAIN (outer)) - { - /* member functions. */ - length += decl_list_length (TREE_VALUE (TREE_VALUE (outer))); - /* friend functions. */ - length += list_length (TREE_TYPE (TREE_VALUE (outer))); - } - } - else - { - length = list_length (functions); - } - - if (final_cp) - candidates = final_cp; - else - candidates = (struct candidate *)alloca ((length+1) * sizeof (struct candidate)); - - cp = candidates; - - my_friendly_assert (TREE_CODE (TREE_VALUE (functions)) != TREE_LIST, 169); - /* OUTER is the list of FUNCTION_DECLS, in a TREE_LIST. */ - - for (outer = functions; outer; outer = TREE_CHAIN (outer)) - { - int template_cost = 0; - function = TREE_VALUE (outer); - if (TREE_CODE (function) != FUNCTION_DECL - && ! (TREE_CODE (function) == TEMPLATE_DECL - && ! DECL_TEMPLATE_IS_CLASS (function) - && TREE_CODE (DECL_TEMPLATE_RESULT (function)) == FUNCTION_DECL)) - { - enum tree_code code = TREE_CODE (function); - if (code == TEMPLATE_DECL) - code = TREE_CODE (DECL_TEMPLATE_RESULT (function)); - if (code == CONST_DECL) - error_with_decl (function, "enumeral value `%s' conflicts with function of same name"); - else if (code == VAR_DECL) - if (TREE_STATIC (function)) - error_with_decl (function, "variable `%s' conflicts with function of same name"); - else - error_with_decl (function, "constant field `%s' conflicts with function of same name"); - else if (code == TYPE_DECL) - continue; - else my_friendly_abort (2); - error ("at this point in file"); - continue; - } - if (TREE_CODE (function) == TEMPLATE_DECL) - { - int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (function)); - tree *targs = (tree *) alloca (sizeof (tree) * ntparms); - int i; - - i = type_unification (DECL_TEMPLATE_PARMS (function), targs, - TYPE_ARG_TYPES (TREE_TYPE (function)), - parms, &template_cost); - if (i == 0) - function = instantiate_template (function, targs); - } - if (TREE_CODE (function) == TEMPLATE_DECL) - /* Unconverted template -- failed match. */ - cp->evil = 1, cp->function = function, cp->u.bad_arg = -4; - else - { - function = DECL_MAIN_VARIANT (function); - - /* Can't use alloca here, since result might be - passed to calling function. */ - cp->harshness - = (unsigned short *)oballoc ((parmlength+1) * sizeof (short)); - compute_conversion_costs (function, parms, cp, parmlength); - /* Should really add another field... */ - cp->easy = cp->easy * 128 + template_cost; - if (cp[0].evil == 0) - { - cp[1].evil = 1; - if (final_cp - && cp[0].user == 0 && cp[0].b_or_d == 0 - && template_cost == 0 - && cp[0].easy <= 1) - { - final_cp[0].easy = cp[0].easy; - return function; - } - cp++; - } - } - } - - if (cp - candidates) - { - tree rval = error_mark_node; - - /* Leave marker. */ - cp[0].evil = 1; - if (cp - candidates > 1) - { - struct candidate *best_cp - = ideal_candidate (NULL_TREE, candidates, - cp - candidates, parms, parmlength); - if (best_cp == (struct candidate *)0) - { - if (complain) - error ("call of overloaded `%s' is ambiguous", IDENTIFIER_POINTER (fnname)); - return error_mark_node; - } - else - rval = best_cp->function; - } - else - { - cp -= 1; - if (cp->evil > 1) - { - if (complain) - error ("type conversion ambiguous"); - } - else - rval = cp->function; - } - - if (final_cp) - return rval; - - return buildxxx ? build_function_call_maybe (rval, parms) - : build_function_call (rval, parms); - } - else if (complain) - { - tree name; - char *err_name; - - /* Initialize name for error reporting. */ - if (TREE_CODE (functions) == TREE_LIST) - name = TREE_PURPOSE (functions); - else if (TREE_CODE (functions) == ADDR_EXPR) - /* Since the implicit `operator new' and `operator delete' functions - are set up to have IDENTIFIER_GLOBAL_VALUEs that are unary ADDR_EXPRs - by default_conversion(), we must compensate for that here by - using the name of the ADDR_EXPR's operand. */ - name = DECL_NAME (TREE_OPERAND (functions, 0)); - else - name = DECL_NAME (functions); - - if (IDENTIFIER_OPNAME_P (name)) - { - char *opname = operator_name_string (name); - err_name = (char *)alloca (strlen (opname) + 12); - sprintf (err_name, "operator %s", opname); - } - else - err_name = IDENTIFIER_POINTER (name); - - report_type_mismatch (cp, parms, "function", err_name); - } - return error_mark_node; -} - -tree -build_overload_call (fnname, parms, complain, final_cp) - tree fnname, parms; - int complain; - struct candidate *final_cp; -{ - return build_overload_call_real (fnname, parms, complain, final_cp, 0); -} - -tree -build_overload_call_maybe (fnname, parms, complain, final_cp) - tree fnname, parms; - int complain; - struct candidate *final_cp; -{ - return build_overload_call_real (fnname, parms, complain, final_cp, 1); -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-class.c b/gnu/usr.bin/gcc2/cc1plus/cp-class.c deleted file mode 100644 index 2358628acbb..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-class.c +++ /dev/null @@ -1,4277 +0,0 @@ -/* Functions related to building classes and their related objects. - Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-class.c,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $"; -#endif /* not lint */ - -/* High-level class interface. */ - -#include "config.h" -#include "tree.h" -#include -#include "cp-tree.h" -#include "flags.h" - -#ifdef DEBUG_CP_BINDING_LEVELS -#include "cp-decl.h" -#endif - -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern struct obstack permanent_obstack; - -/* Way of stacking class types. */ -static tree *current_class_base, *current_class_stack; -static int current_class_stacksize; -int current_class_depth; - -struct class_level -{ - /* The previous class level. */ - struct class_level *level_chain; - - /* The class instance variable, as a PARM_DECL. */ - tree decl; - /* The class instance variable, as an object. */ - tree object; - /* The virtual function table pointer - for the class instance variable. */ - tree vtable_decl; - - /* Name of the current class. */ - tree name; - /* Type of the current class. */ - tree type; - - /* Flags for this class level. */ - int this_is_variable; - int memoized_lookups; - int save_memoized; - int unused; -}; - -tree current_class_decl, C_C_D; /* PARM_DECL: the class instance variable */ -tree current_vtable_decl; - -/* The following two can be derived from the previous one */ -tree current_class_name; /* IDENTIFIER_NODE: name of current class */ -tree current_class_type; /* _TYPE: the type of the current class */ -static tree prev_class_type; /* _TYPE: the previous type that was a class */ - -static tree get_vfield_name PROTO((tree)); -tree the_null_vtable_entry; - -/* Way of stacking language names. */ -tree *current_lang_base, *current_lang_stack; -static int current_lang_stacksize; - -/* Names of languages we recognize. */ -tree lang_name_c, lang_name_cplusplus; -tree current_lang_name; - -/* When layout out an aggregate type, the size of the - basetypes (virtual and non-virtual) is passed to layout_record - via this node. */ -static tree base_layout_decl; - -/* Variables shared between cp-class.c and cp-call.c. */ - -int n_vtables = 0; -int n_vtable_entries = 0; -int n_vtable_searches = 0; -int n_vtable_elems = 0; -int n_convert_harshness = 0; -int n_compute_conversion_costs = 0; -int n_build_method_call = 0; -int n_inner_fields_searched = 0; - -/* Virtual baseclass things. */ -tree -build_vbase_pointer (exp, type) - tree exp, type; -{ - char *name; - - name = (char *) alloca (TYPE_NAME_LENGTH (type) + sizeof (VBASE_NAME) + 1); - sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (type)); - return build_component_ref (exp, get_identifier (name), 0, 0); -} - -/* Build multi-level access to EXPR using hierarchy path PATH. - CODE is PLUS_EXPR if we are going with the grain, - and MINUS_EXPR if we are not (in which case, we cannot traverse - virtual baseclass links). - - TYPE is the type we want this path to have on exit. - - ALIAS_THIS is non-zero if EXPR in an expression involving `this'. */ -tree -build_vbase_path (code, type, expr, path, alias_this) - enum tree_code code; - tree type, expr, path; - int alias_this; -{ - register int changed = 0; - tree last = NULL_TREE, last_virtual = NULL_TREE; - int nonnull = 0; - int fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); - tree null_expr = 0, nonnull_expr; - tree basetype; - tree offset = integer_zero_node; - - if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) - expr = save_expr (expr); - nonnull_expr = expr; - - if (BINFO_INHERITANCE_CHAIN (path)) - { - tree reverse_path = NULL_TREE; - - while (path) - { - tree r = copy_node (path); - BINFO_INHERITANCE_CHAIN (r) = reverse_path; - reverse_path = r; - path = BINFO_INHERITANCE_CHAIN (path); - } - path = reverse_path; - } - - basetype = BINFO_TYPE (path); - - while (path) - { - if (TREE_VIA_VIRTUAL (path)) - { - last_virtual = BINFO_TYPE (path); - if (code == PLUS_EXPR) - { - changed = ! fixed_type_p; - - if (changed) - { - extern int flag_assume_nonnull_objects; - tree ind; - - if (last) - nonnull_expr = convert_pointer_to (last, nonnull_expr); - ind = build_indirect_ref (nonnull_expr, NULL); - nonnull_expr = build_vbase_pointer (ind, last_virtual); - if (nonnull == 0 && !flag_assume_nonnull_objects - && null_expr == NULL_TREE) - { - null_expr = build1 (NOP_EXPR, TYPE_POINTER_TO (last_virtual), integer_zero_node); - expr = build (COND_EXPR, TYPE_POINTER_TO (last_virtual), - build (EQ_EXPR, integer_type_node, expr, - integer_zero_node), - null_expr, nonnull_expr); - } - } - /* else we'll figure out the offset below. */ - - /* Happens in the case of parse errors. */ - if (nonnull_expr == error_mark_node) - return error_mark_node; - } - else - { - error_with_aggr_type (last_virtual, "cannot cast up from virtual baseclass `%s'"); - return error_mark_node; - } - } - last = path; - path = BINFO_INHERITANCE_CHAIN (path); - } - /* LAST is now the last basetype assoc on the path. */ - - /* A pointer to a virtual base member of a non-null object - is non-null. Therefore, we only need to test for zeroness once. - Make EXPR the canonical expression to deal with here. */ - if (null_expr) - { - TREE_OPERAND (expr, 2) = nonnull_expr; - TREE_TYPE (TREE_OPERAND (expr, 1)) = TREE_TYPE (nonnull_expr); - } - else - expr = nonnull_expr; - - /* If we go through any virtual base pointers, make sure that - casts to BASETYPE from the last virtual base class use - the right value for BASETYPE. */ - if (changed) - { - tree intype = TREE_TYPE (TREE_TYPE (expr)); - if (TYPE_MAIN_VARIANT (intype) == BINFO_TYPE (last)) - basetype = intype; - else - { - tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0); - basetype = last; - offset = BINFO_OFFSET (binfo); - } - } - else - { - if (last_virtual) - { - offset = BINFO_OFFSET (binfo_member (last_virtual, - CLASSTYPE_VBASECLASSES (basetype))); - offset = size_binop (PLUS_EXPR, offset, BINFO_OFFSET (last)); - } - else - offset = BINFO_OFFSET (last); - -#if 0 - /* why unconditionally set this? (mrs) see deja-gnu/g++.mike/net15.C - for a test case. */ - code = PLUS_EXPR; -#endif - } - - if (TREE_INT_CST_LOW (offset)) - { - /* For multiple inheritance: if `this' can be set by any - function, then it could be 0 on entry to any function. - Preserve such zeroness here. Otherwise, only in the - case of constructors need we worry, and in those cases, - it will be zero, or initialized to some legal value to - which we may add. */ - if (nonnull == 0 && (alias_this == 0 || flag_this_is_variable > 0)) - { - if (null_expr) - TREE_TYPE (null_expr) = type; - else - null_expr = build1 (NOP_EXPR, type, integer_zero_node); - if (TREE_SIDE_EFFECTS (expr)) - expr = save_expr (expr); - - return build (COND_EXPR, type, - build (EQ_EXPR, integer_type_node, expr, integer_zero_node), - null_expr, - build (code, type, expr, offset)); - } - else return build (code, type, expr, offset); - } - - /* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may - be used multiple times in initialization of multiple inheritance. */ - if (null_expr) - { - TREE_TYPE (expr) = type; - return expr; - } - else - return build1 (NOP_EXPR, type, expr); -} - -/* Virtual function things. */ - -/* Virtual functions to be dealt with after laying out our - base classes. Usually this is used only when classes have virtual - baseclasses, but it can happen also when classes have non-virtual - baseclasses if the derived class overrides baseclass functions - at different offsets. */ -static tree pending_hard_virtuals; -static int doing_hard_virtuals; - -/* The names of the entries in the virtual table structure. */ -static tree delta_name, pfn_name; - -/* XXX This is set but never used. (bpk) */ -#if 0 -/* Temporary binfo list to memoize lookups of the left-most non-virtual - baseclass B in a lattice topped by T. B can appear multiple times - in the lattice. - TREE_PURPOSE is B's TYPE_MAIN_VARIANT. - TREE_VALUE is the path by which B is reached from T. - TREE_TYPE is B's real type. - - If TREE_TYPE is NULL_TREE, it means that B was reached via - a virtual baseclass. - N.B.: This list consists of nodes on the temporary obstack. */ -static tree leftmost_baseclasses; -#endif - -/* Build an entry in the virtual function table. - DELTA is the offset for the `this' pointer. - PFN is an ADDR_EXPR containing a pointer to the virtual function. - Note that the index (DELTA2) in the virtual function table - is always 0. */ -tree -build_vtable_entry (delta, pfn) - tree delta, pfn; -{ - tree elems = tree_cons (NULL_TREE, delta, - tree_cons (NULL_TREE, integer_zero_node, - build_tree_list (NULL_TREE, pfn))); - tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems); - - /* DELTA is constructed by `size_int', which means it may be an - unsigned quantity on some platforms. Therefore, we cannot use - `int_fits_type_p', because when DELTA is really negative, - `force_fit_type' will make it look like a very large number. */ - - if ((TREE_INT_CST_LOW (TYPE_MAX_VALUE (short_integer_type_node)) - < TREE_INT_CST_LOW (delta)) - || (TREE_INT_CST_LOW (delta) - < TREE_INT_CST_LOW (TYPE_MIN_VALUE (short_integer_type_node)))) - sorry ("object size exceeds built-in limit for virtual function table implementation"); - - TREE_CONSTANT (entry) = 1; - TREE_STATIC (entry) = 1; - TREE_READONLY (entry) = 1; - -#ifdef GATHER_STATISTICS - n_vtable_entries += 1; -#endif - - return entry; -} - -/* Given an object INSTANCE, return an expression which yields - the virtual function corresponding to INDEX. There are many special - cases for INSTANCE which we take care of here, mainly to avoid - creating extra tree nodes when we don't have to. */ -tree -build_vfn_ref (ptr_to_instptr, instance, index) - tree *ptr_to_instptr, instance; - tree index; -{ - extern int building_cleanup; - tree vtbl, aref; - tree basetype = TREE_TYPE (instance); - - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); - - if (instance == C_C_D) - { - if (current_vtable_decl == NULL_TREE - || current_vtable_decl == error_mark_node - || !UNIQUELY_DERIVED_FROM_P (DECL_FCONTEXT (CLASSTYPE_VFIELD (current_class_type)), basetype)) - vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), NULL); - else - vtbl = current_vtable_decl; - } - else - { - if (optimize) - { - /* Try to figure out what a reference refers to, and - access its virtual function table directly. */ - tree ref = NULL_TREE; - - if (TREE_CODE (instance) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE) - ref = TREE_OPERAND (instance, 0); - else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) - ref = instance; - - if (ref && TREE_CODE (ref) == VAR_DECL - && DECL_INITIAL (ref)) - { - tree init = DECL_INITIAL (ref); - - while (TREE_CODE (init) == NOP_EXPR - || TREE_CODE (init) == NON_LVALUE_EXPR) - init = TREE_OPERAND (init, 0); - if (TREE_CODE (init) == ADDR_EXPR) - { - init = TREE_OPERAND (init, 0); - if (IS_AGGR_TYPE (TREE_TYPE (init)) - && (TREE_CODE (init) == PARM_DECL - || TREE_CODE (init) == VAR_DECL)) - instance = init; - } - } - } - - if (IS_AGGR_TYPE (TREE_TYPE (instance)) - && (TREE_CODE (instance) == RESULT_DECL - || TREE_CODE (instance) == PARM_DECL - || TREE_CODE (instance) == VAR_DECL)) - vtbl = TYPE_BINFO_VTABLE (basetype); - else - vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), - NULL); - } - assemble_external (vtbl); - aref = build_array_ref (vtbl, index); - if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF) - TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); - - *ptr_to_instptr = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr), - *ptr_to_instptr, - convert (integer_type_node, build_component_ref (aref, delta_name, 0, 0))); - return build_component_ref (aref, pfn_name, 0, 0); -} - -/* Set TREE_PUBLIC and/or TREE_EXTERN on the vtable DECL, - based on TYPE and other static flags. - - Note that anything public is tagged TREE_PUBLIC, whether - it's public in this file or in another one. */ - -static void -import_export_vtable (decl, type) - tree decl, type; -{ - if (write_virtuals >= 2) - { - if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); - } - } - else if (write_virtuals != 0) - { - TREE_PUBLIC (decl) = 1; - if (write_virtuals < 0) - DECL_EXTERNAL (decl) = 1; - } -} - -/* Return the name of the virtual function table (as an IDENTIFIER_NODE) - for the given TYPE. */ -static tree -get_vtable_name (type) - tree type; -{ - tree type_id = build_typename_overload (type); - char *buf = (char *)alloca (sizeof (VTABLE_NAME_FORMAT) - + IDENTIFIER_LENGTH (type_id) + 2); - char *ptr = IDENTIFIER_POINTER (type_id); - int i; - for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; - while (ptr[i] >= '0' && ptr[i] <= '9') - i += 1; - sprintf (buf, VTABLE_NAME_FORMAT, ptr+i); - return get_identifier (buf); -} - -/* Build a virtual function for type TYPE. - If BINFO is non-NULL, build the vtable starting with the initial - approximation that it is the same as the one which is the head of - the association list. */ -static tree -build_vtable (binfo, type) - tree binfo, type; -{ - tree name = get_vtable_name (type); - tree virtuals, decl; - - if (binfo) - { - virtuals = copy_list (BINFO_VIRTUALS (binfo)); - decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo))); - } - else - { - virtuals = NULL_TREE; - decl = build_decl (VAR_DECL, name, void_type_node); - } - -#ifdef GATHER_STATISTICS - n_vtables += 1; - n_vtable_elems += list_length (virtuals); -#endif - - /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - import_export_vtable (decl, type); - - IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl); - /* Initialize the association list for this type, based - on our first approximation. */ - TYPE_BINFO_VTABLE (type) = decl; - TYPE_BINFO_VIRTUALS (type) = virtuals; - - TREE_STATIC (decl) = 1; - DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (decl)); - - if (binfo && write_virtuals >= 0) - DECL_VIRTUAL_P (decl) = 1; -#if 0 - /* Remember which class this vtable is really for. */ - if (binfo) - DECL_VPARENT (decl) = BINFO_TYPE (binfo); - else - DECL_VPARENT (decl) = type; -#endif - DECL_CONTEXT (decl) = type; - - binfo = TYPE_BINFO (type); - SET_BINFO_VTABLE_PATH_MARKED (binfo); - SET_BINFO_NEW_VTABLE_MARKED (binfo); - return decl; -} - -/* Give TYPE a new virtual function table which is initialized - with a skeleton-copy of its original initialization. The only - entry that changes is the `delta' entry, so we can really - share a lot of structure. - - FOR_TYPE is the derived type which caused this table to - be needed. - - BINFO is the type association which provided TYPE for FOR_TYPE. - - The way we update BASE_BINFO's vtable information is just to change the - association information in FOR_TYPE's association list. */ -static void -prepare_fresh_vtable (binfo, base_binfo, for_type) - tree binfo, base_binfo, for_type; -{ - tree basetype = BINFO_TYPE (binfo); - tree orig_decl = BINFO_VTABLE (binfo); - tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type); - tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); - tree path; - int result; - - /* Remember which class this vtable is really for. */ -#if 0 - DECL_VPARENT (new_decl) = BINFO_TYPE (base_binfo); -#endif - DECL_CONTEXT (new_decl) = for_type; - - TREE_STATIC (new_decl) = 1; - BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl); - DECL_VIRTUAL_P (new_decl) = 1; - DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); - - /* Make fresh virtual list, so we can smash it later. */ - BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo)); - /* Install the value for `headof' if that's what we're doing. */ - if (flag_dossier) - TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo))) - = build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, BINFO_OFFSET (binfo)), - FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo))))); - -#ifdef GATHER_STATISTICS - n_vtables += 1; - n_vtable_elems += list_length (BINFO_VIRTUALS (binfo)); -#endif - - /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - import_export_vtable (new_decl, for_type); - - if (TREE_VIA_VIRTUAL (binfo)) - my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (current_class_type)), - 170); - SET_BINFO_NEW_VTABLE_MARKED (binfo); - SET_BINFO_VTABLE_PATH_MARKED (binfo); - - /* Mark all types between FOR_TYPE and TYPE as having been - touched, so that if we change virtual function table entries, - new vtables will be initialized. We may reach the virtual - baseclass via ambiguous intervening baseclasses. This - loop makes sure we get through to the actual baseclass we marked. - - Also, update the vtable entries to reflect the overrides - of the top-most class (short of the top type). */ - - do - { - result = get_base_distance (basetype, for_type, 0, &path); - for_type = path; - while (path) - { - tree path_binfo = path; - tree path_type = BINFO_TYPE (path); - - if (TREE_VIA_VIRTUAL (path)) - path_binfo = binfo_member (path_type, - CLASSTYPE_VBASECLASSES (current_class_type)); - - SET_BINFO_VTABLE_PATH_MARKED (path_binfo); - if (BINFO_INHERITANCE_CHAIN (path) - && CLASSTYPE_VFIELD (path_type) != NULL_TREE - && (DECL_NAME (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))) - == DECL_NAME (CLASSTYPE_VFIELD (path_type))) - /* This is the baseclass just before the original FOR_TYPE. */ - && BINFO_INHERITANCE_CHAIN (BINFO_INHERITANCE_CHAIN (path)) == NULL_TREE) - { - tree old_virtuals = TREE_CHAIN (BINFO_VIRTUALS (binfo)); - tree new_virtuals = TREE_CHAIN (BINFO_VIRTUALS (path_binfo)); - if (flag_dossier) - { - old_virtuals = TREE_CHAIN (old_virtuals); - new_virtuals = TREE_CHAIN (new_virtuals); - } - while (old_virtuals) - { - TREE_VALUE (old_virtuals) = TREE_VALUE (new_virtuals); - old_virtuals = TREE_CHAIN (old_virtuals); - new_virtuals = TREE_CHAIN (new_virtuals); - } - } - path = BINFO_INHERITANCE_CHAIN (path); - } - } - while (result == -2); -} - -/* Access the virtual function table entry that logically - contains BASE_FNDECL. VIRTUALS is the virtual function table's - initializer. */ -static tree -get_vtable_entry (virtuals, base_fndecl) - tree virtuals, base_fndecl; -{ - unsigned HOST_WIDE_INT i = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD -#ifdef VTABLE_USES_MASK - && 0 -#endif - ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)) - & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1)) - : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))); - -#ifdef GATHER_STATISTICS - n_vtable_searches += i; -#endif - - while (i > 0) - { - virtuals = TREE_CHAIN (virtuals); - i -= 1; - } - return virtuals; -} - -/* Put new entry ENTRY into virtual function table initializer - VIRTUALS. The virtual function table is for type CONTEXT. - - Also update DECL_VINDEX (FNDECL). */ - -static void -modify_vtable_entry (old_entry_in_list, new_entry, fndecl, context) - tree old_entry_in_list, new_entry, fndecl, context; -{ - tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)); - tree vindex; - - /* We can't put in the really right offset information - here, since we have not yet laid out the class to - take into account virtual base classes. */ - TREE_VALUE (old_entry_in_list) = new_entry; - vindex = DECL_VINDEX (TREE_OPERAND (base_pfn, 0)); - if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) - DECL_VINDEX (fndecl) = vindex; - else - { - if (! tree_int_cst_equal (DECL_VINDEX (fndecl), vindex)) - { - tree elts = CONSTRUCTOR_ELTS (new_entry); - tree vfield = CLASSTYPE_VFIELD (context); - - if (! doing_hard_virtuals) - { - pending_hard_virtuals - = tree_cons (fndecl, FNADDR_FROM_VTABLE_ENTRY (new_entry), - pending_hard_virtuals); - TREE_TYPE (pending_hard_virtuals) = TREE_OPERAND (base_pfn, 0); - return; - } - -#if 0 - my_friendly_abort (3); - - /* Compute the relative offset of vtable we are really looking for. */ - TREE_VALUE (elts) = size_binop (PLUS_EXPR, - size_int (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (vfield)) -/* ??? This may be wrong. */ - / BITS_PER_UNIT), - TREE_VALUE (elts)); - /* Say what index to use when we use that vtable. */ -#ifndef VTABLE_USES_MASK - vindex = build_int_2 (TREE_INT_CST_LOW (vindex) - & ~((unsigned HOST_WIDE_INT) 1 - << (BITS_PER_WORD -1)), 0); -#endif - TREE_VALUE (TREE_CHAIN (elts)) = vindex; -#endif - } - } -} - -/* Check to ensure that the virtual function table slot in VFIELD, - found by DECL_VINDEX of the BASE_FNDECL is in fact from a parent - virtual function table that is the same parent as for the - BASE_FNDECL given to us. */ - -static int -related_vslot (base_fndecl, vfields, type) - tree base_fndecl, vfields, type; -{ - tree base_context = TYPE_MAIN_VARIANT (DECL_CONTEXT (base_fndecl)); - tree base; - tree path; - int distance; - - if (TREE_CODE (vfields) != TREE_LIST) - abort (); - base = VF_NORMAL_VALUE (vfields); - if (base == NULL_TREE) - base = VF_BASETYPE_VALUE (vfields); - - /* The simple right way to do this is to ensure that the context of - the base virtual function is found along the leftmost path - between the most derived type associated with the vfield and the - current type. */ - distance = get_base_distance (base, type, 0, &path); - if (distance == -1) - abort (); - while (path) - { - if (BINFO_TYPE (path) == base_context) - return 1; - path = BINFO_INHERITANCE_CHAIN (path); - } - - /* given: - Rr - / \ - Mm Hh - \ / - P - - make sure we fill in P's vtable for H with overrides of r, - but be cautious of virtual base classes. */ - /* Combine the two below after debugging. */ - if (get_base_distance (base_context, base, 0, &path) != -1) - { - while (path) - { - if (TREE_VIA_VIRTUAL (path)) - return 0; - path = BINFO_INHERITANCE_CHAIN (path); - } - return 1; - } - return 0; -} - -/* Modify virtual function tables in lattice topped by T to - place FNDECL in tables which previously held BASE_FNDECL. - PFN is just FNDECL wrapped in an ADDR_EXPR, so that it - is suitable for placement directly into an initializer. - - All distinct virtual function tables that this type uses - must be updated. */ -static void -modify_vtable_entries (t, fndecl, base_fndecl, pfn) - tree t; - tree fndecl, base_fndecl, pfn; -{ - tree base_offset, offset; - tree base_context = DECL_CLASS_CONTEXT (base_fndecl); - tree context = DECL_CLASS_CONTEXT (fndecl); - tree vfield = CLASSTYPE_VFIELD (t); - tree vfields, vbases; - - DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl); - - offset = integer_zero_node; - if (context != t && TYPE_USES_COMPLEX_INHERITANCE (t)) - { - offset = virtual_offset (context, CLASSTYPE_VBASECLASSES (t), offset); - if (offset == NULL_TREE) - { - tree binfo = binfo_value (context, t); - offset = BINFO_OFFSET (binfo); - } - } - - /* For each layer of base class (i.e., the first base class, and each - virtual base class from that one), modify the virtual function table - of the derived class to contain the new virtual function. - A class has as many vfields as it has virtual base classes (total). */ - for (vfields = CLASSTYPE_VFIELDS (t); vfields; vfields = TREE_CHAIN (vfields)) - { - int normal = 1; - tree binfo, this_offset; - tree base, path; - -/* This can go away when the new searching strategy as a little mileage on it. */ -#define NEW_SEARCH 1 -#if NEW_SEARCH - if (!related_vslot (base_fndecl, vfields, t)) - continue; -#endif - - /* Find the right base class for this derived class, call it BASE. */ - base = VF_BASETYPE_VALUE (vfields); - -#if NEW_SEARCH == 0 - if (base != base_context) - { - /* If BASE_FNDECL is not contained in the vtable accessed by - the vslot, don't try to modify the vtable. - - Virtual functions from virtual baseclasses are not in derived - virtual function tables. This is an implementation decision; - it keeps there from being a combinatorial explosion in the - number of different vtables which must be maintained. */ - - /* In this case, we need to know whether BASE is derived - from BASE_CONTEXT in any case, even the case where the - derivation is ambiguous. */ - int distance = get_base_distance (base, base_context, 0, (tree *)0); - if (distance < 0 && distance != -2) - continue; - - /* BASE_FNDECL is defined in a class derived from - the base class owning this VFIELD. */ - } -#endif - - /* Get the path starting from the deepest base class CONTEXT - of T (i.e., first defn of BASE_FNDECL). */ - get_base_distance (base_context, t, 0, &path); - - /* Get our best approximation of what to use for constructing - the virtual function table for T. */ - do - { - /* Walk from base toward derived, stopping at the - most derived baseclass that matters. That baseclass - is exactly the one which provides the vtable along - the VFIELD spine, but no more. */ - if (TREE_VIA_VIRTUAL (path)) - { - base = path; - binfo = binfo_member (BINFO_TYPE (base), CLASSTYPE_VBASECLASSES (t)); - break; - } - if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE - || (BINFO_TYPE (BINFO_BASETYPE (BINFO_INHERITANCE_CHAIN (path), 0)) - != BINFO_TYPE (path)) - || BINFO_INHERITANCE_CHAIN (BINFO_INHERITANCE_CHAIN (path)) == NULL_TREE) - { - base = path; - binfo = base; - break; - } - path = BINFO_INHERITANCE_CHAIN (path); - } - while (1); - - /* Find the right offset for the this pointer based on the base - class we just found. */ - base_offset = BINFO_OFFSET (binfo); - this_offset = size_binop (MINUS_EXPR, offset, base_offset); - - /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (TYPE_BINFO (t))) - TYPE_BINFO (t) = copy_binfo (TYPE_BINFO (t)); - - /* We call this case NORMAL iff this virtual function table - pointer field has its storage reserved in this class. - This is normally the case without virtual baseclasses - or off-center multiple baseclasses. */ - normal = (vfield != NULL_TREE - && VF_BASETYPE_VALUE (vfields) == DECL_FCONTEXT (vfield) - && (VF_BINFO_VALUE (vfields) == NULL_TREE - || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))); - - if (normal && VF_BINFO_VALUE (vfields)) - /* Everything looks normal so far...check that we are really - working from VFIELD's basetype, and not some other appearance - of that basetype in the lattice. */ - normal = (VF_BINFO_VALUE (vfields) - == get_binfo (VF_BASETYPE_VALUE (vfields), t, 0)); - - if (normal) - { - /* In this case, it is *type*'s vtable we are modifying. - We start with the approximation that it's vtable is that - of the immediate base class. */ - base_context = t; - binfo = TYPE_BINFO (t); - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t); - } - else - { - /* This is our very own copy of `basetype' to play with. - Later, we will fill in all the virtual functions - that override the virtual functions in these base classes - which are not defined by the current type. */ - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - prepare_fresh_vtable (binfo, base, t); - } - - modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (binfo), base_fndecl), - build_vtable_entry (this_offset, pfn), - fndecl, base_context); - } - for (vbases = CLASSTYPE_VBASECLASSES (t); vbases; vbases = TREE_CHAIN (vbases)) - { - tree this_offset; - tree base, path; - - if (! BINFO_VTABLE (vbases)) - /* There are only two ways that a type can fail to have - virtual functions: neither it nor any of its base - types define virtual functions (in which case - no updating need be done), or virtual functions - accessible to it come from virtual base classes - (in which case we have or will get them modified - in other passes of this loop). */ - continue; - - base = BINFO_TYPE (vbases); - path = NULL_TREE; - - if (base != base_context - && get_base_distance (base_context, base, 0, &path) == -1) - continue; - - if (path) - this_offset = size_binop (MINUS_EXPR, offset, BINFO_OFFSET (path)); - else - this_offset = offset; - - /* Doesn't matter if not actually from this virtual base class, - but shouldn't come from deeper virtual baseclasses. The enclosing - loop should take care of such baseclasses. */ - while (path) - { - if (TREE_VIA_VIRTUAL (path)) - goto skip; - path = BINFO_INHERITANCE_CHAIN (path); - } - - base_offset = BINFO_OFFSET (vbases); - this_offset = size_binop (MINUS_EXPR, this_offset, base_offset); - - /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (TYPE_BINFO (t))) - TYPE_BINFO (t) = copy_binfo (TYPE_BINFO (t)); - - /* This is our very own copy of `basetype' to play with. */ - if (! BINFO_NEW_VTABLE_MARKED (vbases)) - { - tree context_binfo = binfo_value (base_context, base); - prepare_fresh_vtable (vbases, context_binfo, t); - } - modify_vtable_entry (get_vtable_entry (BINFO_VIRTUALS (vbases), base_fndecl), - build_vtable_entry (this_offset, pfn), - fndecl, base_context); - skip: {} - } -} - -static tree -add_virtual_function (pending_virtuals, has_virtual, x, t) - tree pending_virtuals; - int *has_virtual; - tree x; - tree t; /* Structure type. */ -{ - int debug_vbase = 1; - - /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely - convert to void *. Make such a conversion here. */ - tree vfn = build1 (ADDR_EXPR, ptr_type_node, x); - TREE_CONSTANT (vfn) = 1; - - /* current_class_type may be NULL_TREE in case of error. */ - if (current_class_type) - TREE_ADDRESSABLE (x) = CLASSTYPE_VTABLE_NEEDS_WRITING (current_class_type); - - /* If the virtual function is a redefinition of a prior one, - figure out in which base class the new definition goes, - and if necessary, make a fresh virtual function table - to hold that entry. */ - if (DECL_VINDEX (x) == error_mark_node) - { - tree entry = build_vtable_entry (integer_zero_node, vfn); - - if (flag_dossier && *has_virtual == 0) - { - /* CLASSTYPE_DOSSIER is only used as a Boolean (NULL or not). */ - CLASSTYPE_DOSSIER (t) = integer_one_node; - *has_virtual = 1; - } - - /* Build a new INT_CST for this DECL_VINDEX. */ -#ifdef VTABLE_USES_MASK - SET_DECL_VINDEX (x, build_int_2 (++(*has_virtual), 0)); -#else - { - static tree index_table[256]; - tree index; - int i = ++(*has_virtual); - - if (i >= 256 || index_table[i] == 0) - { - index = build_int_2 (((unsigned HOST_WIDE_INT) 1 - << (BITS_PER_WORD - 1)) | i, ~0); - if (i < 256) - index_table[i] = index; - } - else - index = index_table[i]; - - DECL_VINDEX (x) = index; - } -#endif - pending_virtuals = tree_cons (DECL_VINDEX (x), entry, pending_virtuals); - } - /* Happens if declared twice in class or we're not in a class definition. - We will give error later or we've already given it. */ - else if (TREE_CODE (DECL_VINDEX (x)) == INTEGER_CST - || current_class_type == NULL_TREE) - return pending_virtuals; - else if (debug_vbase && TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - { - /* Need an entry in some other virtual function table. - Deal with this after we have laid out our virtual base classes. */ - pending_hard_virtuals = temp_tree_cons (x, vfn, pending_hard_virtuals); - } - else - { - /* Need an entry in some other virtual function table. - We can do this now. */ - tree base_fndecl_list = DECL_VINDEX (x), base_fndecls, prev = 0; - tree vtable_context = DECL_FCONTEXT (CLASSTYPE_VFIELD (current_class_type)); - tree true_base_fndecl = 0; - - /* First assign DECL_VINDEX from the base vfn with which - we share our vtable. */ - base_fndecls = base_fndecl_list; - while (base_fndecls) - { - if (TREE_CHAIN (base_fndecls) == NULL_TREE - || DECL_FCONTEXT (CLASSTYPE_VFIELD (DECL_CLASS_CONTEXT (TREE_VALUE (base_fndecls)))) == vtable_context) - { - true_base_fndecl = TREE_VALUE (base_fndecls); - modify_vtable_entries (current_class_type, x, - true_base_fndecl, vfn); - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (base_fndecls); - else - base_fndecl_list = prev; - break; - } - prev = base_fndecls; - base_fndecls = TREE_CHAIN (base_fndecls); - } - - /* Now fill in the rest of the vtables. */ - base_fndecls = base_fndecl_list; - while (base_fndecls) - { - /* If we haven't found one we like, first one wins. */ - if (true_base_fndecl == 0) - true_base_fndecl = TREE_VALUE (base_fndecls); - - modify_vtable_entries (current_class_type, x, - TREE_VALUE (base_fndecls), vfn); - base_fndecls = TREE_CHAIN (base_fndecls); - } - - DECL_CONTEXT (x) = DECL_CONTEXT (true_base_fndecl); - } - return pending_virtuals; -} - -/* Obstack on which to build the vector of class methods. */ -struct obstack class_obstack; -extern struct obstack *current_obstack; - -/* Add method METHOD to class TYPE. This is used when a method - has been defined which did not initially appear in the class definition, - and helps cut down on spurious error messages. - - FIELDS is the entry in the METHOD_VEC vector entry of the class type where - the method should be added. */ -void -add_method (type, fields, method) - tree type, *fields, method; -{ - /* We must make a copy of METHOD here, since we must be sure that - we have exclusive title to this method's DECL_CHAIN. */ - tree decl; - - push_obstacks (&permanent_obstack, &permanent_obstack); - { - decl = copy_node (method); - if (DECL_RTL (decl) == 0 - && (!processing_template_decl - || !uses_template_parms (decl))) - { - make_function_rtl (decl); - DECL_RTL (method) = DECL_RTL (decl); - } - } - - if (fields && *fields) - { - /* Take care not to hide destructor. */ - DECL_CHAIN (decl) = DECL_CHAIN (*fields); - DECL_CHAIN (*fields) = decl; - } - else if (CLASSTYPE_METHOD_VEC (type) == 0) - { - tree method_vec = make_node (TREE_VEC); - if (TYPE_IDENTIFIER (type) == DECL_NAME (decl)) - { - TREE_VEC_ELT (method_vec, 0) = decl; - TREE_VEC_LENGTH (method_vec) = 1; - } - else - { - /* ??? Is it possible for there to have been enough room in the - current chunk for the tree_vec structure but not a tree_vec - plus a tree*? Will this work in that case? */ - obstack_free (current_obstack, method_vec); - obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *)); - TREE_VEC_ELT (method_vec, 1) = decl; - TREE_VEC_LENGTH (method_vec) = 2; - obstack_finish (current_obstack); - } - CLASSTYPE_METHOD_VEC (type) = method_vec; - } - else - { - tree method_vec = CLASSTYPE_METHOD_VEC (type); - int len = TREE_VEC_LENGTH (method_vec); - - /* Adding a new ctor or dtor. This is easy because our - METHOD_VEC always has a slot for such entries. */ - if (TYPE_IDENTIFIER (type) == DECL_NAME (decl)) - { - /* TREE_VEC_ELT (method_vec, 0) = decl; */ - if (decl != TREE_VEC_ELT (method_vec, 0)) - { - DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, 0); - TREE_VEC_ELT (method_vec, 0) = decl; - } - } - else - { - /* This is trickier. We try to extend the TREE_VEC in-place, - but if that does not work, we copy all its data to a new - TREE_VEC that's large enough. */ - struct obstack *ob = &class_obstack; - tree *end = (tree *)obstack_next_free (ob); - - if (end != TREE_VEC_END (method_vec)) - { - ob = current_obstack; - TREE_VEC_LENGTH (method_vec) += 1; - TREE_VEC_ELT (method_vec, len) = NULL_TREE; - method_vec = copy_node (method_vec); - TREE_VEC_LENGTH (method_vec) -= 1; - } - else - { - tree tmp_vec = (tree) obstack_base (ob); - if (obstack_room (ob) < sizeof (tree)) - { - obstack_blank (ob, sizeof (struct tree_common) - + tree_code_length[(int) TREE_VEC] - * sizeof (char *) - + len * sizeof (tree)); - tmp_vec = (tree) obstack_base (ob); - bcopy (method_vec, tmp_vec, - (sizeof (struct tree_common) - + tree_code_length[(int) TREE_VEC] * sizeof (char *) - + (len-1) * sizeof (tree))); - method_vec = tmp_vec; - } - else - obstack_blank (ob, sizeof (tree)); - } - - obstack_finish (ob); - TREE_VEC_ELT (method_vec, len) = decl; - TREE_VEC_LENGTH (method_vec) = len + 1; - CLASSTYPE_METHOD_VEC (type) = method_vec; - - if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type)) - { - /* ??? May be better to know whether these can be extended? */ - tree baselink_vec = CLASSTYPE_BASELINK_VEC (type); - - TREE_VEC_LENGTH (baselink_vec) += 1; - CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec); - TREE_VEC_LENGTH (baselink_vec) -= 1; - - TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0; - } - } - } - DECL_CONTEXT (decl) = type; - DECL_CLASS_CONTEXT (decl) = type; - - pop_obstacks (); -} - -/* Subroutines of finish_struct. */ - -/* Look through the list of fields for this struct, deleting - duplicates as we go. This must be recursive to handle - anonymous unions. - - FIELD is the field which may not appear anywhere in FIELDS. - FIELD_PTR, if non-null, is the starting point at which - chained deletions may take place. - The value returned is the first acceptable entry found - in FIELDS. - - Note that anonymous fields which are not of UNION_TYPE are - not duplicates, they are just anonymous fields. This happens - when we have unnamed bitfields, for example. */ -static tree -delete_duplicate_fields_1 (field, field_ptr, fields) - tree field, *field_ptr, fields; -{ - tree x; - tree prev = field_ptr ? *field_ptr : 0; - if (DECL_NAME (field) == 0) - { - if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE) - return fields; - - for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x)) - fields = delete_duplicate_fields_1 (x, field_ptr, fields); - if (prev) - TREE_CHAIN (prev) = fields; - return fields; - } - else - { - for (x = fields; x; prev = x, x = TREE_CHAIN (x)) - { - if (DECL_NAME (x) == 0) - { - if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE) - continue; - TYPE_FIELDS (TREE_TYPE (x)) - = delete_duplicate_fields_1 (field, (tree *)0, TYPE_FIELDS (TREE_TYPE (x))); - if (TYPE_FIELDS (TREE_TYPE (x)) == 0) - { - if (prev == 0) - fields = TREE_CHAIN (fields); - else - TREE_CHAIN (prev) = TREE_CHAIN (x); - } - } - else - { - if (DECL_NAME (field) == DECL_NAME (x)) - { - if (TREE_CODE (field) == CONST_DECL - && TREE_CODE (x) == CONST_DECL) - error_with_decl (x, "duplicate enum value `%s'"); - else if (TREE_CODE (field) == CONST_DECL - || TREE_CODE (x) == CONST_DECL) - error_with_decl (x, "duplicate field `%s' (as enum and non-enum)"); - else if (TREE_CODE (field) == TYPE_DECL - && TREE_CODE (x) == TYPE_DECL) - error_with_decl (x, "duplicate class scope type `%s'"); - else if (TREE_CODE (field) == TYPE_DECL - || TREE_CODE (x) == TYPE_DECL) - error_with_decl (x, "duplicate field `%s' (as type and non-type)"); - else - error_with_decl (x, "duplicate member `%s'"); - if (prev == 0) - fields = TREE_CHAIN (fields); - else - TREE_CHAIN (prev) = TREE_CHAIN (x); - } - } - } - } - return fields; -} - -static void -delete_duplicate_fields (fields) - tree fields; -{ - tree x; - for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x)) - TREE_CHAIN (x) = delete_duplicate_fields_1 (x, &x, TREE_CHAIN (x)); -} - -/* Change the visibility of T::FDECL to VISIBILITY. - Return 1 if change was legit, otherwise return 0. */ -static int -alter_visibility (t, fdecl, visibility) - tree t; - tree fdecl; - enum visibility_type visibility; -{ - tree elem = purpose_member (t, DECL_VISIBILITY (fdecl)); - if (elem && TREE_VALUE (elem) != (tree)visibility) - { - if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL) - { - error_with_decl (TREE_TYPE (fdecl), "conflicting visibility specifications for method `%s', ignored"); - } - else error ("conflicting visibility specifications for field `%s', ignored", IDENTIFIER_POINTER (DECL_NAME (fdecl))); - } - else if (TREE_PRIVATE (fdecl) && visibility != visibility_private) - error_with_decl (fdecl, "cannot make private `%s' non-private"); - else if (TREE_PROTECTED (fdecl) && visibility == visibility_public) - error_with_decl (fdecl, "cannot make protected `%s' public"); - /* ARM 11.3: an access declaration may not be used to restrict access - to a member that is accessible in the base class. */ - else if (TREE_PUBLIC (fdecl) - && (visibility == visibility_private - || visibility == visibility_protected)) - error_with_decl (fdecl, "cannot reduce visibility of public member `%s'"); - else if (elem == NULL_TREE) - { - DECL_VISIBILITY (fdecl) = tree_cons (t, (tree)visibility, - DECL_VISIBILITY (fdecl)); - return 1; - } - return 0; -} - -static tree -get_vfield_offset (binfo) - tree binfo; -{ - return size_binop (PLUS_EXPR, - DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))), - BINFO_OFFSET (binfo)); -} - -/* If FOR_TYPE needs to reinitialize virtual function table pointers - for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST. - Returns BASE_INIT_LIST appropriately modified. */ - -static tree -maybe_fixup_vptrs (for_type, binfo, base_init_list) - tree for_type, binfo, base_init_list; -{ - /* Now reinitialize any slots that don't fall under our virtual - function table pointer. */ - tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)); - while (vfields) - { - tree base_binfo = get_binfo (VF_BASETYPE_VALUE (vfields), for_type, 0); - if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (VF_BASETYPE_VALUE (vfields))) - { - tree base_offset = get_vfield_offset (base_binfo); - if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type))) - && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo))) - base_init_list = tree_cons (error_mark_node, base_binfo, - base_init_list); - } - vfields = TREE_CHAIN (vfields); - } - return base_init_list; -} - -/* If TYPE does not have a constructor, then the compiler must - manually deal with all of the initialization this type requires. - - If a base initializer exists only to fill in the virtual function - table pointer, then we mark that fact with the TREE_VIRTUAL bit. - This way, we avoid multiple initializations of the same field by - each virtual function table up the class hierarchy. - - Virtual base class pointers are not initialized here. They are - initialized only at the "top level" of object creation. If we - initialized them here, we would have to skip a lot of work. */ - -static void -build_class_init_list (type) - tree type; -{ - tree base_init_list = NULL_TREE; - tree member_init_list = NULL_TREE; - - /* Since we build member_init_list and base_init_list using - tree_cons, backwards fields the all through work. */ - tree x; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x)) - { - if (TREE_CODE (x) != FIELD_DECL) - continue; - - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x)) - || DECL_INITIAL (x) != NULL_TREE) - member_init_list = tree_cons (x, type, member_init_list); - } - member_init_list = nreverse (member_init_list); - - /* We will end up doing this last. Need special marker - to avoid infinite regress. */ - if (TYPE_VIRTUAL_P (type)) - { - base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type)); - if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0) - TREE_VALUE (base_init_list) = NULL_TREE; - TREE_ADDRESSABLE (base_init_list) = 1; - } - - /* Each base class which needs to have initialization - of some kind gets to make such requests known here. */ - for (i = n_baseclasses-1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree blist; - - /* Don't initialize virtual baseclasses this way. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo))) - { - /* ...and the last shall come first... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - continue; - } - - if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE) - /* Nothing to initialize. */ - continue; - - /* ...ditto... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - - /* This is normally true for single inheritance. - The win is we can shrink the chain of initializations - to be done by only converting to the actual type - we are interested in. */ - if (TREE_VALUE (blist) - && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC - && tree_int_cst_equal (BINFO_OFFSET (base_binfo), - BINFO_OFFSET (TREE_VALUE (blist)))) - { - if (base_init_list) - { - /* Does it do more than just fill in a - virtual function table pointer? */ - if (! TREE_ADDRESSABLE (blist)) - base_init_list = build_tree_list (blist, base_init_list); - /* Can we get by just with the virtual function table - pointer that it fills in? */ - else if (TREE_ADDRESSABLE (base_init_list) - && TREE_VALUE (base_init_list) == 0) - base_init_list = blist; - /* Maybe, but it is not obvious as the previous case. */ - else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type)) - { - tree last = tree_last (base_init_list); - while (TREE_VALUE (last) - && TREE_CODE (TREE_VALUE (last)) == TREE_LIST) - last = tree_last (TREE_VALUE (last)); - if (TREE_VALUE (last) == 0) - base_init_list = build_tree_list (blist, base_init_list); - } - } - else - base_init_list = blist; - } - else - { - /* The function expand_aggr_init knows how to do the - initialization of `basetype' without getting - an explicit `blist'. */ - if (base_init_list) - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - else - base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo)); - } - } - - if (base_init_list) - if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = build_tree_list (base_init_list, member_init_list); - else - CLASSTYPE_BASE_INIT_LIST (type) = base_init_list; - else if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = member_init_list; -} - -struct base_info -{ - int has_virtual; - int max_has_virtual; - int n_ancestors; - tree vfield; - tree vfields; - char needs_default_ctor; - char cant_have_default_ctor; - char needs_const_ctor; - char cant_have_const_ctor; - char members_need_dtors; - char needs_virtual_dtor; -}; - -/* Record information about type T derived from its base classes. - Store most of that information in T itself, and place the - remaining information in the struct BASE_INFO. - - Propagate basetype offsets throughout the lattice. Note that the - lattice topped by T is really a pair: it's a DAG that gives the - structure of the derivation hierarchy, and it's a list of the - virtual baseclasses that appear anywhere in the DAG. When a vbase - type appears in the DAG, it's offset is 0, and it's children start - their offsets from that point. When a vbase type appears in the list, - its offset is the offset it has in the hierarchy, and its children's - offsets include that offset in theirs. - - Returns the index of the first base class to have virtual functions, - or zero if no such base class. */ - -static int -finish_base_struct (t, b, binfos) - tree t; - struct base_info *b; - tree binfos; -{ - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int first_vfn_base_index = -1; - bzero (b, sizeof (struct base_info)); - - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - /* If the type of basetype is incomplete, then - we already complained about that fact - (and we should have fixed it up as well). */ - if (TYPE_SIZE (basetype) == 0) - { - int j; - /* The base type is of incomplete type. It is - probably best to pretend that it does not - exist. */ - if (i == n_baseclasses-1) - TREE_VEC_ELT (binfos, i) = NULL_TREE; - TREE_VEC_LENGTH (binfos) -= 1; - n_baseclasses -= 1; - for (j = i; j+1 < n_baseclasses; j++) - TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1); - } - - if (TYPE_NEEDS_DESTRUCTOR (basetype)) - b->members_need_dtors = 1; - if (TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)) - b->needs_default_ctor = 1; - else if (TYPE_HAS_CONSTRUCTOR (basetype)) - b->cant_have_default_ctor = 1; - if (TYPE_GETS_CONST_INIT_REF (basetype)) - b->needs_const_ctor = 1; - else if (TYPE_GETS_INIT_REF (basetype)) - b->cant_have_const_ctor = 1; - - CLASSTYPE_ALTERS_VISIBILITIES_P (t) - |= CLASSTYPE_ALTERS_VISIBILITIES_P (basetype); - - b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype); - TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); - TYPE_NEEDS_CONSTRUCTOR (t) |= TYPE_NEEDS_CONSTRUCTOR (basetype); - TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype); - TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (basetype); - TYPE_GETS_INIT_REF (t) |= TYPE_GETS_INIT_REF (basetype); - - TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype); - TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); - TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); - - if (! TREE_VIA_VIRTUAL (base_binfo) -#if 0 - /* This cannot be done, as prepare_fresh_vtable wants to modify - binfos associated with vfields anywhere in the hierarchy, not - just immediate base classes. Due to unsharing, the compiler - might consume 3% more memory on a real program. - */ - && ! BINFO_OFFSET_ZEROP (base_binfo) -#endif - && BINFO_BASETYPES (base_binfo)) - { - tree base_binfos = BINFO_BASETYPES (base_binfo); - tree chain = NULL_TREE; - int j; - - /* Now unshare the structure beneath BASE_BINFO. */ - for (j = TREE_VEC_LENGTH (base_binfos)-1; - j >= 0; j--) - { - tree base_base_binfo = TREE_VEC_ELT (base_binfos, j); - if (! TREE_VIA_VIRTUAL (base_base_binfo)) - TREE_VEC_ELT (base_binfos, j) - = make_binfo (BINFO_OFFSET (base_base_binfo), - BINFO_TYPE (base_base_binfo), - BINFO_VTABLE (base_base_binfo), - BINFO_VIRTUALS (base_base_binfo), - chain); - chain = TREE_VEC_ELT (base_binfos, j); - TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); - TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); - } - - /* Completely unshare potentially shared data, and - update what is ours. */ - propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); - } - - if (! TREE_VIA_VIRTUAL (base_binfo)) - CLASSTYPE_N_SUPERCLASSES (t) += 1; - - if (TYPE_VIRTUAL_P (basetype)) - { - /* If there's going to be a destructor needed, make - sure it will be virtual. */ - b->needs_virtual_dtor = 1; - - /* Don't borrow virtuals from virtual baseclasses. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - if (first_vfn_base_index < 0) - { - first_vfn_base_index = i; - - b->has_virtual = CLASSTYPE_VSIZE (basetype); - b->vfield = CLASSTYPE_VFIELD (basetype); - b->vfields = CLASSTYPE_VFIELDS (basetype); - CLASSTYPE_VFIELD (t) = b->vfield; - } - else - { - /* Only add unique vfields, and flatten them out as we go. */ - tree vfields = CLASSTYPE_VFIELDS (basetype); - while (vfields) - { - if (VF_BINFO_VALUE (vfields) == NULL_TREE - || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) - { - tree value = VF_BASETYPE_VALUE (vfields); - b->vfields = tree_cons (base_binfo, value, b->vfields); - if (DECL_NAME (CLASSTYPE_VFIELD (value)) - == DECL_NAME (CLASSTYPE_VFIELD (basetype))) - VF_NORMAL_VALUE (b->vfields) = basetype; - else - VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); - } - vfields = TREE_CHAIN (vfields); - } - - if (b->has_virtual == 0) - { - first_vfn_base_index = i; - b->has_virtual = CLASSTYPE_VSIZE (basetype); - b->vfield = CLASSTYPE_VFIELD (basetype); - CLASSTYPE_VFIELD (t) = b->vfield; - } - } - } - } - - { - tree vfields; - /* Find the base class with the largest number of virtual functions. */ - for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields)) - { - if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual) - b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)); - if (VF_DERIVED_VALUE (vfields) - && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual) - b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)); - } - } - - if (b->vfield == 0) - /* If all virtual functions come only from virtual baseclasses. */ - return -1; - return first_vfn_base_index; -} - -static int -typecode_p (type, code) - tree type; - enum tree_code code; -{ - return (TREE_CODE (type) == code - || (TREE_CODE (type) == REFERENCE_TYPE - && TREE_CODE (TREE_TYPE (type)) == code)); -} - -/* Set memoizing fields and bits of T (and its variants) for later use. - MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables. */ -static void -finish_struct_bits (t, max_has_virtual) - tree t; - int max_has_virtual; -{ - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - tree method_vec = CLASSTYPE_METHOD_VEC (t); - - /* Fix up variants (if any). */ - tree variants = TYPE_NEXT_VARIANT (t); - while (variants) - { - /* These fields are in the _TYPE part of the node, not in - the TYPE_LANG_SPECIFIC component, so they are not shared. */ - TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t); - TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t); - TYPE_NEEDS_CONSTRUCTOR (variants) = TYPE_NEEDS_CONSTRUCTOR (t); - TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t); - TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t); - - TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t); - TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t); - TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t); - /* Copy whatever these are holding today. */ - TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t); - TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t); - variants = TYPE_NEXT_VARIANT (variants); - } - - if (n_baseclasses && max_has_virtual) - { - /* Done by `finish_struct' for classes without baseclasses. */ - int has_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0; - tree binfos = TYPE_BINFO_BASETYPES (t); - for (i = n_baseclasses-1; i >= 0; i--) - { - has_abstract_virtuals - |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0); - if (has_abstract_virtuals) - break; - } - if (has_abstract_virtuals) - CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t); - } - - if (n_baseclasses) - { - /* Notice whether this class has type conversion functions defined. - Also report whether joining two types yields an ambiguity in the - virtual function table, e.g., - - struct A { virtual int f (); }; - struct B { virtual int f (); }; - struct C : A, B { / * no f (); * / }; / / error, ambiguous - */ - tree binfo = TYPE_BINFO (t); - tree binfos = BINFO_BASETYPES (binfo); - int n_binfos = list_length (binfo); - tree vbases = CLASSTYPE_VBASECLASSES (t), basetype; - int n_vbases = list_length (vbases), j; - - build_mi_virtuals (n_binfos+n_vbases*n_baseclasses, max_has_virtual); - /* Fill in virtual function table with values which do not come - "normal"ly, i.e., those which come from virtual and/or - non-leftmost base classes. */ - for (i = 0; binfo; binfo = TREE_CHAIN (binfo)) - { - if (TREE_VIA_VIRTUAL (binfo)) - /* Virtual functions from virtual baseclasses are done below. */; - else if (CLASSTYPE_VSIZE (BINFO_TYPE (binfo))) - { - tree virtuals = TREE_CHAIN (BINFO_VIRTUALS (binfo)); - if (flag_dossier) - virtuals = TREE_CHAIN (virtuals); - add_mi_virtuals (++i, virtuals); - } - } - for (; vbases; vbases = TREE_CHAIN (vbases)) - { - basetype = BINFO_TYPE (vbases); - if (CLASSTYPE_VSIZE (basetype)) - for (j = n_baseclasses-1; j >= 0; j--) - { - tree this_binfo = TREE_VEC_ELT (binfos, j); - if (UNIQUELY_DERIVED_FROM_P (basetype, this_binfo)) - { - tree virtuals = TREE_CHAIN (BINFO_VIRTUALS (vbases)); - if (flag_dossier) - virtuals = TREE_CHAIN (virtuals); - add_mi_virtuals (++i, virtuals); - } - } - } - for (i = n_baseclasses-1; i >= 0; i--) - { - basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); - - if (TYPE_HAS_CONVERSION (basetype)) - { - TYPE_HAS_CONVERSION (t) = 1; - TYPE_HAS_INT_CONVERSION (t) |= TYPE_HAS_INT_CONVERSION (basetype); - TYPE_HAS_REAL_CONVERSION (t) |= TYPE_HAS_REAL_CONVERSION (basetype); - } - if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t)) - CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1; - } - report_ambiguous_mi_virtuals (n_binfos+n_vbases*n_baseclasses, t); -#if 0 - /* Now that we know what the virtual function table looks like, - fix up offsets in the presence of virtual base classes. */ - if (n_vbases) - fixup_vbase_offsets (t); -#endif - } - - /* Need to test METHOD_VEC here in case all methods - (conversions and otherwise) are inherited. */ - if (TYPE_HAS_CONVERSION (t) && method_vec != NULL_TREE) - { - tree first_conversions[last_conversion_type]; - tree last_conversions[last_conversion_type]; - enum conversion_type conv_index; - tree *tmp; - int i; - - bzero (first_conversions, sizeof (first_conversions)); - bzero (last_conversions, sizeof (last_conversions)); - for (tmp = &TREE_VEC_ELT (method_vec, 1); - tmp != TREE_VEC_END (method_vec); tmp += 1) - { - /* ??? This should compare DECL_NAME (*tmp) == ansi_opname[TYPE_EXPR]. */ - if (IDENTIFIER_TYPENAME_P (DECL_ASSEMBLER_NAME (*tmp))) - { - tree fntype = TREE_TYPE (*tmp); - tree return_type = TREE_TYPE (fntype); - my_friendly_assert (TREE_CODE (fntype) == METHOD_TYPE, 171); - - if (typecode_p (return_type, POINTER_TYPE)) - { - if (TYPE_READONLY (TREE_TYPE (return_type))) - conv_index = constptr_conv; - else - conv_index = ptr_conv; - } - else if (typecode_p (return_type, INTEGER_TYPE)) - { - TYPE_HAS_INT_CONVERSION (t) = 1; - conv_index = int_conv; - } - else if (typecode_p (return_type, REAL_TYPE)) - { - TYPE_HAS_REAL_CONVERSION (t) = 1; - conv_index = real_conv; - } - else - continue; - - if (first_conversions[(int) conv_index] == NULL_TREE) - first_conversions[(int) conv_index] = *tmp; - last_conversions[(int) conv_index] = *tmp; - } - } - - for (i = 0; i < (int) last_conversion_type; i++) - if (first_conversions[i] != last_conversions[i]) - CLASSTYPE_CONVERSION (t, i) = error_mark_node; - else - CLASSTYPE_CONVERSION (t, i) = first_conversions[i]; - } - - /* If this type has constructors, force its mode to be BLKmode, - and force its TREE_ADDRESSABLE bit to be nonzero. */ - if (TYPE_NEEDS_CONSTRUCTING (t) || TYPE_NEEDS_DESTRUCTOR (t)) - { - tree variants = t; - - if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL) - DECL_MODE (TYPE_NAME (t)) = BLKmode; - while (variants) - { - TYPE_MODE (variants) = BLKmode; - TREE_ADDRESSABLE (variants) = 1; - variants = TYPE_NEXT_VARIANT (variants); - } - } -} - -/* Warn about duplicate methods in fn_fields. Also compact method - lists so that lookup can be made faster. - - Algorithm: Outer loop builds lists by method name. Inner loop - checks for redundant method names within a list. - - Data Structure: List of method lists. The outer list is a - TREE_LIST, whose TREE_PURPOSE field is the field name and the - TREE_VALUE is the TREE_CHAIN of the FUNCTION_DECLs. Friends are - chained in the same way as member functions, but they live in the - TREE_TYPE field of the outer list. That allows them to be quickly - deleted, and requires no extra storage. - - If there are any constructors/destructors, they are moved to the - front of the list. This makes pushclass more efficient. - - We also link each field which has shares a name with its baseclass - to the head of the list of fields for that base class. This allows - us to reduce search time in places like `build_method_call' to - consider only reasonably likely functions. */ - -static tree -finish_struct_methods (t, fn_fields, nonprivate_method) - tree t; - tree fn_fields; - int nonprivate_method; -{ - tree method_vec; - tree name = constructor_name (t); - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - - /* Now prepare to gather fn_fields into vector. */ - struct obstack *ambient_obstack = current_obstack; - current_obstack = &class_obstack; - method_vec = make_node (TREE_VEC); - /* Room has been saved for constructors and destructors. */ - current_obstack = ambient_obstack; - /* Now make this a live vector. */ - obstack_free (&class_obstack, method_vec); - obstack_blank (&class_obstack, sizeof (struct tree_vec)); - - while (fn_fields) - { - /* NEXT Pointer, TEST Pointer, and BASE Pointer. */ - tree nextp, *testp; - tree fn_name = DECL_NAME (fn_fields); - if (fn_name == NULL_TREE) - fn_name = name; - - nextp = TREE_CHAIN (fn_fields); - TREE_CHAIN (fn_fields) = NULL_TREE; - /* Constructors are handled easily in search routines. - Besides, we know we won't find any, so do not bother looking. */ - if (fn_name == name && TREE_VEC_ELT (method_vec, 0) == 0) - TREE_VEC_ELT (method_vec, 0) = fn_fields; - else - { - testp = &TREE_VEC_ELT (method_vec, 0); - if (*testp == NULL_TREE) - testp++; - while (((HOST_WIDE_INT) testp - < (HOST_WIDE_INT) obstack_next_free (&class_obstack)) - && DECL_NAME (*testp) != fn_name) - testp++; - if ((HOST_WIDE_INT) testp - < (HOST_WIDE_INT) obstack_next_free (&class_obstack)) - { - tree x, prev_x; - - for (x = *testp; x; x = DECL_CHAIN (x)) - { - if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR]) - { - /* ANSI C++ June 5 1992 WP 12.5.5.1 */ - error_with_decl (fn_fields, "operator delete cannot be overloaded"); - error_with_decl (x, "previous declaration here"); - } - if (DECL_ASSEMBLER_NAME (fn_fields) == DECL_ASSEMBLER_NAME (x)) - { - /* We complain about multiple destructors on sight, - so we do not repeat the warning here. Friend-friend - ambiguities are warned about outside this loop. */ - if (! DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields))) - error_with_file_and_line (DECL_SOURCE_FILE (fn_fields), - DECL_SOURCE_LINE (fn_fields), - "ambiguous method `%s' in structure", - lang_printable_name (fn_fields)); - break; - } - prev_x = x; - } - if (x == 0) - if (*testp) - DECL_CHAIN (prev_x) = fn_fields; - else - *testp = fn_fields; - } - else - { - obstack_ptr_grow (&class_obstack, fn_fields); - method_vec = (tree)obstack_base (&class_obstack); - } - } - fn_fields = nextp; - } - - TREE_VEC_LENGTH (method_vec) - = (tree *)obstack_next_free (&class_obstack) - (&TREE_VEC_ELT (method_vec, 0)); - obstack_finish (&class_obstack); - CLASSTYPE_METHOD_VEC (t) = method_vec; - - if (nonprivate_method == 0 - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE) - { - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - for (i = 0; i < n_baseclasses; i++) - if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i)) - || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i))) - { - nonprivate_method = 1; - break; - } - if (nonprivate_method == 0) - warning ("all member functions in class `%s' are private", - TYPE_NAME_STRING (t)); - } - - /* If there are constructors (and destructors), they are at the - front. Place destructors at very front. Also warn if all - constructors and/or destructors are private (in which case this - class is effectively unusable. */ - if (TYPE_HAS_DESTRUCTOR (t)) - { - tree dtor, prev; - - for (dtor = TREE_VEC_ELT (method_vec, 0); dtor; prev = dtor, dtor = DECL_CHAIN (dtor)) - { - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor))) - { - if (TREE_PRIVATE (dtor) - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE) - warning_with_decl (TYPE_NAME (t), "class `%s' only defines a private destructor and has no friends"); - break; - } - } - /* Wild parse errors can cause this to happen. */ - if (dtor == NULL_TREE) - TYPE_HAS_DESTRUCTOR (t) = 0; - else if (dtor != TREE_VEC_ELT (method_vec, 0)) - { - DECL_CHAIN (prev) = DECL_CHAIN (dtor); - DECL_CHAIN (dtor) = TREE_VEC_ELT (method_vec, 0); - TREE_VEC_ELT (method_vec, 0) = dtor; - } - } - - /* Now for each member function (except for constructors and - destructors), compute where member functions of the same - name reside in base classes. */ - if (n_baseclasses != 0 - && TREE_VEC_LENGTH (method_vec) > 1) - { - int len = TREE_VEC_LENGTH (method_vec); - tree baselink_vec = make_tree_vec (len); - int any_links = 0; - tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - for (i = 1; i < len; i++) - { - TREE_VEC_ELT (baselink_vec, i) - = get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i))); - if (TREE_VEC_ELT (baselink_vec, i) != 0) - any_links = 1; - } - if (any_links != 0) - CLASSTYPE_BASELINK_VEC (t) = baselink_vec; - else - obstack_free (current_obstack, baselink_vec); - } - - /* Now add the methods to the TYPE_METHODS of T, arranged in a chain. */ - { - tree x, last_x = NULL_TREE; - int limit = TREE_VEC_LENGTH (method_vec); - - for (i = 1; i < limit; i++) - { - for (x = TREE_VEC_ELT (method_vec, i); x; x = DECL_CHAIN (x)) - { - if (last_x != NULL_TREE) - TREE_CHAIN (last_x) = x; - last_x = x; - } - } - - /* Put ctors and dtors at the front of the list. */ - x = TREE_VEC_ELT (method_vec, 0); - if (x) - { - while (DECL_CHAIN (x)) - { - /* Let's avoid being circular about this. */ - if (x == DECL_CHAIN (x)) - break; - TREE_CHAIN (x) = DECL_CHAIN (x); - x = DECL_CHAIN (x); - } - if (TREE_VEC_LENGTH (method_vec) > 1) - TREE_CHAIN (x) = TREE_VEC_ELT (method_vec, 1); - else - TREE_CHAIN (x) = NULL_TREE; - } - } - -#if 0 - TYPE_METHODS (t) = TREE_VEC_ELT (method_vec, 0) - ? TREE_VEC_ELT (method_vec, 0) : TREE_VEC_ELT (method_vec, 1); -#else - TYPE_METHODS (t) = method_vec; -#endif - - return method_vec; -} - -/* Emit error when a duplicate definition of a type is seen. Patch up. */ - -void -duplicate_tag_error (t) - tree t; -{ - char *err_name; - tree name = TYPE_NAME (t); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - err_name = IDENTIFIER_POINTER (name); - if (TREE_CODE (t) == UNION_TYPE) - error ("redefinition of `union %s'", err_name); - else if (TREE_CODE (t) == RECORD_TYPE) - error ("redefinition of `struct %s'", err_name); - else - error ("redefinition of tag %s", err_name); - - /* Pretend we haven't defined this type. */ - - /* All of the component_decl's were TREE_CHAINed together in the parser. - finish_struct_methods walks these chains and assembles all methods with - the same base name into DECL_CHAINs. Now we don't need the parser chains - anymore, so we unravel them. - */ - /* - * This used to be in finish_struct, but it turns out that the - * TREE_CHAIN is used by dbxout_type_methods and perhaps some other things... - */ - if (CLASSTYPE_METHOD_VEC(t)) - { - tree tv = CLASSTYPE_METHOD_VEC(t); - int i, len = TREE_VEC_LENGTH (tv); - for (i = 0; i < len; i++) - { - tree unchain = TREE_VEC_ELT (tv, i); - while(unchain != NULL_TREE) - { - TREE_CHAIN (unchain) = NULL_TREE; - unchain = DECL_CHAIN(unchain); - } - } - } - - if (TYPE_LANG_SPECIFIC (t)) - { - tree as_list = CLASSTYPE_AS_LIST (t); - tree binfo = TYPE_BINFO (t); - tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t); - int interface_only = CLASSTYPE_INTERFACE_ONLY (t); - int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t); - - bzero (TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type)); - BINFO_BASETYPES(binfo) = NULL_TREE; - - CLASSTYPE_AS_LIST (t) = as_list; - TYPE_BINFO (t) = binfo; - CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list; - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown; - CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; - TYPE_REDEFINED (t) = 1; - } - TYPE_SIZE (t) = NULL_TREE; - TYPE_MODE (t) = VOIDmode; - TYPE_FIELDS (t) = NULL_TREE; - TYPE_METHODS (t) = NULL_TREE; - TYPE_VFIELD (t) = NULL_TREE; - TYPE_CONTEXT (t) = NULL_TREE; -} - -/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration - (or C++ class declaration). - - For C++, we must handle the building of derived classes. - Also, C++ allows static class members. The way that this is - handled is to keep the field name where it is (as the DECL_NAME - of the field), and place the overloaded decl in the DECL_FIELD_BITPOS - of the field. layout_record and layout_union will know about this. - - More C++ hair: inline functions have text in their - DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into - meaningful tree structure. After the struct has been laid out, set - things up so that this can happen. - - And still more: virtual functions. In the case of single inheritance, - when a new virtual function is seen which redefines a virtual function - from the base class, the new virtual function is placed into - the virtual function table at exactly the same address that - it had in the base class. When this is extended to multiple - inheritance, the same thing happens, except that multiple virtual - function tables must be maintained. The first virtual function - table is treated in exactly the same way as in the case of single - inheritance. Additional virtual function tables have different - DELTAs, which tell how to adjust `this' to point to the right thing. - - LIST_OF_FIELDLISTS is just that. The elements of the list are - TREE_LIST elements, whose TREE_PURPOSE field tells what visibility - the list has, and the TREE_VALUE slot gives the actual fields. - - If flag_all_virtual == 1, then we lay all functions into - the virtual function table, as though they were declared - virtual. Constructors do not lay down in the virtual function table. - - If flag_all_virtual == 2, then we lay all functions into - the virtual function table, such that virtual functions - occupy a space by themselves, and then all functions - of the class occupy a space by themselves. This is illustrated - in the following diagram: - - class A; class B : A; - - Class A's vtbl: Class B's vtbl: - -------------------------------------------------------------------- - | A's virtual functions| | B's virtual functions | - | | | (may inherit some from A). | - -------------------------------------------------------------------- - | All of A's functions | | All of A's functions | - | (such as a->A::f). | | (such as b->A::f) | - -------------------------------------------------------------------- - | B's new virtual functions | - | (not defined in A.) | - ------------------------------- - | All of B's functions | - | (such as b->B::f) | - ------------------------------- - - this allows the program to make references to any function, virtual - or otherwise in a type-consistent manner. */ - -tree -finish_struct (t, list_of_fieldlists, warn_anon) - tree t; - tree list_of_fieldlists; - int warn_anon; -{ - extern int interface_only, interface_unknown; - int old; - int round_up_size = 1; - /* Set non-zero to debug using default functions. - Not set by program. */ - static int debug_default_functions = 0; - - enum tree_code code = TREE_CODE (t); - register tree x, last_x, method_vec; - int needs_ctor = 0, needs_dtor = 0; - int members_need_dtors, needs_virtual_dtor; - tree name = TYPE_NAME (t), fields, fn_fields, tail; - enum visibility_type visibility; - int all_virtual; - int has_virtual; - int max_has_virtual; - tree pending_virtuals = NULL_TREE; - tree abstract_virtuals = NULL_TREE; - tree vfield; - tree vfields; - int needs_default_ctor; - int cant_have_default_ctor; - int needs_const_ctor; - int cant_have_const_ctor; - - /* The index of the first base class which has virtual - functions. Only applied to non-virtual baseclasses. */ - int first_vfn_base_index; - - int n_baseclasses; - int any_default_members = 0; - char *err_name; - int const_sans_init = 0; - int ref_sans_init = 0; - int nonprivate_method = 0; - tree t_binfo = TYPE_BINFO (t); - - if (TREE_CODE (name) == TYPE_DECL) - { - extern int lineno; - - DECL_SOURCE_FILE (name) = input_filename; - /* For TYPE_DECL that are not typedefs (those marked with a line number - of zero, we don't want to mark them as real typedefs. If this fails - one needs to make sure real typedefs have a previous line number, - even if it is wrong, that way the below will fill in the right line - number. (mrs) */ - if (DECL_SOURCE_LINE (name)) - DECL_SOURCE_LINE (name) = lineno; - name = DECL_NAME (name); - } - err_name = IDENTIFIER_POINTER (name); - - if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (name)) - { - warning ("un-usable class ignored (anonymous classes and unions are useless)"); - err_name = "(anon)"; - } - -#if 0 - /* This is set here, but it's never actually used anywhere. (bpk) */ - leftmost_baseclasses = NULL_TREE; -#endif - if (TYPE_SIZE (t)) - { - if (TREE_CODE (t) == UNION_TYPE) - error ("redefinition of `union %s'", err_name); - else if (TREE_CODE (t) == RECORD_TYPE) - error ("redefinition of `struct %s'", err_name); - else - my_friendly_abort (172); - popclass (0); - return t; - } - - GNU_xref_decl (current_function_decl, t); - - /* If this type was previously laid out as a forward reference, - make sure we lay it out again. */ - - TYPE_SIZE (t) = 0; - CLASSTYPE_GOT_SEMICOLON (t) = 0; - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown; - - if (flag_dossier) - build_t_desc (t, 0); - - TYPE_BINFO (t) = NULL_TREE; - - old = suspend_momentary (); - - /* Install struct as DECL_FIELD_CONTEXT of each field decl. - Also process specified field sizes. - Set DECL_FIELD_SIZE to the specified size, or 0 if none specified. - The specified size is found in the DECL_INITIAL. - Store 0 there, except for ": 0" fields (so we can find them - and delete them, below). */ - - if (t_binfo && BINFO_BASETYPES (t_binfo)) - n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo)); - else - n_baseclasses = 0; - - if (n_baseclasses > 0) - { - struct base_info base_info; - - /* If using multiple inheritance, this may cause variants of our - basetypes to be used (instead of their canonical forms). */ - fields = layout_basetypes (t, BINFO_BASETYPES (t_binfo)); - last_x = tree_last (fields); - - first_vfn_base_index = finish_base_struct (t, &base_info, - BINFO_BASETYPES (t_binfo)); - has_virtual = base_info.has_virtual; - max_has_virtual = base_info.max_has_virtual; - CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors; - vfield = base_info.vfield; - vfields = base_info.vfields; - needs_default_ctor = base_info.needs_default_ctor; - cant_have_default_ctor = base_info.cant_have_default_ctor; - needs_const_ctor = base_info.needs_const_ctor; - cant_have_const_ctor = base_info.cant_have_const_ctor; - members_need_dtors = base_info.members_need_dtors; - needs_virtual_dtor = base_info.needs_virtual_dtor; - n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo)); - } - else - { - first_vfn_base_index = -1; - has_virtual = 0; - max_has_virtual = has_virtual; - vfield = NULL_TREE; - vfields = NULL_TREE; - fields = NULL_TREE; - last_x = NULL_TREE; - needs_default_ctor = 0; - cant_have_default_ctor = 0; - needs_const_ctor = 0; - cant_have_const_ctor = 0; - members_need_dtors = 0; - needs_virtual_dtor = 0; - } - - if (write_virtuals == 3 && ! CLASSTYPE_INTERFACE_UNKNOWN (t) - && current_lang_name == lang_name_cplusplus) - { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only; - } - - /* The three of these are approximations which may later be - modified. Needed at this point to make add_virtual_function - and modify_vtable_entries work. */ - TREE_CHAIN (t_binfo) = TYPE_BINFO (t); - TYPE_BINFO (t) = t_binfo; - CLASSTYPE_VFIELDS (t) = vfields; - CLASSTYPE_VFIELD (t) = vfield; - - fn_fields = NULL_TREE; - tail = NULL_TREE; - if (last_x && list_of_fieldlists) - TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists); - - if (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (t)) - all_virtual = 1; - else - all_virtual = 0; - - if (CLASSTYPE_DECLARED_CLASS (t) == 0) - { - nonprivate_method = 1; - if (list_of_fieldlists - && TREE_PURPOSE (list_of_fieldlists) == (tree)visibility_default) - TREE_PURPOSE (list_of_fieldlists) = (tree)visibility_public; - } - else if (list_of_fieldlists - && TREE_PURPOSE (list_of_fieldlists) == (tree)visibility_default) - TREE_PURPOSE (list_of_fieldlists) = (tree)visibility_private; - - while (list_of_fieldlists) - { - visibility = (enum visibility_type)TREE_PURPOSE (list_of_fieldlists); - - for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x)) - { - TREE_PRIVATE (x) = visibility == visibility_private; - TREE_PROTECTED (x) = visibility == visibility_protected; - GNU_xref_member (current_class_name, x); - - if (TREE_CODE (x) == TYPE_DECL - && TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE) - { -#if 0 - /* @@ Um. This doesn't seem to be handled properly, at - least in my PT test cases. Not sure if it's really - supposed to work for non-PT cases. Let's find out. */ - static tree t, d; - d = DECL_NAME (x); - t = TYPE_IDENTIFIER (TREE_TYPE (x)); - if (d == t) continue; - if (IDENTIFIER_TEMPLATE (t)) - { - t = DECL_NAME (TREE_PURPOSE (IDENTIFIER_TEMPLATE (t))); - my_friendly_assert (t == d, 173); - continue; - } - else if (IDENTIFIER_CLASS_VALUE (t)) - my_friendly_assert (TREE_TYPE (DECL_NAME (d)) - == TREE_TYPE (DECL_NAME (TREE_TYPE (t))), - 174); - else - abort (); -#endif - continue; - } - - - if (TREE_CODE (x) == FUNCTION_DECL) - { - /* Clear out this flag. - - @@ Doug may figure out how to break - @@ this with nested classes and friends. */ - DECL_IN_AGGR_P (x) = 0; - - nonprivate_method |= ! TREE_PRIVATE (x); - - /* If this was an evil function, don't keep it in class. */ - if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) - continue; - - if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); - if (! fn_fields) fn_fields = x; - else TREE_CHAIN (tail) = x; - tail = x; - -#if 0 - /* ??? What if we have duplicate declarations - in T's definition? */ - if (DECL_CLASS_CONTEXT (x)) - continue; -#endif - DECL_CLASS_CONTEXT (x) = t; - - DECL_FIELD_SIZE (x) = 0; - - /* The name of the field is the original field name - Save this in auxiliary field for later overloading. */ - if (DECL_VINDEX (x) - || (all_virtual == 1 && ! DECL_CONSTRUCTOR_P (x))) - { - pending_virtuals = add_virtual_function (pending_virtuals, - &has_virtual, x, t); - if (DECL_ABSTRACT_VIRTUAL_P (x)) - abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals); - } - continue; - } - - /* Handle visibility declarations. */ - if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF) - { - tree fdecl = TREE_OPERAND (DECL_NAME (x), 1); - - if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); - /* Make type T see field decl FDECL with - the visibility VISIBILITY. */ - if (TREE_CODE (fdecl) == TREE_LIST) - { - fdecl = TREE_VALUE (fdecl); - while (fdecl) - { - if (alter_visibility (t, fdecl, visibility) == 0) - break; - fdecl = DECL_CHAIN (fdecl); - } - } - else alter_visibility (t, fdecl, visibility); - CLASSTYPE_ALTERS_VISIBILITIES_P (t) = 1; - continue; - } - - /* If this is of reference type, check if it needs an init. */ - if (TREE_CODE (x) != TYPE_DECL - && TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE - && DECL_INITIAL (x) == 0) - ref_sans_init = 1; - - /* ``A local class cannot have static data members.'' ARM 9.4 */ - if (current_function_decl && TREE_STATIC (x)) - error_with_decl (x, "field `%s' in local class cannot be static"); - - /* When this goes into scope, it will be a non-local reference. */ - DECL_NONLOCAL (x) = 1; - - /* Perform error checking that did not get done in grokdeclarator. */ - if (TREE_CODE (x) == FIELD_DECL || TREE_CODE (x) == VAR_DECL) - { - if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE) - { - error_with_decl (x, "field `%s' invalidly declared function type"); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE) - { - error_with_decl (x, "field `%s' invalidly declared method type"); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE) - { - error_with_decl (x, "field `%s' invalidly declared offset type"); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - } - - if (TREE_CODE (x) == FIELD_DECL) - { - /* If the field has a bogus type, don't bother with it. */ - if (TREE_TYPE (x) != error_mark_node) - { - /* Never let anything with uninheritable virtuals - make it through without complaint. */ - if (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) - && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (x))) - abstract_virtuals_error (x, TREE_TYPE (x)); - - if (TYPE_LANG_SPECIFIC (TREE_TYPE (x))) - { - if (TYPE_HAS_DEFAULT_CONSTRUCTOR (TREE_TYPE (x))) - needs_default_ctor = 1; - if (TYPE_GETS_CONST_INIT_REF (TREE_TYPE (x))) - needs_const_ctor = 1; - else if (TYPE_GETS_INIT_REF (TREE_TYPE (x))) - cant_have_const_ctor = 1; - } - else if (DECL_INITIAL (x) == NULL_TREE - && (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (x)) - || TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)) - cant_have_default_ctor = 1; - } - - /* If any field is const, the structure type is pseudo-const. */ - if (TREE_READONLY (x)) - { - C_TYPE_FIELDS_READONLY (t) = 1; - if (DECL_INITIAL (x) == 0) - const_sans_init = 1; - } - else - { - /* A field that is pseudo-const makes the structure likewise. */ - tree t1 = TREE_TYPE (x); - while (TREE_CODE (t1) == ARRAY_TYPE) - t1 = TREE_TYPE (t1); - if (IS_AGGR_TYPE (t1)) - { - if (C_TYPE_FIELDS_READONLY (t1)) - C_TYPE_FIELDS_READONLY (t) = 1; - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1)) - const_sans_init = 1; - } - } - } - else if (TREE_CODE (x) == VAR_DECL && TREE_CODE (t) == UNION_TYPE) - /* Unions cannot have static members. */ - error_with_decl (x, "field `%s' declared static in union"); - - if (! fields) fields = x; - DECL_FIELD_CONTEXT (x) = t; - /* We could be making an extern "C" function a friend. */ - if (DECL_LANG_SPECIFIC (x)) - DECL_CLASS_CONTEXT (x) = t; - DECL_FIELD_SIZE (x) = 0; - - /* We set DECL_BIT_FIELD tentatively in grokbitfield. - If the type and width are valid, we'll keep it set. - Otherwise, the flag is cleared. */ - if (DECL_BIT_FIELD (x)) - { - DECL_BIT_FIELD (x) = 0; - /* Invalid bit-field size done by grokfield. */ - /* Detect invalid bit-field type. */ - if (DECL_INITIAL (x) - && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) - { - error_with_decl (x, "bit-field `%s' has invalid type"); - DECL_INITIAL (x) = NULL; - } - if (DECL_INITIAL (x) && pedantic - && TREE_TYPE (x) != integer_type_node - && TREE_TYPE (x) != unsigned_type_node - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) - warning_with_decl (x, "bit-field `%s' type invalid in ANSI C++"); - - /* Detect and ignore out of range field width. */ - if (DECL_INITIAL (x)) - { - register int width = TREE_INT_CST_LOW (DECL_INITIAL (x)); - - if (width < 0) - { - DECL_INITIAL (x) = NULL; - warning_with_decl (x, "negative width in bit-field `%s'"); - } - else if (width == 0 && DECL_NAME (x) != 0) - { - error_with_decl (x, "zero width for bit-field `%s'"); - DECL_INITIAL (x) = NULL; - } - else if ((unsigned)width > TYPE_PRECISION (TREE_TYPE (x))) - { - DECL_INITIAL (x) = NULL; - warning_with_decl (x, "width of `%s' exceeds its type"); - } - } - - /* Process valid field width. */ - if (DECL_INITIAL (x)) - { - register int width = TREE_INT_CST_LOW (DECL_INITIAL (x)); - - if (width == 0) - { -#ifdef EMPTY_FIELD_BOUNDARY - /* field size 0 => mark following field as "aligned" */ - if (TREE_CHAIN (x)) - DECL_ALIGN (TREE_CHAIN (x)) - = MAX (DECL_ALIGN (TREE_CHAIN (x)), EMPTY_FIELD_BOUNDARY); - /* field of size 0 at the end => round up the size. */ - else - round_up_size = EMPTY_FIELD_BOUNDARY; -#endif -#ifdef PCC_BITFIELD_TYPE_MATTERS - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); -#endif - } - else - { - DECL_INITIAL (x) = NULL_TREE; - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; - /* Traditionally a bit field is unsigned - even if declared signed. */ - if (flag_traditional - && TREE_CODE (TREE_TYPE (x)) == INTEGER_TYPE) - TREE_TYPE (x) = unsigned_type_node; - } - } - else - /* Non-bit-fields are aligned for their type. */ - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x))); - } - else if (TREE_CODE (x) == FIELD_DECL) - { - tree type = TREE_TYPE (x); - if (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - if (code == UNION_TYPE && IS_AGGR_TYPE (type)) - { - if (TYPE_NEEDS_CONSTRUCTING (type) - || TYPE_NEEDS_DESTRUCTOR (type)) - error_with_decl (x, "member `%s' with constructor or destructor not allowed in union"); - TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (type); - TYPE_GETS_INIT_REF (t) |= TYPE_GETS_INIT_REF (type); - } - else if (code == RECORD_TYPE) - { - /* Array of record type doesn't matter for this bit. */ - TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type); - if (IS_AGGR_TYPE (type)) - { - needs_ctor |= TYPE_NEEDS_CONSTRUCTOR (type); - needs_dtor |= TYPE_NEEDS_DESTRUCTOR (type); - members_need_dtors |= TYPE_NEEDS_DESTRUCTOR (type); - TYPE_GETS_CONST_INIT_REF (t) |= TYPE_GETS_CONST_INIT_REF (type); - TYPE_GETS_ASSIGNMENT (t) |= TYPE_GETS_ASSIGNMENT (type); - TYPE_GETS_INIT_REF (t) |= TYPE_GETS_INIT_REF (type); - } - } - if (DECL_INITIAL (x) != NULL_TREE) - { - /* `build_class_init_list' does not recognize non-FIELD_DECLs. */ - if (code == UNION_TYPE && any_default_members != 0) - error ("multiple fields in union initialized"); - any_default_members = 1; - } - } - last_x = x; - } - list_of_fieldlists = TREE_CHAIN (list_of_fieldlists); - /* link the tail while we have it! */ - if (last_x) - { - TREE_CHAIN (last_x) = NULL_TREE; - - if (list_of_fieldlists - && TREE_VALUE (list_of_fieldlists) - && TREE_CODE (TREE_VALUE (list_of_fieldlists)) != FUNCTION_DECL) - TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists); - } - } - - if (tail) TREE_CHAIN (tail) = NULL_TREE; - - /* If this type has any constant members which did not come - with their own initialization, mark that fact here. It is - not an error here, since such types can be saved either by their - constructors, or by fortuitous initialization. */ - CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init; - CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init; - CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals; - - if (members_need_dtors && !TYPE_HAS_DESTRUCTOR (t)) - { - /* Here we must cons up a destructor on the fly. */ - tree dtor = cons_up_default_function (t, name, - needs_virtual_dtor != 0); - - /* If we couldn't make it work, then pretend we didn't need it. */ - if (dtor == void_type_node) - TYPE_NEEDS_DESTRUCTOR (t) = 0; - else - { - if (! fn_fields) fn_fields = dtor; - else TREE_CHAIN (tail) = dtor; - tail = dtor; - - if (DECL_VINDEX (dtor) == NULL_TREE - && ! CLASSTYPE_DECLARED_EXCEPTION (t) - && (needs_virtual_dtor - || pending_virtuals != NULL_TREE - || pending_hard_virtuals != NULL_TREE)) - DECL_VINDEX (dtor) = error_mark_node; - if (DECL_VINDEX (dtor)) - pending_virtuals = add_virtual_function (pending_virtuals, - &has_virtual, dtor, NULL_TREE); - nonprivate_method = 1; - TYPE_HAS_DESTRUCTOR (t) = 1; - } - } - - if (debug_default_functions) - { - if ((TYPE_NEEDS_CONSTRUCTOR (t) || TYPE_HAS_CONSTRUCTOR (t) || needs_ctor) - && ! TYPE_HAS_INIT_REF (t)) - { - tree default_fn = cons_up_default_function (t, name, 4); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - TYPE_HAS_INIT_REF (t) = 1; - default_fn = cons_up_default_function (t, name, 3); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - nonprivate_method = 1; - } - - if (! TYPE_HAS_DEFAULT_CONSTRUCTOR (t) - && needs_default_ctor && ! cant_have_default_ctor) - { - tree default_fn = cons_up_default_function (t, name, 2); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1; - nonprivate_method = 1; - } - } - - if (fn_fields) - { - method_vec = finish_struct_methods (t, fn_fields, nonprivate_method); - - if (TYPE_HAS_CONSTRUCTOR (t) - && ! CLASSTYPE_DECLARED_EXCEPTION (t) - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE) - { - int nonprivate_ctor = 0; - tree ctor; - - for (ctor = TREE_VEC_ELT (method_vec, 0); - ctor; - ctor = DECL_CHAIN (ctor)) - if (! TREE_PRIVATE (ctor)) - { - nonprivate_ctor = 1; - break; - } - if (nonprivate_ctor == 0) - warning ("class `%s' only defines private constructors and has no friends", - err_name); - } - } - else - { - method_vec = 0; - - /* Just in case these got accidentally - filled in by syntax errors. */ - TYPE_HAS_CONSTRUCTOR (t) = 0; - TYPE_HAS_DESTRUCTOR (t) = 0; - } - - if (vfield == NULL_TREE && has_virtual) - { - /* We build this decl with ptr_type_node, and - change the type when we know what it should be. */ - vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), ptr_type_node); - /* If you change any of the below, take a look at all the - other VFIELD_BASEs and VTABLE_BASEs in the code, and change - them too. */ - DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE); - CLASSTYPE_VFIELD (t) = vfield; - DECL_VIRTUAL_P (vfield) = 1; - DECL_FIELD_CONTEXT (vfield) = t; - DECL_CLASS_CONTEXT (vfield) = t; - DECL_FCONTEXT (vfield) = t; - DECL_FIELD_SIZE (vfield) = 0; - DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node); - if (CLASSTYPE_DOSSIER (t)) - { - /* vfield is always first entry in structure. */ - TREE_CHAIN (vfield) = fields; - fields = vfield; - } - else if (last_x) - { - my_friendly_assert (TREE_CHAIN (last_x) == 0, 175); - TREE_CHAIN (last_x) = vfield; - last_x = vfield; - } - else fields = vfield; - vfields = chainon (vfields, CLASSTYPE_AS_LIST (t)); - } - - /* Now DECL_INITIAL is null on all members except for zero-width bit-fields. - And they have already done their work. - - C++: maybe we will support default field initialization some day... */ - - /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fields && DECL_BIT_FIELD (fields) - && DECL_INITIAL (fields)) - fields = TREE_CHAIN (fields); - /* Delete all such fields from the rest of the fields. */ - for (x = fields; x;) - { - if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x)) - && DECL_INITIAL (TREE_CHAIN (x))) - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - else x = TREE_CHAIN (x); - } - /* Delete all duplicate fields from the fields */ - delete_duplicate_fields (fields); - - /* Now we have the final fieldlist for the data fields. Record it, - then lay out the structure or union (including the fields). */ - - TYPE_FIELDS (t) = fields; - - /* If there's a :0 field at the end, round the size to the - EMPTY_FIELD_BOUNDARY. */ - TYPE_ALIGN (t) = round_up_size; - - /* Pass layout information about base classes to layout_type, if any. */ - - if (n_baseclasses) - { - tree pseudo_basetype = TREE_TYPE (base_layout_decl); - - TREE_CHAIN (base_layout_decl) = TYPE_FIELDS (t); - TYPE_FIELDS (t) = base_layout_decl; - - TYPE_SIZE (pseudo_basetype) = CLASSTYPE_SIZE (t); - TYPE_MODE (pseudo_basetype) = TYPE_MODE (t); - TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t); - DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype); - } - - layout_type (t); - - if (n_baseclasses) - TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t)); - - /* C++: do not let empty structures exist. */ - if (integer_zerop (TYPE_SIZE (t))) - TYPE_SIZE (t) = TYPE_SIZE (char_type_node); - - /* Set the TYPE_DECL for this type to contain the right - value for DECL_OFFSET, so that we can use it as part - of a COMPONENT_REF for multiple inheritance. */ - - if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL) - layout_decl (TYPE_NAME (t), 0); - - /* Now fix up any virtual base class types that we - left lying around. We must get these done - before we try to lay out the virtual function table. */ - doing_hard_virtuals = 1; - pending_hard_virtuals = nreverse (pending_hard_virtuals); - - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - { - tree vbases; - - max_has_virtual = layout_vbasetypes (t, max_has_virtual); - vbases = CLASSTYPE_VBASECLASSES (t); - CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases); - - /* This loop makes all the entries in the virtual function tables - of interest contain the "latest" version of the functions - we have defined. */ - - while (vbases) - { - tree virtuals = BINFO_VIRTUALS (vbases); - - if (virtuals) - { - /* Get past the `null' vtable entry... */ - virtuals = TREE_CHAIN (virtuals); - /* and the `dossier' vtable entry if we're doing dossiers. */ - if (flag_dossier) - virtuals = TREE_CHAIN (virtuals); - } - - while (virtuals != NULL_TREE) - { - tree pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)); - tree base_fndecl = TREE_OPERAND (pfn, 0); - tree decl = get_first_matching_virtual (TYPE_BINFO (t), base_fndecl, - DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))); - tree context = DECL_CLASS_CONTEXT (decl); - if (decl != base_fndecl && context != t) - { - tree base_context = DECL_CLASS_CONTEXT (base_fndecl); - tree binfo = NULL_TREE, these_virtuals; -#if 0 - unsigned HOST_WIDE_INT i - = (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)) - & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1)); -#endif - - if (TYPE_USES_VIRTUAL_BASECLASSES (context)) - binfo = virtual_member (base_context, - CLASSTYPE_VBASECLASSES (context)); - if (binfo == NULL_TREE) - binfo = binfo_value (base_context, context); - if (binfo != NULL_TREE) - { -#if 1 - pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (get_vtable_entry (BINFO_VIRTUALS (binfo), base_fndecl))); -#else - these_virtuals = BINFO_VIRTUALS (binfo); - - while (i-- > 0) - these_virtuals = TREE_CHAIN (these_virtuals); - pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (these_virtuals)); -#endif - modify_vtable_entries (t, decl, base_fndecl, pfn); - } - } - virtuals = TREE_CHAIN (virtuals); - } - /* Update dossier info with offsets for virtual baseclasses. */ - if (flag_dossier && ! BINFO_NEW_VTABLE_MARKED (vbases)) - prepare_fresh_vtable (vbases, vbases, t); - - vbases = TREE_CHAIN (vbases); - } - } - - while (pending_hard_virtuals) - { - /* Need an entry in some other virtual function table. */ - if (TREE_TYPE (pending_hard_virtuals)) - { - /* This is how we modify entries when a vfn's index changes - between derived and base type. */ - modify_vtable_entries (t, TREE_PURPOSE (pending_hard_virtuals), - TREE_TYPE (pending_hard_virtuals), - TREE_VALUE (pending_hard_virtuals)); - } - else - { - /* This is how we modify entries when a vfn comes from - a virtual baseclass. */ - tree base_fndecls = DECL_VINDEX (TREE_PURPOSE (pending_hard_virtuals)); - my_friendly_assert (base_fndecls != error_mark_node, 176); - while (base_fndecls) - { - modify_vtable_entries (t, TREE_PURPOSE (pending_hard_virtuals), - TREE_VALUE (base_fndecls), - TREE_VALUE (pending_hard_virtuals)); - base_fndecls = TREE_CHAIN (base_fndecls); - } - } - pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals); - } - doing_hard_virtuals = 0; - - /* Under our model of GC, every C++ class gets its own virtual - function table, at least virtually. */ - if (pending_virtuals || CLASSTYPE_DOSSIER (t)) - { - pending_virtuals = nreverse (pending_virtuals); - /* We must enter these virtuals into the table. */ - if (first_vfn_base_index < 0) - { - if (flag_dossier) - pending_virtuals = tree_cons (NULL_TREE, - build_vtable_entry (integer_zero_node, - build_t_desc (t, 0)), - pending_virtuals); - pending_virtuals = tree_cons (NULL_TREE, the_null_vtable_entry, - pending_virtuals); - build_vtable (NULL_TREE, t); - } - else - { - /* Here we know enough to change the type of our virtual - function table, but we will wait until later this function. */ - - if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) - build_vtable (binfo_value (TYPE_BINFO_BASETYPE (t, first_vfn_base_index), t), t); - - /* Update the dossier pointer for this class. */ - if (flag_dossier) - TREE_VALUE (TREE_CHAIN (TYPE_BINFO_VIRTUALS (t))) - = build_vtable_entry (integer_zero_node, build_t_desc (t, 0)); - } - - /* If this type has basetypes with constructors, then those - constructors might clobber the virtual function table. But - they don't if the derived class shares the exact vtable of the base - class. */ - - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; - } - else if (first_vfn_base_index >= 0) - { - tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); - - /* This class contributes nothing new to the virtual function - table. However, it may have declared functions which - went into the virtual function table "inherited" from the - base class. If so, we grab a copy of those updated functions, - and pretend they are ours. */ - - /* See if we should steal the virtual info from base class. */ - if (TYPE_BINFO_VTABLE (t) == NULL_TREE) - TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo); - if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE) - TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo); - if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo)) - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; - } - - if (has_virtual > max_has_virtual) - max_has_virtual = has_virtual; - if (max_has_virtual || first_vfn_base_index >= 0) - { -#ifdef VTABLE_USES_MASK - if (max_has_virtual >= VINDEX_MAX) - { - error ("too many virtual functions for class `%s' (VINDEX_MAX < %d)", - err_name, has_virtual); - } -#endif - TYPE_VIRTUAL_P (t) = 1; - CLASSTYPE_VSIZE (t) = has_virtual; - if (first_vfn_base_index >= 0) - { - if (pending_virtuals) - TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), - pending_virtuals); - } - else if (has_virtual) - { - TYPE_BINFO_VIRTUALS (t) = pending_virtuals; - if (write_virtuals >= 0) - DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1; - } - } - - /* Now lay out the virtual function table. */ - if (has_virtual) - { - tree atype, itype; - - if (TREE_TYPE (vfield) == ptr_type_node) - { - /* We must create a pointer to this table because - the one inherited from base class does not exist. - We will fill in the type when we know what it - should really be. Use `size_int' so values are memoized - in common cases. */ - itype = build_index_type (size_int (has_virtual)); - atype = build_array_type (vtable_entry_type, itype); - layout_type (atype); - TREE_TYPE (vfield) = build_pointer_type (atype); - } - else - { - atype = TREE_TYPE (TREE_TYPE (vfield)); - - if (has_virtual != TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))) - { - /* We must extend (or create) the boundaries on this array, - because we picked up virtual functions from multiple - base classes. */ - itype = build_index_type (size_int (has_virtual)); - atype = build_array_type (vtable_entry_type, itype); - layout_type (atype); - vfield = copy_node (vfield); - TREE_TYPE (vfield) = build_pointer_type (atype); - } - } - - CLASSTYPE_VFIELD (t) = vfield; - if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) - { - TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; - layout_decl (TYPE_BINFO_VTABLE (t), 0); - DECL_ALIGN (TYPE_BINFO_VTABLE (t)) - = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (TYPE_BINFO_VTABLE (t))); - } - } - else if (first_vfn_base_index >= 0) - CLASSTYPE_VFIELD (t) = vfield; - CLASSTYPE_VFIELDS (t) = vfields; - - /* Set all appropriate CLASSTYPE_... flags for this type - and its variants. */ - TYPE_NEEDS_CONSTRUCTOR (t) |= needs_ctor || TYPE_HAS_CONSTRUCTOR (t); - TYPE_NEEDS_CONSTRUCTING (t) - |= ((TYPE_NEEDS_CONSTRUCTOR (t)|TYPE_USES_VIRTUAL_BASECLASSES (t)) - || has_virtual || any_default_members - || first_vfn_base_index >= 0); - TYPE_NEEDS_DESTRUCTOR (t) |= needs_dtor || TYPE_HAS_DESTRUCTOR (t); - finish_struct_bits (t, max_has_virtual); - - /* Promote each bit-field's type to int if it is narrower than that. - There's more: complete the rtl for any static member objects which - is of the same type we're working on. - */ - for (x = fields; x; x = TREE_CHAIN (x)) - { - if (DECL_BIT_FIELD (x) - && C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x))) - TREE_TYPE (x) = TREE_UNSIGNED (TREE_TYPE (x)) - ? unsigned_type_node : integer_type_node; - if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) - && TREE_TYPE (x) == t) - { - DECL_MODE (x) = TYPE_MODE (t); - make_decl_rtl (x, NULL, 0); - } - } - - /* Now add the tags, if any, to the list of TYPE_DECLs - defined for this type. */ - if (CLASSTYPE_TAGS (t)) - { - x = CLASSTYPE_TAGS (t); - last_x = tree_last (TYPE_FIELDS (t)); - while (x) - { - tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x)); - DECL_CONTEXT (tag) = t; - DECL_CLASS_CONTEXT (tag) = t; - x = TREE_CHAIN (x); - last_x = chainon (last_x, tag); - } - if (TYPE_FIELDS (t) == 0) - TYPE_FIELDS (t) = last_x; - CLASSTYPE_LOCAL_TYPEDECLS (t) = 1; - } - - if (TYPE_HAS_CONSTRUCTOR (t)) - { - tree vfields = CLASSTYPE_VFIELDS (t); - - while (vfields) - { - /* Mark the fact that constructor for T - could affect anybody inheriting from T - who wants to initialize vtables for VFIELDS's type. */ - if (VF_DERIVED_VALUE (vfields)) - TREE_ADDRESSABLE (vfields) = 1; - vfields = TREE_CHAIN (vfields); - } - if (any_default_members != 0) - build_class_init_list (t); - } - else if (TYPE_NEEDS_CONSTRUCTING (t)) - build_class_init_list (t); - - if (current_lang_name == lang_name_cplusplus) - { - if (! CLASSTYPE_DECLARED_EXCEPTION (t)) - embrace_waiting_friends (t); - - /* Write out inline function definitions. */ - do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); - CLASSTYPE_INLINE_FRIENDS (t) = 0; - } - - if (CLASSTYPE_VSIZE (t) != 0) - { -#if 0 - if (!TYPE_USES_COMPLEX_INHERITANCE (t)) - TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield); -#endif - - if ((flag_this_is_variable & 1) == 0) - { - tree vtbl_ptr = build_decl (VAR_DECL, get_identifier (VPTR_NAME), - TREE_TYPE (vfield)); - DECL_REGISTER (vtbl_ptr) = 1; - CLASSTYPE_VTBL_PTR (t) = vtbl_ptr; - } - if (DECL_FIELD_CONTEXT (vfield) != t) - { - tree binfo = binfo_value (DECL_FIELD_CONTEXT (vfield), t); - tree offset = BINFO_OFFSET (binfo); - - vfield = copy_node (vfield); - copy_lang_decl (vfield); - - if (! integer_zerop (offset)) - offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); - DECL_FIELD_CONTEXT (vfield) = t; - DECL_CLASS_CONTEXT (vfield) = t; - DECL_FIELD_BITPOS (vfield) - = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); - CLASSTYPE_VFIELD (t) = vfield; - } - if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) - && DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE) - warning ("class `%s' has virtual functions but non-virtual destructor", - err_name); - } - - /* Make the rtl for any new vtables we have created, and unmark - the base types we marked. */ - unmark_finished_struct (t); - TYPE_BEING_DEFINED (t) = 0; - - if (flag_dossier && CLASSTYPE_VTABLE_NEEDS_WRITING (t)) - { - tree variants; - tree tdecl; - - /* Now instantiate its type descriptors. */ - tdecl = TREE_OPERAND (build_t_desc (t, 1), 0); - variants = TYPE_POINTER_TO (t); - build_type_variant (variants, 1, 0); - while (variants) - { - build_t_desc (variants, 1); - variants = TYPE_NEXT_VARIANT (variants); - } - variants = build_reference_type (t); - build_type_variant (variants, 1, 0); - while (variants) - { - build_t_desc (variants, 1); - variants = TYPE_NEXT_VARIANT (variants); - } -#if 0 - DECL_VPARENT (tdecl) = t; -#endif - DECL_CONTEXT (tdecl) = t; - } - /* Still need to instantiate this C struct's type descriptor. */ - else if (flag_dossier && ! CLASSTYPE_DOSSIER (t)) - build_t_desc (t, 1); - - if (TYPE_NAME (t) && TYPE_IDENTIFIER (t)) - undo_template_name_overload (TYPE_IDENTIFIER (t), 1); - if (current_class_type) - popclass (0); - else - error ("trying to finish struct, but kicked out due to previous parse errors."); - - hack_incomplete_structures (t); - - resume_momentary (old); - - if (flag_cadillac) - cadillac_finish_struct (t); - -#if 0 - /* This has to be done after we have sorted out what to do with - the enclosing type. */ - /* Be smarter about nested classes here. If a type is nested, - only output it if we would output the enclosing type. */ - if (DECL_CONTEXT (TYPE_NAME (t)) - && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (TYPE_NAME (t)))) == 't') - DECL_IGNORED_P (TYPE_NAME (t)) = TREE_ASM_WRITTEN (TYPE_NAME (t)); -#endif - - /* If the type has methods, we want to think about cutting down - the amount of symbol table stuff we output. The value stored in - the TYPE_DECL's DECL_IGNORED_P slot is a first approximation. - For example, if a member function is seen and we decide to - write out that member function, then we can change the value - of the DECL_IGNORED_P slot, and the type will be output when - that member function's debug info is written out. */ - if (CLASSTYPE_METHOD_VEC (t)) - { - extern tree pending_vtables; - - /* Don't output full info about any type - which does not have its implementation defined here. */ - if (TYPE_VIRTUAL_P (t) && write_virtuals == 2) - DECL_IGNORED_P (TYPE_NAME (t)) - = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0); - else if (CLASSTYPE_INTERFACE_ONLY (t)) - DECL_IGNORED_P (TYPE_NAME (t)) = 1; - else if (CLASSTYPE_INTERFACE_UNKNOWN (t)) - /* Only a first approximation! */ - DECL_IGNORED_P (TYPE_NAME (t)) = 1; - } - else if (CLASSTYPE_INTERFACE_ONLY (t)) - DECL_IGNORED_P (TYPE_NAME (t)) = 1; - - /* Finish debugging output for this type. */ - rest_of_type_compilation (t, global_bindings_p ()); - - return t; -} - -/* Return non-zero if the effective type of INSTANCE is static. - Used to determine whether the virtual function table is needed - or not. - - *NONNULL is set iff INSTANCE can be known to be nonnull, regardless - of our knowledge of its type. */ -int -resolves_to_fixed_type_p (instance, nonnull) - tree instance; - int *nonnull; -{ - switch (TREE_CODE (instance)) - { - case INDIRECT_REF: - /* Check that we are not going through a cast of some sort. */ - if (TREE_TYPE (instance) - == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0)))) - instance = TREE_OPERAND (instance, 0); - /* fall through... */ - case CALL_EXPR: - /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) - { - if (nonnull) - *nonnull = 1; - return 1; - } - return 0; - - case SAVE_EXPR: - /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) - { - if (nonnull) - *nonnull = 1; - return 1; - } - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - - case RTL_EXPR: - /* This is a call to `new', hence it's never zero. */ - if (TREE_CALLS_NEW (instance)) - { - if (nonnull) - *nonnull = 1; - return 1; - } - return 0; - - case PLUS_EXPR: - case MINUS_EXPR: - if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST) - /* Propagate nonnull. */ - resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR) - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - return 0; - - case NOP_EXPR: - case CONVERT_EXPR: - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - - case ADDR_EXPR: - if (nonnull) - *nonnull = 1; - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - - case COMPONENT_REF: - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull); - - case WITH_CLEANUP_EXPR: - if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR) - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - /* fall through... */ - case VAR_DECL: - case FIELD_DECL: - if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE - && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance)))) - { - if (nonnull) - *nonnull = 1; - return 1; - } - /* fall through... */ - case TARGET_EXPR: - case PARM_DECL: - if (IS_AGGR_TYPE (TREE_TYPE (instance))) - { - if (nonnull) - *nonnull = 1; - return 1; - } - else if (nonnull) - { - if (instance == current_class_decl - && flag_this_is_variable <= 0) - { - /* Some people still use `this = 0' inside destructors. */ - *nonnull = ! DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl)); - /* In a constructor, we know our type. */ - if (flag_this_is_variable < 0) - return 1; - } - else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) - /* Reference variables should be references to objects. */ - *nonnull = 1; - } - return 0; - - default: - return 0; - } -} - -void -init_class_processing () -{ - current_class_depth = 0; - current_class_stacksize = 10; - current_class_base = (tree *)xmalloc(current_class_stacksize * sizeof (tree)); - current_class_stack = current_class_base; - - current_lang_stacksize = 10; - current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree)); - current_lang_stack = current_lang_base; - - delta_name = get_identifier (VTABLE_DELTA_NAME); - pfn_name = get_identifier (VTABLE_PFN_NAME); - - /* Keep these values lying around. */ - the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node); - base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node); - TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE); - - gcc_obstack_init (&class_obstack); -} - -/* Set current scope to NAME. CODE tells us if this is a - STRUCT, UNION, or ENUM environment. - - NAME may end up being NULL_TREE if this is an anonymous or - late-bound struct (as in "struct { ... } foo;") */ - -/* Here's a subroutine we need because C lacks lambdas. */ -static void -unuse_fields (type) - tree type; -{ - tree fields; - - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - { - if (TREE_CODE (fields) != FIELD_DECL) - continue; - - TREE_USED (fields) = 0; - if (DECL_NAME (fields) == NULL_TREE - && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) - unuse_fields (TREE_TYPE (fields)); - } -} - -/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to - appropriate values, found by looking up the type definition of - NAME (as a CODE). - - If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names - which can be seen locally to the class. They are shadowed by - any subsequent local declaration (including parameter names). - - If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names - which have static meaning (i.e., static members, static - member functions, enum declarations, etc). - - If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names - which can be seen locally to the class (as in 1), but - know that we are doing this for declaration purposes - (i.e. friend foo::bar (int)). - - So that we may avoid calls to lookup_name, we cache the _TYPE - nodes of local TYPE_DECLs in the TREE_TYPE field of the name. - - For multiple inheritance, we perform a two-pass depth-first search - of the type lattice. The first pass performs a pre-order search, - marking types after the type has had its fields installed in - the appropriate IDENTIFIER_CLASS_VALUE slot. The second pass merely - unmarks the marked types. If a field or member function name - appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of - that name becomes `error_mark_node'. */ - -void -pushclass (type, modify) - tree type; - int modify; -{ -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushclass"); - debug_bindings_indentation += 4; -#endif - - push_memoized_context (type, modify); - - current_class_depth++; - *current_class_stack++ = current_class_name; - *current_class_stack++ = current_class_type; - if (current_class_stack >= current_class_base + current_class_stacksize) - { - current_class_base = - (tree *)xrealloc (current_class_base, - sizeof (tree) * (current_class_stacksize + 10)); - current_class_stack = current_class_base + current_class_stacksize; - current_class_stacksize += 10; - } - - current_class_name = TYPE_NAME (type); - if (TREE_CODE (current_class_name) == TYPE_DECL) - current_class_name = DECL_NAME (current_class_name); - current_class_type = type; - - if (prev_class_type != NULL_TREE - && (type != prev_class_type - || TYPE_SIZE (prev_class_type) == NULL_TREE - /* ??? Is this necessary any more? */ - || IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (prev_class_type))) - && (current_class_depth == 1 || modify == 3)) - { - /* Forcibly remove any old class remnants. */ - popclass (-1); - prev_class_type = 0; - } - - pushlevel_class (); - - if (modify) - { - tree tags; - tree this_fndecl = current_function_decl; - - if (current_function_decl - && DECL_CONTEXT (current_function_decl) - && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL) - current_function_decl = DECL_CONTEXT (current_function_decl); - else - current_function_decl = NULL_TREE; - - if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) - { - declare_uninstantiated_type_level (); - overload_template_name (current_class_name, 0); - } - else if (type != prev_class_type) - { - build_mi_matrix (type); - push_class_decls (type); - free_mi_matrix (); - prev_class_type = type; - } - else - unuse_fields (type); - - for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1; - if (! TREE_PURPOSE (tags)) - continue; - pushtag (TREE_PURPOSE (tags), TREE_VALUE (tags)); - if (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) == NULL_TREE - && TREE_CODE (TYPE_NAME (TREE_VALUE (tags))) == TYPE_DECL) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) - = TYPE_NAME (TREE_VALUE (tags)); - } - - current_function_decl = this_fndecl; - } - - if (flag_cadillac) - cadillac_push_class (type); - -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif -} - -/* Get out of the current class scope. If we were in a class scope - previously, that is the one popped to. The flag MODIFY tells - whether the current scope declarations needs to be modified - as a result of popping to the previous scope. */ -void -popclass (modify) - int modify; -{ -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "popclass"); - debug_bindings_indentation += 4; -#endif - - if (flag_cadillac) - cadillac_pop_class (); - - if (modify < 0) - { - /* Back this old class out completely. */ - tree tags = CLASSTYPE_TAGS (prev_class_type); - - pop_class_decls (prev_class_type); - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = NULL_TREE; - tags = TREE_CHAIN (tags); - } - goto ret; - } - - if (modify) - { - /* Just remove from this class what didn't make - it into IDENTIFIER_CLASS_VALUE. */ - tree tags = CLASSTYPE_TAGS (current_class_type); - - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - if (TREE_PURPOSE (tags)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (tags)) = NULL_TREE; - tags = TREE_CHAIN (tags); - } - } - if (TREE_CODE (current_class_type) == UNINSTANTIATED_P_TYPE) - undo_template_name_overload (current_class_name, 0); - poplevel_class (); - - current_class_depth--; - current_class_type = *--current_class_stack; - current_class_name = *--current_class_stack; - - if (current_class_type) - { - if (CLASSTYPE_VTBL_PTR (current_class_type)) - { - current_vtable_decl = lookup_name (DECL_NAME (CLASSTYPE_VTBL_PTR (current_class_type)), 0); - if (current_vtable_decl) - current_vtable_decl = build_indirect_ref (current_vtable_decl, - NULL); - } - current_class_decl = lookup_name (get_identifier (THIS_NAME), 0); - if (current_class_decl) - { - if (TREE_CODE (TREE_TYPE (current_class_decl)) == POINTER_TYPE) - { - tree temp; - /* Can't call build_indirect_ref here, because it has special - logic to return C_C_D given this argument. */ - C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl); - temp = TREE_TYPE (TREE_TYPE (current_class_decl)); - TREE_READONLY (C_C_D) = TYPE_READONLY (temp); - TREE_SIDE_EFFECTS (C_C_D) = TYPE_VOLATILE (temp); - TREE_THIS_VOLATILE (C_C_D) = TYPE_VOLATILE (temp); - } - else - C_C_D = current_class_decl; - } - else C_C_D = NULL_TREE; - } - else - { - current_class_decl = NULL_TREE; - current_vtable_decl = NULL_TREE; - C_C_D = NULL_TREE; - } - - pop_memoized_context (modify); - - ret: - ; -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif -} - -/* Set global variables CURRENT_LANG_NAME to appropriate value - so that behavior of name-mangling machinery is correct. */ - -void -push_lang_context (name) - tree name; -{ - *current_lang_stack++ = current_lang_name; - if (current_lang_stack >= current_lang_base + current_lang_stacksize) - { - current_lang_base = - (tree *)xrealloc (current_lang_base, - sizeof (tree) * (current_lang_stacksize + 10)); - current_lang_stack = current_lang_base + current_lang_stacksize; - current_lang_stacksize += 10; - } - - if (name == lang_name_cplusplus) - { - strict_prototype = strict_prototypes_lang_cplusplus; - current_lang_name = name; - } - else if (name == lang_name_c) - { - strict_prototype = strict_prototypes_lang_c; - current_lang_name = name; - } - else - error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name)); - - if (flag_cadillac) - cadillac_push_lang (name); -} - -/* Get out of the current language scope. */ -void -pop_lang_context () -{ - if (flag_cadillac) - cadillac_pop_lang (); - - current_lang_name = *--current_lang_stack; - if (current_lang_name == lang_name_cplusplus) - strict_prototype = strict_prototypes_lang_cplusplus; - else if (current_lang_name == lang_name_c) - strict_prototype = strict_prototypes_lang_c; -} - -int -root_lang_context_p () -{ - return current_lang_stack == current_lang_base; -} - -/* Type instantiation routines. */ - -/* This function will instantiate the type of the expression given - in RHS to match the type of LHSTYPE. If LHSTYPE is NULL_TREE, - or other errors exist, the TREE_TYPE of RHS will be ERROR_MARK_NODE. - - This function is used in build_modify_expr, convert_arguments, - build_c_cast, and compute_conversion_costs. */ -tree -instantiate_type (lhstype, rhs, complain) - tree lhstype, rhs; - int complain; -{ - if (TREE_CODE (lhstype) == UNKNOWN_TYPE) - { - if (complain) - error ("not enough type information"); - return error_mark_node; - } - - if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs))) - return rhs; - - /* This should really only be used when attempting to distinguish - what sort of a pointer to function we have. For now, any - arithmetic operation which is not supported on pointers - is rejected as an error. */ - - switch (TREE_CODE (rhs)) - { - case TYPE_EXPR: - case CONVERT_EXPR: - case SAVE_EXPR: - case CONSTRUCTOR: - case BUFFER_REF: - my_friendly_abort (177); - return error_mark_node; - - case INDIRECT_REF: - case ARRAY_REF: - TREE_TYPE (rhs) = lhstype; - lhstype = build_pointer_type (lhstype); - TREE_OPERAND (rhs, 0) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (TREE_OPERAND (rhs, 0) == error_mark_node) - return error_mark_node; - - return rhs; - - case NOP_EXPR: - rhs = copy_node (TREE_OPERAND (rhs, 0)); - TREE_TYPE (rhs) = unknown_type_node; - return instantiate_type (lhstype, rhs, complain); - - case COMPONENT_REF: - { - tree field = TREE_OPERAND (rhs, 1); - if (TREE_CODE (field) == TREE_LIST) - { - tree function = instantiate_type (lhstype, field, complain); - if (function == error_mark_node) - return error_mark_node; - my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185); - if (DECL_VINDEX (function)) - { - tree base = TREE_OPERAND (rhs, 0); - tree base_ptr = build_unary_op (ADDR_EXPR, base, 0); - if (base_ptr == error_mark_node) - return error_mark_node; - base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr); - if (base_ptr == error_mark_node) - return error_mark_node; - return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function)); - } - return function; - } - - my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178); - my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE), - 179); - - TREE_TYPE (rhs) = lhstype; - /* First look for an exact match */ - - while (field && TREE_TYPE (field) != lhstype) - field = TREE_CHAIN (field); - if (field) - { - TREE_OPERAND (rhs, 1) = field; - return rhs; - } - - /* No exact match found, look for a compatible function. */ - field = TREE_OPERAND (rhs, 1); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = TREE_CHAIN (field); - if (field) - { - TREE_OPERAND (rhs, 1) = field; - field = TREE_CHAIN (field); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = TREE_CHAIN (field); - if (field) - { - if (complain) - error ("ambiguous overload for COMPONENT_REF requested"); - return error_mark_node; - } - } - else - { - if (complain) - error ("no appropriate overload exists for COMPONENT_REF"); - return error_mark_node; - } - return rhs; - } - - case TREE_LIST: - { - tree elem, baselink, name; - int globals = overloaded_globals_p (rhs); - - /* If there's only one function we know about, return that. */ - if (globals > 0 && TREE_CHAIN (rhs) == NULL_TREE) - return TREE_VALUE (rhs); - - /* First look for an exact match. Search either overloaded - functions or member functions. May have to undo what - `default_conversion' might do to lhstype. */ - - if (TREE_CODE (lhstype) == POINTER_TYPE) - if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) - lhstype = TREE_TYPE (lhstype); - else - { - if (complain) - error ("invalid type combination for overload"); - return error_mark_node; - } - - if (TREE_CODE (lhstype) != FUNCTION_TYPE && globals > 0) - { - if (complain) - error ("cannot resolve overloaded function `%s' based on non-function type", - IDENTIFIER_POINTER (TREE_PURPOSE (rhs))); - return error_mark_node; - } - - if (globals > 0) - { - my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL, - 180); - elem = rhs; - while (elem) - if (TREE_TYPE (TREE_VALUE (elem)) != lhstype) - elem = TREE_CHAIN (elem); - else - return TREE_VALUE (elem); - /* No exact match found, look for a compatible function. */ - elem = rhs; - while (elem && ! comp_target_types (lhstype, TREE_TYPE (TREE_VALUE (elem)), 1)) - elem = TREE_CHAIN (elem); - if (elem) - { - tree save_elem = TREE_VALUE (elem); - elem = TREE_CHAIN (elem); - while (elem && ! comp_target_types (lhstype, TREE_TYPE (TREE_VALUE (elem)), 0)) - elem = TREE_CHAIN (elem); - if (elem) - { - if (complain) - error ("ambiguous overload for overloaded function requested"); - return error_mark_node; - } - return save_elem; - } - if (complain) - { - if (TREE_CHAIN (rhs)) - error ("no appropriate overload for overloaded function `%s' exists", - IDENTIFIER_POINTER (TREE_PURPOSE (rhs))); - else - error ("function `%s' has inappropriate type signature", - IDENTIFIER_POINTER (TREE_PURPOSE (rhs))); - } - return error_mark_node; - } - - if (TREE_NONLOCAL_FLAG (rhs)) - { - /* Got to get it as a baselink. */ - rhs = lookup_fnfields (TYPE_BINFO (current_class_type), - TREE_PURPOSE (rhs), 0); - } - else - { - my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181); - if (TREE_CODE (TREE_VALUE (rhs)) == TREE_LIST) - rhs = TREE_VALUE (rhs); - my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL, - 182); - } - - for (baselink = rhs; baselink; - baselink = next_baselink (baselink)) - { - elem = TREE_VALUE (baselink); - while (elem) - if (TREE_TYPE (elem) != lhstype) - elem = TREE_CHAIN (elem); - else - return elem; - } - - /* No exact match found, look for a compatible method. */ - for (baselink = rhs; baselink; - baselink = next_baselink (baselink)) - { - elem = TREE_VALUE (baselink); - while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1)) - elem = TREE_CHAIN (elem); - if (elem) - { - tree save_elem = elem; - elem = TREE_CHAIN (elem); - while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 0)) - elem = TREE_CHAIN (elem); - if (elem) - { - if (complain) - error ("ambiguous overload for overloaded method requested"); - return error_mark_node; - } - return save_elem; - } - name = DECL_NAME (TREE_VALUE (rhs)); - if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0) - { - /* Try to instantiate from non-member functions. */ - rhs = IDENTIFIER_GLOBAL_VALUE (name); - if (rhs && TREE_CODE (rhs) == TREE_LIST) - { - /* This code seems to be missing a `return'. */ - my_friendly_abort (4); - instantiate_type (lhstype, rhs, complain); - } - } - } - if (complain) - error ("no static member functions named `%s'", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - - case CALL_EXPR: - /* This is too hard for now. */ - my_friendly_abort (183); - return error_mark_node; - - case PLUS_EXPR: - case MINUS_EXPR: - case COMPOUND_EXPR: - TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (TREE_OPERAND (rhs, 0) == error_mark_node) - return error_mark_node; - TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case FLOOR_DIV_EXPR: - case CEIL_DIV_EXPR: - case ROUND_DIV_EXPR: - case RDIV_EXPR: - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - case CEIL_MOD_EXPR: - case ROUND_MOD_EXPR: - case FIX_ROUND_EXPR: - case FIX_FLOOR_EXPR: - case FIX_CEIL_EXPR: - case FIX_TRUNC_EXPR: - case FLOAT_EXPR: - case NEGATE_EXPR: - case ABS_EXPR: - case MAX_EXPR: - case MIN_EXPR: - case FFS_EXPR: - - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case LROTATE_EXPR: - case RROTATE_EXPR: - - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - if (complain) - error ("illegal operation on uninstantiated type"); - return error_mark_node; - - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_NOT_EXPR: - if (complain) - error ("not enough type information"); - return error_mark_node; - - case COND_EXPR: - if (type_unknown_p (TREE_OPERAND (rhs, 0))) - { - if (complain) - error ("not enough type information"); - return error_mark_node; - } - TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - TREE_OPERAND (rhs, 2) = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain); - if (TREE_OPERAND (rhs, 2) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case MODIFY_EXPR: - TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case ADDR_EXPR: - if (TREE_CODE (lhstype) != POINTER_TYPE) - { - if (complain) - error ("type for resolving address of overloaded function must be pointer type"); - return error_mark_node; - } - TREE_TYPE (rhs) = lhstype; - lhstype = TREE_TYPE (lhstype); - TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (TREE_OPERAND (rhs, 0) == error_mark_node) - return error_mark_node; - - mark_addressable (TREE_OPERAND (rhs, 0)); - return rhs; - - case ENTRY_VALUE_EXPR: - my_friendly_abort (184); - return error_mark_node; - - case ERROR_MARK: - return error_mark_node; - - default: - my_friendly_abort (185); - return error_mark_node; - } -} - -/* Return the name of the virtual function pointer field - (as an IDENTIFIER_NODE) for the given TYPE. Note that - this may have to look back through base types to find the - ultimate field name. (For single inheritance, these could - all be the same name. Who knows for multiple inheritance). */ -static tree -get_vfield_name (type) - tree type; -{ - tree binfo = TYPE_BINFO (type); - char *buf; - - while (BINFO_BASETYPES (binfo) - && TYPE_VIRTUAL_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0))) - && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0))) - binfo = BINFO_BASETYPE (binfo, 0); - - type = BINFO_TYPE (binfo); - buf = (char *)alloca (sizeof (VFIELD_NAME_FORMAT) - + TYPE_NAME_LENGTH (type) + 2); - sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); - return get_identifier (buf); -} - -void -print_class_statistics () -{ -#ifdef GATHER_STATISTICS - fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness); - fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs); - fprintf (stderr, "build_method_call = %d (inner = %d)\n", - n_build_method_call, n_inner_fields_searched); - if (n_vtables) - { - fprintf (stderr, "vtables = %d; vtable searches = %d\n", - n_vtables, n_vtable_searches); - fprintf (stderr, "vtable entries = %d; vtable elems = %d\n", - n_vtable_entries, n_vtable_elems); - } -#endif -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-class.h b/gnu/usr.bin/gcc2/cc1plus/cp-class.h deleted file mode 100644 index 3ca3a8b42f4..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-class.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Variables and structures for overloading rules. - Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: cp-class.h,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $ -*/ - -/* The following structure is used when comparing various alternatives - for overloading. The unsigned quantity `strikes.i' is used - for fast comparison of two possibilities. This number is an - aggregate of four constituents: - - EVIL: if this is non-zero, then the candidate should not be considered - ELLIPSIS: if this is non-zero, then some actual argument has been matched - against an ellipsis - USER: if this is non-zero, then a user-defined type conversion is needed - B_OR_D: if this is non-zero, then use a base pointer instead of the - type of the pointer we started with. - EASY: if this is non-zero, then we have a builtin conversion - (such as int to long, int to float, etc) to do. - - If two candidates require user-defined type conversions, and the - type conversions are not identical, then an ambiguity error - is reported. - - If two candidates agree on user-defined type conversions, - and one uses pointers of strictly higher type (derived where - another uses base), then that alternative is silently chosen. - - If two candidates have a non-monotonic derived/base pointer - relationship, and/or a non-monotonic easy conversion relationship, - then a warning is emitted to show which paths are possible, and - which one is being chosen. - - For example: - - int i; - double x; - - overload f; - int f (int, int); - double f (double, double); - - f (i, x); // draws a warning - - struct B - { - f (int); - } *bb; - struct D : B - { - f (double); - } *dd; - - dd->f (x); // exact match - dd->f (i); // draws warning - - Note that this technique really only works for 255 arguments. Perhaps - this is not enough. */ - -struct candidate -{ - tree function; /* A FUNCTION_DECL */ - - unsigned char evil; /* !0 if this will never convert. */ - unsigned char ellipsis; /* !0 if a match against an ellipsis occurred */ - unsigned char user; /* !0 if at least one user-defined type conv. */ - unsigned short b_or_d; /* count number of derived->base or - base->derived conv. */ - unsigned short easy; /* count number of builtin type conv. */ - tree arg; /* first parm to function. */ - unsigned short *harshness; /* Indexed by argument number, encodes - evil, user, d_to_b, and easy strikes for - that argument. - At end of array, we store the index+1 - of where we started using default - parameters, or 0 if there are none. */ - union - { - tree field; /* If no evil strikes, the FUNCTION_DECL of - the function (if a member function). */ - int bad_arg; /* the index of the first bad argument: - 0 if no bad arguments - > 0 is first bad argument - -1 if extra actual arguments - -2 if too few actual arguments. - -3 if const/non const method mismatch. - -4 if type unification failed. - -5 if contravariance violation. */ - } u; -}; -int rank_for_overload (); - -/* Variables shared between cp-class.c and cp-call.c. */ - -extern int n_vtables; -extern int n_vtable_entries; -extern int n_vtable_searches; -extern int n_vtable_elems; -extern int n_convert_harshness; -extern int n_compute_conversion_costs; -extern int n_build_method_call; -extern int n_inner_fields_searched; diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-cvt.c b/gnu/usr.bin/gcc2/cc1plus/cp-cvt.c deleted file mode 100644 index 2c647849c5a..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-cvt.c +++ /dev/null @@ -1,1793 +0,0 @@ -/* Language-level data type conversion for GNU C++. - Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-cvt.c,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $"; -#endif /* not lint */ - -/* This file contains the functions for converting C expressions - to different data types. The only entry point is `convert'. - Every language front end must have a `convert' function - but what kind of conversions it does will depend on the language. */ - -#include "config.h" -#include "tree.h" -#include "flags.h" -#include "cp-tree.h" -#include "convert.h" - -#undef NULL -#define NULL (char *)0 - -/* Change of width--truncation and extension of integers or reals-- - is represented with NOP_EXPR. Proper functioning of many things - assumes that no other conversions can be NOP_EXPRs. - - Conversion between integer and pointer is represented with CONVERT_EXPR. - Converting integer to real uses FLOAT_EXPR - and real to integer uses FIX_TRUNC_EXPR. - - Here is a list of all the functions that assume that widening and - narrowing is always done with a NOP_EXPR: - In c-convert.c, convert_to_integer. - In c-typeck.c, build_binary_op_nodefault (boolean ops), - and truthvalue_conversion. - In expr.c: expand_expr, for operands of a MULT_EXPR. - In fold-const.c: fold. - In tree.c: get_narrower and get_unwidened. - - C++: in multiple-inheritance, converting between pointers may involve - adjusting them by a delta stored within the class definition. */ - -/* Subroutines of `convert'. */ - -static tree -cp_convert_to_pointer (type, expr) - tree type, expr; -{ - register tree intype = TREE_TYPE (expr); - register enum tree_code form = TREE_CODE (intype); - - if (form == POINTER_TYPE) - { - intype = TYPE_MAIN_VARIANT (intype); - - if (TYPE_MAIN_VARIANT (type) != intype - && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) - { - enum tree_code code = PLUS_EXPR; - tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1); - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == NULL_TREE) - { - binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 1); - if (binfo == error_mark_node) - return error_mark_node; - code = MINUS_EXPR; - } - if (binfo) - { - if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type)) - || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype)) - || ! BINFO_OFFSET_ZEROP (binfo)) - { - /* Need to get the path we took. */ - tree path; - - if (code == PLUS_EXPR) - get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), 0, &path); - else - get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), 0, &path); - return build_vbase_path (code, type, expr, path, 0); - } - } - } - return build1 (NOP_EXPR, type, expr); - } - - my_friendly_assert (form != OFFSET_TYPE, 186); - - if (IS_AGGR_TYPE (intype)) - { - /* If we cannot convert to the specific pointer type, - try to convert to the type `void *'. */ - tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, expr, 1); - if (rval) - { - if (rval == error_mark_node) - error ("ambiguous pointer conversion"); - return rval; - } - } - - return convert_to_pointer (type, expr); -} - -/* Like convert, except permit conversions to take place which - are not normally allowed due to visibility restrictions - (such as conversion from sub-type to private super-type). */ -static tree -convert_to_pointer_force (type, expr) - tree type, expr; -{ - register tree intype = TREE_TYPE (expr); - register enum tree_code form = TREE_CODE (intype); - - if (integer_zerop (expr)) - { - if (type == TREE_TYPE (null_pointer_node)) - return null_pointer_node; - expr = build_int_2 (0, 0); - TREE_TYPE (expr) = type; - return expr; - } - - if (form == POINTER_TYPE) - { - intype = TYPE_MAIN_VARIANT (intype); - - if (TYPE_MAIN_VARIANT (type) != intype - && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) - { - enum tree_code code = PLUS_EXPR; - tree path; - int distance = get_base_distance (TREE_TYPE (type), - TREE_TYPE (intype), 0, &path); - if (distance == -2) - { - ambig: - error_with_aggr_type (TREE_TYPE (type), "type `%s' is ambiguous baseclass of `%s'", - TYPE_NAME_STRING (TREE_TYPE (intype))); - return error_mark_node; - } - if (distance == -1) - { - distance = get_base_distance (TREE_TYPE (intype), - TREE_TYPE (type), 0, &path); - if (distance == -2) - goto ambig; - if (distance < 0) - /* Doesn't need any special help from us. */ - return build1 (NOP_EXPR, type, expr); - - code = MINUS_EXPR; - } - return build_vbase_path (code, type, expr, path, 0); - } - return build1 (NOP_EXPR, type, expr); - } - - return cp_convert_to_pointer (type, expr); -} - -/* We are passing something to a function which requires a reference. - The type we are interested in is in TYPE. The initial - value we have to begin with is in ARG. - - FLAGS controls how we manage visibility checking. - CHECKCONST controls if we report error messages on const subversion. */ -static tree -build_up_reference (type, arg, flags, checkconst) - tree type, arg; - int flags, checkconst; -{ - tree rval, targ; - int literal_flag = 0; - tree argtype = TREE_TYPE (arg), basetype = argtype; - tree target_type = TREE_TYPE (type); - tree binfo = NULL_TREE; - - my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187); - if (flags != 0 - && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) - && IS_AGGR_TYPE (argtype) - && IS_AGGR_TYPE (target_type)) - { - binfo = get_binfo (target_type, argtype, - (flags & LOOKUP_PROTECTED_OK) ? 3 : 2); - if ((flags & LOOKUP_PROTECT) && binfo == error_mark_node) - return error_mark_node; - if (basetype == NULL_TREE) - return (tree) error_not_base_type (target_type, argtype); - basetype = BINFO_TYPE (binfo); - } - - /* Pass along const and volatile down into the type. */ - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - target_type = build_type_variant (target_type, TYPE_READONLY (type), - TYPE_VOLATILE (type)); - targ = arg; - if (TREE_CODE (targ) == SAVE_EXPR) - targ = TREE_OPERAND (targ, 0); - - switch (TREE_CODE (targ)) - { - case INDIRECT_REF: - /* This is a call to a constructor which did not know what it was - initializing until now: it needs to initialize a temporary. */ - if (TREE_HAS_CONSTRUCTOR (targ)) - { - tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0), 1); - TREE_HAS_CONSTRUCTOR (targ) = 0; - return build_up_reference (type, temp, flags, 1); - } - /* Let &* cancel out to simplify resulting code. - Also, throw away intervening NOP_EXPRs. */ - arg = TREE_OPERAND (targ, 0); - if (TREE_CODE (arg) == NOP_EXPR || TREE_CODE (arg) == NON_LVALUE_EXPR - || (TREE_CODE (arg) == CONVERT_EXPR && TREE_REFERENCE_EXPR (arg))) - arg = TREE_OPERAND (arg, 0); - - /* in doing a &*, we have to get rid of the const'ness on the pointer - value. Haven't thought about volatile here. Pointers come to mind - here. */ - if (TREE_READONLY (arg)) - { - arg = copy_node (arg); - TREE_READONLY (arg) = 0; - } - - rval = build1 (CONVERT_EXPR, type, arg); - TREE_REFERENCE_EXPR (rval) = 1; - - /* propagate the const flag on something like: - - class Base { - public: - int foo; - }; - - class Derived : public Base { - public: - int bar; - }; - - void func(Base&); - - void func2(const Derived& d) { - func(d); - } - - on the d parameter. The below could have been avoided, if the flags - were down in the tree, not sure why they are not. (mrs) */ - /* The below code may have to be propagated to other parts of this - switch. */ - if (TREE_READONLY (targ) && !TREE_READONLY (arg) - && (TREE_CODE (arg) == PARM_DECL || TREE_CODE (arg) == VAR_DECL) - && TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE - && (TYPE_READONLY (target_type) && checkconst)) - { - arg = copy_node (arg); - TREE_READONLY (arg) = TREE_READONLY (targ); - } - literal_flag = TREE_CONSTANT (arg); - - goto done_but_maybe_warn; - - /* Get this out of a register if we happened to be in one by accident. - Also, build up references to non-lvalues it we must. */ - /* For &x[y], return (&) x+y */ - case ARRAY_REF: - if (mark_addressable (TREE_OPERAND (targ, 0)) == 0) - return error_mark_node; - rval = build_binary_op (PLUS_EXPR, TREE_OPERAND (targ, 0), - TREE_OPERAND (targ, 1), 1); - TREE_TYPE (rval) = type; - if (TREE_CONSTANT (TREE_OPERAND (targ, 1)) - && staticp (TREE_OPERAND (targ, 0))) - TREE_CONSTANT (rval) = 1; - goto done; - - case SCOPE_REF: - /* Could be a reference to a static member. */ - { - tree field = TREE_OPERAND (targ, 1); - if (TREE_STATIC (field)) - { - rval = build1 (ADDR_EXPR, type, field); - literal_flag = 1; - goto done; - } - } - - /* We should have farmed out member pointers above. */ - my_friendly_abort (188); - - case COMPONENT_REF: - rval = build_component_addr (targ, build_pointer_type (argtype), - "attempt to make a reference to bit-field structure member `%s'"); - TREE_TYPE (rval) = type; - literal_flag = staticp (TREE_OPERAND (targ, 0)); - - goto done_but_maybe_warn; - - /* Anything not already handled and not a true memory reference - needs to have a reference built up. Do so silently for - things like integers and return values from function, - but complain if we need a reference to something declared - as `register'. */ - - case RESULT_DECL: - if (staticp (targ)) - literal_flag = 1; - TREE_ADDRESSABLE (targ) = 1; - put_var_into_stack (targ); - break; - - case PARM_DECL: - if (targ == current_class_decl) - { - error ("address of `this' not available"); -#if 0 - /* This code makes the following core dump the compiler on a sun4, - if the code below is used. - - class e_decl; - class a_decl; - typedef a_decl* a_ref; - - class a_s { - public: - a_s(); - void* append(a_ref& item); - }; - class a_decl { - public: - a_decl (e_decl *parent); - a_s generic_s; - a_s decls; - e_decl* parent; - }; - - class e_decl { - public: - e_decl(); - a_s implementations; - }; - - void foobar(void *); - - a_decl::a_decl(e_decl *parent) { - parent->implementations.append(this); - } - */ - - TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */ - put_var_into_stack (targ); - break; -#else - return error_mark_node; -#endif - } - /* Fall through. */ - case VAR_DECL: - case CONST_DECL: - if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)) - warning ("address needed to build reference for `%s', which is declared `register'", - IDENTIFIER_POINTER (DECL_NAME (targ))); - else if (staticp (targ)) - literal_flag = 1; - - TREE_ADDRESSABLE (targ) = 1; - put_var_into_stack (targ); - break; - - case COMPOUND_EXPR: - { - tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 1), - LOOKUP_PROTECT, checkconst); - rval = build (COMPOUND_EXPR, type, TREE_OPERAND (targ, 0), real_reference); - TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 1)); - return rval; - } - - case MODIFY_EXPR: - case INIT_EXPR: - { - tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 0), - LOOKUP_PROTECT, checkconst); - rval = build (COMPOUND_EXPR, type, arg, real_reference); - TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 0)); - return rval; - } - - case COND_EXPR: - return build (COND_EXPR, type, - TREE_OPERAND (targ, 0), - build_up_reference (type, TREE_OPERAND (targ, 1), - LOOKUP_PROTECT, checkconst), - build_up_reference (type, TREE_OPERAND (targ, 2), - LOOKUP_PROTECT, checkconst)); - - case WITH_CLEANUP_EXPR: - return build (WITH_CLEANUP_EXPR, type, - build_up_reference (type, TREE_OPERAND (targ, 0), - LOOKUP_PROTECT, checkconst), - 0, TREE_OPERAND (targ, 2)); - - case BIND_EXPR: - arg = TREE_OPERAND (targ, 1); - if (arg == NULL_TREE) - { - compiler_error ("({ ... }) expression not expanded when needed for reference"); - return error_mark_node; - } - rval = build1 (ADDR_EXPR, type, arg); - TREE_REFERENCE_EXPR (rval) = 1; - return rval; - - default: - break; - } - - if (TREE_ADDRESSABLE (targ) == 0) - { - tree temp; - - if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype)) - { - temp = build_cplus_new (argtype, targ, 1); - rval = build1 (ADDR_EXPR, type, temp); - goto done; - } - else - { - temp = get_temp_name (argtype, 0); - if (global_bindings_p ()) - { - /* Give this new temp some rtl and initialize it. */ - DECL_INITIAL (temp) = targ; - TREE_STATIC (temp) = 1; - finish_decl (temp, targ, NULL_TREE, 0); - /* Do this after declaring it static. */ - rval = build_unary_op (ADDR_EXPR, temp, 0); - literal_flag = TREE_CONSTANT (rval); - goto done; - } - else - { - rval = build_unary_op (ADDR_EXPR, temp, 0); - /* Put a value into the rtl. */ - if (IS_AGGR_TYPE (argtype)) - { - /* This may produce surprising results, - since we commit to initializing the temp - when the temp may not actually get used. */ - expand_aggr_init (temp, targ, 0); - TREE_TYPE (rval) = type; - literal_flag = TREE_CONSTANT (rval); - goto done; - } - else - { - if (binfo && !BINFO_OFFSET_ZEROP (binfo)) - rval = convert_pointer_to (target_type, rval); - else - TREE_TYPE (rval) = type; - return build (COMPOUND_EXPR, type, - build (MODIFY_EXPR, argtype, temp, arg), rval); - } - } - } - } - else - { - if (TREE_CODE (arg) == SAVE_EXPR) - my_friendly_abort (5); - rval = build1 (ADDR_EXPR, type, arg); - } - - done_but_maybe_warn: - if (checkconst && TREE_READONLY (arg) && ! TYPE_READONLY (target_type)) - readonly_error (arg, "conversion to reference", 1); - - done: - if (TYPE_USES_COMPLEX_INHERITANCE (argtype)) - { - TREE_TYPE (rval) = TYPE_POINTER_TO (argtype); - rval = convert_pointer_to (target_type, rval); - TREE_TYPE (rval) = type; - } - TREE_CONSTANT (rval) = literal_flag; - return rval; -} - -/* For C++: Only need to do one-level references, but cannot - get tripped up on signed/unsigned differences. - - If DECL is NULL_TREE it means convert as though casting (by force). - If it is ERROR_MARK_NODE, it means the conversion is implicit, - and that temporaries may be created. - Make sure the use of user-defined conversion operators is un-ambiguous. - Otherwise, DECL is a _DECL node which can be used in error reporting. - - FNDECL, PARMNUM, and ERRTYPE are only used when checking for use of - volatile or const references where they aren't desired. */ - -tree -convert_to_reference (decl, reftype, expr, fndecl, parmnum, - errtype, strict, flags) - - tree decl; - tree reftype, expr; - tree fndecl; - int parmnum; - char *errtype; - int strict, flags; -{ - register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); - register tree intype = TREE_TYPE (expr); - register enum tree_code form = TREE_CODE (intype); - tree rval = NULL_TREE; - - if (form == REFERENCE_TYPE) - intype = TREE_TYPE (intype); - intype = TYPE_MAIN_VARIANT (intype); - - /* @@ Probably need to have a check for X(X&) here. */ - - if (IS_AGGR_TYPE (intype)) - { - rval = build_type_conversion (CONVERT_EXPR, reftype, expr, 1); - if (rval) - { - if (rval == error_mark_node) - error ("ambiguous pointer conversion"); - return rval; - } - else if (type != intype - && (rval = build_type_conversion (CONVERT_EXPR, type, expr, 1))) - { - if (rval == error_mark_node) - return rval; - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - rval = convert_to_reference (NULL_TREE, reftype, rval, NULL_TREE, --1, (char *)NULL, strict, flags); - } - else - { - decl = get_temp_name (type, 0); - rval = build (INIT_EXPR, type, decl, rval); - rval = build (COMPOUND_EXPR, reftype, rval, - convert_to_reference (NULL_TREE, reftype, decl, - NULL_TREE, -1, (char*)NULL, - strict, flags)); - } - } - - if (form == REFERENCE_TYPE - && type != intype - && TYPE_USES_COMPLEX_INHERITANCE (intype)) - { - /* If it may move around, build a fresh reference. */ - expr = convert_from_reference (expr); - form = TREE_CODE (TREE_TYPE (expr)); - } - } - - /* @@ Perhaps this should try to go through a constructor first - @@ for proper initialization, but I am not sure when that - @@ is needed or desirable. - - @@ The second disjunct is provided to make references behave - @@ as some people think they should, i.e., an interconvertibility - @@ between references to builtin types (such as short and - @@ unsigned short). There should be no conversion between - @@ types whose codes are different, or whose sizes are different. */ - - if (((IS_AGGR_TYPE (type) || IS_AGGR_TYPE (intype)) - && comptypes (type, intype, strict)) - || (!IS_AGGR_TYPE (type) - && TREE_CODE (type) == TREE_CODE (intype) - && int_size_in_bytes (type) == int_size_in_bytes (intype))) - { - /* Section 13. */ - /* Since convert_for_initialization didn't call convert_for_assignment, - we have to do this checking here. XXX We should have a common - routine between here and convert_for_assignment. */ - if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE) - { - register tree ttl = TREE_TYPE (reftype); - register tree ttr = TREE_TYPE (TREE_TYPE (expr)); - - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s of non-`const &' reference from `const &'", - "reference to const given for argument %d of `%s'", - errtype, fndecl, parmnum, pedantic); - if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s of non-`volatile &' reference from `volatile &'", - "reference to volatile given for argument %d of `%s'", - errtype, fndecl, parmnum, pedantic); - } - - /* If EXPR is of aggregate type, and is really a CALL_EXPR, - then we don't need to convert it to reference type if - it is only being used to initialize DECL which is also - of the same aggregate type. */ - if (form == REFERENCE_TYPE - || (decl != NULL_TREE && decl != error_mark_node - && IS_AGGR_TYPE (type) - && TREE_CODE (expr) == CALL_EXPR - && TYPE_MAIN_VARIANT (type) == intype)) - { - if (decl && decl != error_mark_node) - { - tree e1 = build (INIT_EXPR, void_type_node, decl, expr); - tree e2; - - TREE_SIDE_EFFECTS (e1) = 1; - if (form == REFERENCE_TYPE) - e2 = build1 (NOP_EXPR, reftype, decl); - else - { - e2 = build_unary_op (ADDR_EXPR, decl, 0); - TREE_TYPE (e2) = reftype; - TREE_REFERENCE_EXPR (e2) = 1; - } - return build_compound_expr (tree_cons (NULL_TREE, e1, - build_tree_list (NULL_TREE, e2))); - } - expr = copy_node (expr); - TREE_TYPE (expr) = reftype; - return expr; - } - if (decl == error_mark_node) - flags |= LOOKUP_PROTECTED_OK; - return build_up_reference (reftype, expr, flags, decl!=NULL_TREE); - } - - /* Definitely need to go through a constructor here. */ - if (TYPE_HAS_CONSTRUCTOR (type)) - { - tree init = build_method_call (NULL_TREE, constructor_name (type), - build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), LOOKUP_NO_CONVERSION); - - if (init != error_mark_node) - if (rval) - { - error ("both constructor and type conversion operator apply"); - return error_mark_node; - } - - init = build_method_call (NULL_TREE, constructor_name (type), - build_tree_list (NULL_TREE, expr), - TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); - - if (init == error_mark_node) - return error_mark_node; - rval = build_cplus_new (type, init, 1); - if (decl == error_mark_node) - flags |= LOOKUP_PROTECTED_OK; - return build_up_reference (reftype, rval, flags, decl!=NULL_TREE); - } - - my_friendly_assert (form != OFFSET_TYPE, 189); - - /* This is in two pieces for now, because pointer to first becomes - invalid once type_as_string is called again. */ - error ("cannot convert type `%s'", type_as_string (intype)); - error (" to type `%s'", type_as_string (reftype)); - - return error_mark_node; -} - -/* We are using a reference VAL for its value. Bash that reference all the - way down to its lowest form. */ -tree -convert_from_reference (val) - tree val; -{ - tree type = TREE_TYPE (val); - - if (TREE_CODE (type) == OFFSET_TYPE) - type = TREE_TYPE (type); - if (TREE_CODE (type) == REFERENCE_TYPE) - { - tree target_type = TREE_TYPE (type); - tree nval; - - /* This can happen if we cast to a reference type. */ - if (TREE_CODE (val) == ADDR_EXPR) - { - nval = build1 (NOP_EXPR, build_pointer_type (target_type), val); - nval = build_indirect_ref (nval, 0); - /* The below was missing, are other important flags missing too? */ - TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val); - return nval; - } - - nval = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (target_type), val); - - TREE_THIS_VOLATILE (nval) = TYPE_VOLATILE (target_type); - TREE_SIDE_EFFECTS (nval) = TYPE_VOLATILE (target_type); - TREE_READONLY (nval) = TYPE_READONLY (target_type); - /* The below was missing, are other important flags missing too? */ - TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val); - return nval; - } - return val; -} - -/* See if there is a constructor of type TYPE which will convert - EXPR. The reference manual seems to suggest (8.5.6) that we need - not worry about finding constructors for base classes, then converting - to the derived class. - - MSGP is a pointer to a message that would be an appropriate error - string. If MSGP is NULL, then we are not interested in reporting - errors. */ -tree -convert_to_aggr (type, expr, msgp, protect) - tree type, expr; - char **msgp; - int protect; -{ - tree basetype = type; - tree name = TYPE_IDENTIFIER (basetype); - tree function, fndecl, fntype, parmtypes, parmlist, result; - tree method_name; - enum visibility_type visibility; - int can_be_private, can_be_protected; - - if (! TYPE_HAS_CONSTRUCTOR (basetype)) - { - if (msgp) - *msgp = "type `%s' does not have a constructor"; - return error_mark_node; - } - - visibility = visibility_public; - can_be_private = 0; - can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name; - - parmlist = build_tree_list (NULL_TREE, expr); - parmtypes = tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node); - - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes); - parmlist = tree_cons (NULL_TREE, integer_one_node, parmlist); - } - - /* The type of the first argument will be filled in inside the loop. */ - parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist); - parmtypes = tree_cons (NULL_TREE, TYPE_POINTER_TO (basetype), parmtypes); - - method_name = build_decl_overload (name, parmtypes, 1); - - /* constructors are up front. */ - fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0); - if (TYPE_HAS_DESTRUCTOR (basetype)) - fndecl = DECL_CHAIN (fndecl); - - while (fndecl) - { - if (DECL_ASSEMBLER_NAME (fndecl) == method_name) - { - function = fndecl; - if (protect) - { - if (TREE_PRIVATE (fndecl)) - { - can_be_private = - (basetype == current_class_type - || is_friend (basetype, current_function_decl) - || purpose_member (basetype, DECL_VISIBILITY (fndecl))); - if (! can_be_private) - goto found; - } - else if (TREE_PROTECTED (fndecl)) - { - if (! can_be_protected) - goto found; - } - } - goto found_and_ok; - } - fndecl = DECL_CHAIN (fndecl); - } - - /* No exact conversion was found. See if an approximate - one will do. */ - fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0); - if (TYPE_HAS_DESTRUCTOR (basetype)) - fndecl = DECL_CHAIN (fndecl); - - { - int saw_private = 0; - int saw_protected = 0; - struct candidate *candidates = - (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate)); - struct candidate *cp = candidates; - - while (fndecl) - { - function = fndecl; - cp->harshness = (unsigned short *)alloca (3 * sizeof (short)); - compute_conversion_costs (fndecl, parmlist, cp, 2); - if (cp->evil == 0) - { - cp->u.field = fndecl; - if (protect) - { - if (TREE_PRIVATE (fndecl)) - visibility = visibility_private; - else if (TREE_PROTECTED (fndecl)) - visibility = visibility_protected; - else - visibility = visibility_public; - } - else - visibility = visibility_public; - - if (visibility == visibility_private - ? (basetype == current_class_type - || is_friend (basetype, cp->function) - || purpose_member (basetype, DECL_VISIBILITY (fndecl))) - : visibility == visibility_protected - ? (can_be_protected - || purpose_member (basetype, DECL_VISIBILITY (fndecl))) - : 1) - { - if (cp->user == 0 && cp->b_or_d == 0 - && cp->easy <= 1) - { - goto found_and_ok; - } - cp++; - } - else - { - if (visibility == visibility_private) - saw_private = 1; - else - saw_protected = 1; - } - } - fndecl = DECL_CHAIN (fndecl); - } - if (cp - candidates) - { - /* Rank from worst to best. Then cp will point to best one. - Private fields have their bits flipped. For unsigned - numbers, this should make them look very large. - If the best alternate has a (signed) negative value, - then all we ever saw were private members. */ - if (cp - candidates > 1) - qsort (candidates, /* char *base */ - cp - candidates, /* int nel */ - sizeof (struct candidate), /* int width */ - rank_for_overload); /* int (*compar)() */ - - --cp; - if (cp->evil > 1) - { - if (msgp) - *msgp = "ambiguous type conversion possible for `%s'"; - return error_mark_node; - } - - function = cp->function; - fndecl = cp->u.field; - goto found_and_ok; - } - else if (msgp) - { - if (saw_private) - if (saw_protected) - *msgp = "only private and protected conversions apply"; - else - *msgp = "only private conversions apply"; - else if (saw_protected) - *msgp = "only protected conversions apply"; - } - return error_mark_node; - } - /* NOTREACHED */ - - not_found: - if (msgp) *msgp = "no appropriate conversion to type `%s'"; - return error_mark_node; - found: - if (visibility == visibility_private) - if (! can_be_private) - { - if (msgp) - *msgp = TREE_PRIVATE (fndecl) - ? "conversion to type `%s' is private" - : "conversion to type `%s' is from private base class"; - return error_mark_node; - } - if (visibility == visibility_protected) - if (! can_be_protected) - { - if (msgp) - *msgp = TREE_PRIVATE (fndecl) - ? "conversion to type `%s' is protected" - : "conversion to type `%s' is from protected base class"; - return error_mark_node; - } - function = fndecl; - found_and_ok: - - /* It will convert, but we don't do anything about it yet. */ - if (msgp == 0) - return NULL_TREE; - - fntype = TREE_TYPE (function); - if (DECL_INLINE (function) && TREE_CODE (function) == FUNCTION_DECL) - function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); - else - function = default_conversion (function); - - result = build_nt (CALL_EXPR, function, - convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype), - parmlist, NULL_TREE, LOOKUP_NORMAL), - NULL_TREE); - TREE_TYPE (result) = TREE_TYPE (fntype); - TREE_SIDE_EFFECTS (result) = 1; - TREE_RAISES (result) = !! TYPE_RAISES_EXCEPTIONS (fntype); - return result; -} - -/* Call this when we know (for any reason) that expr is - not, in fact, zero. */ -tree -convert_pointer_to (binfo, expr) - tree binfo, expr; -{ - register tree intype = TREE_TYPE (expr); - tree ptr_type; - tree type, rval; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE (binfo)) - { - type = binfo; - binfo = TYPE_BINFO (binfo); - } - else - { - type = binfo; - binfo = NULL_TREE; - } - - ptr_type = build_pointer_type (type); - if (ptr_type == TYPE_MAIN_VARIANT (intype)) - return expr; - - if (intype == error_mark_node) - return error_mark_node; - - my_friendly_assert (!integer_zerop (expr), 191); - - if (TREE_CODE (type) == RECORD_TYPE - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE - && type != TYPE_MAIN_VARIANT (TREE_TYPE (intype))) - { - tree path; - int distance - = get_base_distance (type, TYPE_MAIN_VARIANT (TREE_TYPE (intype)), - 0, &path); - - /* This function shouldn't be called with unqualified arguments - but if it is, give them an error message that they can read. - */ - if (distance < 0) - { - error ("cannot convert a pointer of type `%s'", - TYPE_NAME_STRING (TREE_TYPE (intype))); - error_with_aggr_type (type, "to a pointer of type `%s'"); - - return error_mark_node; - } - - return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1); - } - rval = build1 (NOP_EXPR, ptr_type, - TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr); - TREE_CONSTANT (rval) = TREE_CONSTANT (expr); - return rval; -} - -/* Same as above, but don't abort if we get an "ambiguous" baseclass. - There's only one virtual baseclass we are looking for, and once - we find one such virtual baseclass, we have found them all. */ - -tree -convert_pointer_to_vbase (binfo, expr) - tree binfo; - tree expr; -{ - tree intype = TREE_TYPE (TREE_TYPE (expr)); - tree binfos = TYPE_BINFO_BASETYPES (intype); - int i; - - for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--) - { - tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); - if (BINFO_TYPE (binfo) == basetype) - return convert_pointer_to (binfo, expr); - if (binfo_member (BINFO_TYPE (binfo), CLASSTYPE_VBASECLASSES (basetype))) - return convert_pointer_to_vbase (binfo, convert_pointer_to (basetype, expr)); - } - my_friendly_abort (6); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Create an expression whose value is that of EXPR, - converted to type TYPE. The TREE_TYPE of the value - is always TYPE. This function implements all reasonable - conversions; callers should filter out those that are - not permitted by the language being compiled. */ - -tree -convert (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (expr) - || TREE_CODE (expr) == ERROR_MARK) - return expr; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold (build1 (NOP_EXPR, type, expr)); - if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == VOID_TYPE) - { - tree rval = build_type_conversion (NOP_EXPR, type, e, 0); - /* If we can convert to void type via a type conversion, do so. */ - if (rval) - return rval; - return build1 (CONVERT_EXPR, type, e); - } -#if 0 - /* This is incorrect. A truncation can't be stripped this way. - Extensions will be stripped by the use of get_unwidened. */ - if (TREE_CODE (expr) == NOP_EXPR) - return convert (type, TREE_OPERAND (expr, 0)); -#endif - - /* Just convert to the type of the member. */ - if (code == OFFSET_TYPE) - { - type = TREE_TYPE (type); - code = TREE_CODE (type); - } - - /* C++ */ - if (code == REFERENCE_TYPE) - return fold (convert_to_reference (error_mark_node, - type, e, - NULL_TREE, -1, (char *)NULL, - -1, LOOKUP_NORMAL)); - else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) - e = convert_from_reference (e); - - if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) - { - tree intype = TREE_TYPE (expr); - enum tree_code form = TREE_CODE (intype); - if (flag_int_enum_equivalence == 0 - && TREE_CODE (type) == ENUMERAL_TYPE - && form == INTEGER_TYPE) - { - if (pedantic) - pedwarn ("anachronistic conversion from integer type to enumeral type `%s'", - TYPE_NAME_STRING (type)); - if (flag_pedantic_errors) - return error_mark_node; - } - if (form == OFFSET_TYPE) - error_with_decl (TYPE_NAME (TYPE_OFFSET_BASETYPE (intype)), - "pointer-to-member expression object not composed with type `%s' object"); - else if (IS_AGGR_TYPE (intype)) - { - tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, expr, 1); - if (rval) return rval; - error ("aggregate value used where an integer was expected"); - return error_mark_node; - } - return fold (convert_to_integer (type, e)); - } - if (code == POINTER_TYPE) - return fold (cp_convert_to_pointer (type, e)); - if (code == REAL_TYPE) - { - if (IS_AGGR_TYPE (TREE_TYPE (e))) - { - tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, e, 1); - if (rval) - return rval; - else - error ("aggregate value used where a floating point value was expected"); - } - return fold (convert_to_real (type, e)); - } - - /* New C++ semantics: since assignment is now based on - memberwise copying, if the rhs type is derived from the - lhs type, then we may still do a conversion. */ - if (IS_AGGR_TYPE_CODE (code)) - { - tree dtype = TREE_TYPE (e); - - if (TREE_CODE (dtype) == REFERENCE_TYPE) - { - e = convert_from_reference (e); - dtype = TREE_TYPE (e); - } - dtype = TYPE_MAIN_VARIANT (dtype); - - /* Conversion between aggregate types. New C++ semantics allow - objects of derived type to be cast to objects of base type. - Old semantics only allowed this between pointers. - - There may be some ambiguity between using a constructor - vs. using a type conversion operator when both apply. */ - - if (IS_AGGR_TYPE (dtype)) - { - tree binfo; - - tree conversion = TYPE_HAS_CONVERSION (dtype) - ? build_type_conversion (CONVERT_EXPR, type, e, 1) : NULL_TREE; - - if (TYPE_HAS_CONSTRUCTOR (type)) - { - tree rval = build_method_call (NULL_TREE, constructor_name (type), - build_tree_list (NULL_TREE, e), - TYPE_BINFO (type), - conversion ? LOOKUP_NO_CONVERSION : 0); - - if (rval != error_mark_node) - { - if (conversion) - { - error ("both constructor and type conversion operator apply"); - return error_mark_node; - } - /* call to constructor successful. */ - rval = build_cplus_new (type, rval, 0); - return rval; - } - } - /* Type conversion successful/applies. */ - if (conversion) - { - if (conversion == error_mark_node) - error ("ambiguous pointer conversion"); - return conversion; - } - - /* now try normal C++ assignment semantics. */ - binfo = TYPE_BINFO (dtype); - if (BINFO_TYPE (binfo) == type - || (binfo = get_binfo (type, dtype, 1))) - { - if (binfo == error_mark_node) - return error_mark_node; - } - if (binfo != NULL_TREE) - { - if (lvalue_p (e)) - { - e = build_unary_op (ADDR_EXPR, e, 0); - - if (! BINFO_OFFSET_ZEROP (binfo)) - e = build (PLUS_EXPR, TYPE_POINTER_TO (type), - e, BINFO_OFFSET (binfo)); - return build1 (INDIRECT_REF, type, e); - } - - sorry ("addressable aggregates"); - return error_mark_node; - } - error ("conversion between incompatible aggregate types requested"); - return error_mark_node; - } - /* conversion from non-aggregate to aggregate type requires constructor. */ - else if (TYPE_HAS_CONSTRUCTOR (type)) - { - tree rval; - tree init = build_method_call (NULL_TREE, constructor_name (type), - build_tree_list (NULL_TREE, e), - TYPE_BINFO (type), LOOKUP_NORMAL); - if (init == error_mark_node) - { - error_with_aggr_type (type, "in conversion to type `%s'"); - return error_mark_node; - } - rval = build_cplus_new (type, init, 0); - return rval; - } - } - - /* If TYPE or TREE_TYPE (EXPR) is not on the permanent_obstack, - then the it won't be hashed and hence compare as not equal, - even when it is. */ - if (code == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (expr)) == TREE_TYPE (type) - && index_type_equal (TYPE_DOMAIN (TREE_TYPE (expr)), TYPE_DOMAIN (type))) - return expr; - - error ("conversion to non-scalar type requested"); - return error_mark_node; -} - -/* Like convert, except permit conversions to take place which - are not normally allowed due to visibility restrictions - (such as conversion from sub-type to private super-type). */ -tree -convert_force (type, expr) - tree type; - tree expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (code == REFERENCE_TYPE) - return fold (convert_to_reference (0, type, e, - NULL_TREE, -1, (char *)NULL, - -1, 0)); - else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) - e = convert_from_reference (e); - - if (code == POINTER_TYPE) - return fold (convert_to_pointer_force (type, e)); - - { - int old_equiv = flag_int_enum_equivalence; - flag_int_enum_equivalence = 1; - e = convert (type, e); - flag_int_enum_equivalence = old_equiv; - } - return e; -} - -/* Subroutine of build_type_conversion. */ -static tree -build_type_conversion_1 (xtype, basetype, expr, typename, for_sure) - tree xtype, basetype; - tree expr; - tree typename; - int for_sure; -{ - tree first_arg = expr; - tree rval; - int flags; - - if (for_sure == 0) - { - if (! lvalue_p (expr)) - first_arg = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node); - flags = LOOKUP_PROTECT; - } - else - flags = LOOKUP_NORMAL; - - rval = build_method_call (first_arg, constructor_name (typename), - NULL_TREE, NULL_TREE, flags); - if (rval == error_mark_node) - { - if (for_sure == 0) - return NULL_TREE; - return error_mark_node; - } - if (first_arg != expr) - { - expr = build_up_reference (build_reference_type (TREE_TYPE (expr)), expr, - LOOKUP_COMPLAIN, 1); - TREE_VALUE (TREE_OPERAND (rval, 1)) = build_unary_op (ADDR_EXPR, expr, 0); - } - if (TREE_CODE (TREE_TYPE (rval)) == REFERENCE_TYPE - && TREE_CODE (xtype) != REFERENCE_TYPE) - rval = default_conversion (rval); - - if (pedantic - && TREE_TYPE (xtype) - && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval))) - > TREE_READONLY (TREE_TYPE (xtype)))) - pedwarn ("user-defined conversion casting away `const'"); - return convert (xtype, rval); -} - -/* Convert an aggregate EXPR to type XTYPE. If a conversion - exists, return the attempted conversion. This may - return ERROR_MARK_NODE if the conversion is not - allowed (references private members, etc). - If no conversion exists, NULL_TREE is returned. - - If (FOR_SURE & 1) is non-zero, then we allow this type conversion - to take place immediately. Otherwise, we build a SAVE_EXPR - which can be evaluated if the results are ever needed. - - If FOR_SURE >= 2, then we only look for exact conversions. - - TYPE may be a reference type, in which case we first look - for something that will convert to a reference type. If - that fails, we will try to look for something of the - reference's target type, and then return a reference to that. */ -tree -build_type_conversion (code, xtype, expr, for_sure) - enum tree_code code; - tree xtype, expr; - int for_sure; -{ - /* C++: check to see if we can convert this aggregate type - into the required scalar type. */ - tree type, type_default; - tree typename = build_typename_overload (xtype), *typenames; - int n_variants = 0; - tree basetype, save_basetype; - tree rval; - int exact_conversion = for_sure >= 2; - for_sure &= 1; - - if (expr == error_mark_node) - return error_mark_node; - - basetype = TREE_TYPE (expr); - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); - - basetype = TYPE_MAIN_VARIANT (basetype); - if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype)) - return 0; - - if (TREE_CODE (xtype) == POINTER_TYPE - || TREE_CODE (xtype) == REFERENCE_TYPE) - { - /* Prepare to match a variant of this type. */ - type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype)); - for (n_variants = 0; type; type = TYPE_NEXT_VARIANT (type)) - n_variants++; - typenames = (tree *)alloca (n_variants * sizeof (tree)); - for (n_variants = 0, type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype)); - type; n_variants++, type = TYPE_NEXT_VARIANT (type)) - { - if (type == TREE_TYPE (xtype)) - typenames[n_variants] = typename; - else if (TREE_CODE (xtype) == POINTER_TYPE) - typenames[n_variants] = build_typename_overload (build_pointer_type (type)); - else - typenames[n_variants] = build_typename_overload (build_reference_type (type)); - } - } - - save_basetype = basetype; - type = xtype; - - while (TYPE_HAS_CONVERSION (basetype)) - { - int i; - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - for (i = 0; i < n_variants; i++) - if (typenames[i] != typename - && lookup_fnfields (TYPE_BINFO (basetype), typenames[i], 0)) - return build_type_conversion_1 (xtype, basetype, expr, typenames[i], for_sure); - - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - - if (TREE_CODE (type) == REFERENCE_TYPE) - { - tree first_arg = expr; - type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - basetype = save_basetype; - - /* May need to build a temporary for this. */ - while (TYPE_HAS_CONVERSION (basetype)) - { - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - { - int flags; - - if (for_sure == 0) - { - if (! lvalue_p (expr)) - first_arg = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node); - flags = LOOKUP_PROTECT; - } - else - flags = LOOKUP_NORMAL; - rval = build_method_call (first_arg, constructor_name (typename), - NULL_TREE, NULL_TREE, flags); - if (rval == error_mark_node) - { - if (for_sure == 0) - return NULL_TREE; - return error_mark_node; - } - TREE_VALUE (TREE_OPERAND (rval, 1)) = expr; - - if (IS_AGGR_TYPE (type)) - { - tree init = build_method_call (NULL_TREE, - constructor_name (type), - build_tree_list (NULL_TREE, rval), NULL_TREE, LOOKUP_NORMAL); - tree temp = build_cplus_new (type, init, 1); - return build_up_reference (TYPE_REFERENCE_TO (type), temp, - LOOKUP_COMPLAIN, 1); - } - return convert (xtype, rval); - } - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - /* No free conversions for reference types, right?. */ - return NULL_TREE; - } - - if (exact_conversion) - return NULL_TREE; - - /* No perfect match found, try default. */ - if (code == CONVERT_EXPR && TREE_CODE (type) == POINTER_TYPE) - type_default = ptr_type_node; - else if (type == void_type_node) - return NULL_TREE; - else - { - tree tmp = default_conversion (build1 (NOP_EXPR, type, integer_zero_node)); - if (tmp == error_mark_node) - return NULL_TREE; - type_default = TREE_TYPE (tmp); - } - - basetype = save_basetype; - - if (type_default != type) - { - type = type_default; - typename = build_typename_overload (type); - - while (TYPE_HAS_CONVERSION (basetype)) - { - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - } - - try_pointer: - - if (type == ptr_type_node) - { - /* Try converting to some other pointer type - with which void* is compatible, or in situations - in which void* is appropriate (such as &&,||, and !). */ - - while (TYPE_HAS_CONVERSION (basetype)) - { - if (CLASSTYPE_CONVERSION (basetype, ptr_conv) != 0) - { - if (CLASSTYPE_CONVERSION (basetype, ptr_conv) == error_mark_node) - return error_mark_node; - typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, ptr_conv)); - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - } - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - } - if (TREE_CODE (type) == POINTER_TYPE - && TYPE_READONLY (TREE_TYPE (type)) - && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) - { - /* Try converting to some other pointer type - with which const void* is compatible. */ - - while (TYPE_HAS_CONVERSION (basetype)) - { - if (CLASSTYPE_CONVERSION (basetype, constptr_conv) != 0) - { - if (CLASSTYPE_CONVERSION (basetype, constptr_conv) == error_mark_node) - return error_mark_node; - typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, constptr_conv)); - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - } - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - } - /* Use the longer or shorter conversion that is appropriate. Have - to check against 0 because the conversion may come from a baseclass. */ - if (TREE_CODE (type) == INTEGER_TYPE - && TYPE_HAS_INT_CONVERSION (basetype) - && CLASSTYPE_CONVERSION (basetype, int_conv) != 0 - && CLASSTYPE_CONVERSION (basetype, int_conv) != error_mark_node) - { - typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, int_conv)); - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - } - if (TREE_CODE (type) == REAL_TYPE - && TYPE_HAS_REAL_CONVERSION (basetype) - && CLASSTYPE_CONVERSION (basetype, real_conv) != 0 - && CLASSTYPE_CONVERSION (basetype, real_conv) != error_mark_node) - { - typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, real_conv)); - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - } - - /* THIS IS A KLUDGE. */ - if (TREE_CODE (type) != POINTER_TYPE - && (code == TRUTH_ANDIF_EXPR - || code == TRUTH_ORIF_EXPR - || code == TRUTH_NOT_EXPR)) - { - /* Here's when we can convert to a pointer. */ - type = ptr_type_node; - goto try_pointer; - } - - /* THESE ARE TOTAL KLUDGES. */ - /* Default promotion yields no new alternatives, try - conversions which are anti-default, such as - - double -> float or int -> unsigned or unsigned -> long - - */ - if (type_default == type - && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE)) - { - int not_again = 0; - - if (type == double_type_node) - typename = build_typename_overload (float_type_node); - else if (type == integer_type_node) - typename = build_typename_overload (unsigned_type_node); - else if (type == unsigned_type_node) - typename = build_typename_overload (long_integer_type_node); - - again: - basetype = save_basetype; - while (TYPE_HAS_CONVERSION (basetype)) - { - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else break; - } - if (! not_again) - { - if (type == integer_type_node) - { - typename = build_typename_overload (long_integer_type_node); - not_again = 1; - goto again; - } - else - { - typename = build_typename_overload (integer_type_node); - not_again = 1; - goto again; - } - } - } - - /* Now, try C promotions... - - float -> int - int -> float, void * - void * -> int - - Truthvalue conversions let us try to convert - to pointer if we were going for int, and to int - if we were looking for pointer. */ - - basetype = save_basetype; - if (TREE_CODE (type) == REAL_TYPE - || (TREE_CODE (type) == POINTER_TYPE - && (code == TRUTH_ANDIF_EXPR - || code == TRUTH_ORIF_EXPR - || code == TRUTH_NOT_EXPR))) - type = integer_type_node; - else if (TREE_CODE (type) == INTEGER_TYPE) - if (TYPE_HAS_REAL_CONVERSION (basetype)) - type = double_type_node; - else - return NULL_TREE; - else - return NULL_TREE; - - typename = build_typename_overload (type); - while (TYPE_HAS_CONVERSION (basetype)) - { - if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0)) - { - rval = build_type_conversion_1 (xtype, basetype, expr, typename, for_sure); - return rval; - } - if (TYPE_BINFO_BASETYPES (basetype)) - basetype = TYPE_BINFO_BASETYPE (basetype, 0); - else - break; - } - - return NULL_TREE; -} - -/* Must convert two aggregate types to non-aggregate type. - Attempts to find a non-ambiguous, "best" type conversion. - - Return 1 on success, 0 on failure. - - @@ What are the real semantics of this supposed to be??? */ -int -build_default_binary_type_conversion (code, arg1, arg2) - enum tree_code code; - tree *arg1, *arg2; -{ - tree type1 = TREE_TYPE (*arg1); - tree type2 = TREE_TYPE (*arg2); - char *name1, *name2; - - if (TREE_CODE (type1) == REFERENCE_TYPE) - type1 = TREE_TYPE (type1); - if (TREE_CODE (type2) == REFERENCE_TYPE) - type2 = TREE_TYPE (type2); - - if (TREE_CODE (TYPE_NAME (type1)) != TYPE_DECL) - { - tree decl = typedecl_for_tag (type1); - if (decl) - error ("type conversion nonexistent for type `%s'", - IDENTIFIER_POINTER (DECL_NAME (decl))); - else - error ("type conversion nonexistent for non-C++ type"); - return 0; - } - if (TREE_CODE (TYPE_NAME (type2)) != TYPE_DECL) - { - tree decl = typedecl_for_tag (type2); - if (decl) - error ("type conversion nonexistent for type `%s'", - IDENTIFIER_POINTER (decl)); - else - error ("type conversion nonexistent for non-C++ type"); - return 0; - } - - name1 = TYPE_NAME_STRING (type1); - name2 = TYPE_NAME_STRING (type2); - - if (!IS_AGGR_TYPE (type1) || !TYPE_HAS_CONVERSION (type1)) - { - if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2)) - error ("type conversion required for binary operation on types `%s' and `%s'", - name1, name2); - else - error ("type conversion required for type `%s'", name1); - return 0; - } - else if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2)) - { - error ("type conversion required for type `%s'", name2); - return 0; - } - - if (TYPE_HAS_INT_CONVERSION (type1) && TYPE_HAS_REAL_CONVERSION (type1)) - warning ("ambiguous type conversion for type `%s', defaulting to int", name1); - if (TYPE_HAS_INT_CONVERSION (type1)) - { - *arg1 = build_type_conversion (code, integer_type_node, *arg1, 1); - *arg2 = build_type_conversion (code, integer_type_node, *arg2, 1); - } - else if (TYPE_HAS_REAL_CONVERSION (type1)) - { - *arg1 = build_type_conversion (code, double_type_node, *arg1, 1); - *arg2 = build_type_conversion (code, double_type_node, *arg2, 1); - } - else - { - *arg1 = build_type_conversion (code, ptr_type_node, *arg1, 1); - if (*arg1 == error_mark_node) - error ("ambiguous pointer conversion"); - *arg2 = build_type_conversion (code, ptr_type_node, *arg2, 1); - if (*arg1 != error_mark_node && *arg2 == error_mark_node) - error ("ambiguous pointer conversion"); - } - if (*arg1 == 0) - { - if (*arg2 == 0 && type1 != type2) - error ("default type conversion for types `%s' and `%s' failed", - name1, name2); - else - error ("default type conversion for type `%s' failed", name1); - return 0; - } - else if (*arg2 == 0) - { - error ("default type conversion for type `%s' failed", name2); - return 0; - } - return 1; -} - -/* Must convert two aggregate types to non-aggregate type. - Attempts to find a non-ambiguous, "best" type conversion. - - Return 1 on success, 0 on failure. - - The type of the argument is expected to be of aggregate type here. - - @@ What are the real semantics of this supposed to be??? */ -int -build_default_unary_type_conversion (code, arg) - enum tree_code code; - tree *arg; -{ - tree type = TREE_TYPE (*arg); - tree id = TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - ? TYPE_IDENTIFIER (type) : TYPE_NAME (type); - char *name = IDENTIFIER_POINTER (id); - - if (! TYPE_HAS_CONVERSION (type)) - { - error ("type conversion required for type `%s'", name); - return 0; - } - - if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type)) - warning ("ambiguous type conversion for type `%s', defaulting to int", name); - if (TYPE_HAS_INT_CONVERSION (type)) - *arg = build_type_conversion (code, integer_type_node, *arg, 1); - else if (TYPE_HAS_REAL_CONVERSION (type)) - *arg = build_type_conversion (code, double_type_node, *arg, 1); - else - { - *arg = build_type_conversion (code, ptr_type_node, *arg, 1); - if (*arg == error_mark_node) - error ("ambiguous pointer conversion"); - } - if (*arg == 0) - { - error ("default type conversion for type `%s' failed", name); - return 0; - } - return 1; -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-decl.c b/gnu/usr.bin/gcc2/cc1plus/cp-decl.c deleted file mode 100644 index aa3728af082..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-decl.c +++ /dev/null @@ -1,11554 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-decl.c,v 1.1.1.1 1995/10/18 08:39:30 deraadt Exp $"; -#endif /* not lint */ - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include -#include "config.h" -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "cp-tree.h" -#include "cp-decl.h" -#include "cp-lex.h" -#include -#include -#include "obstack.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern struct obstack permanent_obstack; - -/* Stack of places to restore the search obstack back to. */ - -/* Obstack used for remembering local class declarations (like - enums and static (const) members. */ -#include "stack.h" -static struct obstack decl_obstack; -static struct stack_level *decl_stack; - -#undef NULL -#define NULL (char *)0 - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -/* We let tm.h override the types used here, to handle trivial differences - such as the choice of unsigned int or long unsigned int for size_t. - When machines start needing nontrivial differences in the size type, - it would be best to do something here to figure out automatically - from other information what type to use. */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif - -#define builtin_function(NAME, TYPE, CODE, LIBNAME) \ - define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME) -#define auto_function(NAME, TYPE, CODE) \ - do { \ - tree __name = NAME; \ - tree __type = TYPE; \ - define_function (IDENTIFIER_POINTER (__name), __type, CODE, \ - (void (*)())push_overloaded_decl_1, \ - IDENTIFIER_POINTER (build_decl_overload (__name, TYPE_ARG_TYPES (__type), 0)));\ - } while (0) - -static tree grokparms PROTO((tree, int)); -static tree lookup_nested_type PROTO((tree, tree)); -static char *redeclaration_error_message PROTO((tree, tree)); -static int parmlist_is_random PROTO((tree)); -static void grok_op_properties PROTO((tree, int)); -static void expand_static_init PROTO((tree, tree)); -static void deactivate_exception_cleanups PROTO((void)); - -tree define_function PROTO((char *, tree, enum built_in_function, void (*)(), char *)); - -/* a node which has tree code ERROR_MARK, and whose type is itself. - All erroneous expressions are replaced with this node. All functions - that accept nodes as arguments should avoid generating error messages - if this node is one of the arguments, since it is undesirable to get - multiple error messages from one error in the input. */ - -tree error_mark_node; - -/* Erroneous argument lists can use this *IFF* they do not modify it. */ -tree error_mark_list; - -/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */ - -tree short_integer_type_node; -tree integer_type_node; -tree long_integer_type_node; -tree long_long_integer_type_node; - -tree short_unsigned_type_node; -tree unsigned_type_node; -tree long_unsigned_type_node; -tree long_long_unsigned_type_node; - -tree ptrdiff_type_node; - -tree unsigned_char_type_node; -tree signed_char_type_node; -tree char_type_node; -tree wchar_type_node; -tree signed_wchar_type_node; -tree unsigned_wchar_type_node; - -tree float_type_node; -tree double_type_node; -tree long_double_type_node; - -tree intQI_type_node; -tree intHI_type_node; -tree intSI_type_node; -tree intDI_type_node; - -tree unsigned_intQI_type_node; -tree unsigned_intHI_type_node; -tree unsigned_intSI_type_node; -tree unsigned_intDI_type_node; - -/* a VOID_TYPE node, and the same, packaged in a TREE_LIST. */ - -tree void_type_node, void_list_node; -tree void_zero_node; - -/* Nodes for types `void *' and `const void *'. */ - -tree ptr_type_node, const_ptr_type_node; - -/* Nodes for types `char *' and `const char *'. */ - -tree string_type_node, const_string_type_node; - -/* Type `char[256]' or something like it. - Used when an array of char is needed and the size is irrelevant. */ - -tree char_array_type_node; - -/* Type `int[256]' or something like it. - Used when an array of int needed and the size is irrelevant. */ - -tree int_array_type_node; - -/* Type `wchar_t[256]' or something like it. - Used when a wide string literal is created. */ - -tree wchar_array_type_node; - -/* type `int ()' -- used for implicit declaration of functions. */ - -tree default_function_type; - -/* function types `double (double)' and `double (double, double)', etc. */ - -tree double_ftype_double, double_ftype_double_double; -tree int_ftype_int, long_ftype_long; - -/* Function type `void (void *, void *, int)' and similar ones. */ - -tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int; - -/* Function type `char *(char *, char *)' and similar ones */ -tree string_ftype_ptr_ptr, int_ftype_string_string; - -/* Function type `size_t (const char *)' */ -tree sizet_ftype_string; - -/* Function type `int (const void *, const void *, size_t)' */ -tree int_ftype_cptr_cptr_sizet; - -/* C++ extensions */ -tree vtable_entry_type; -tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node; -tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type; -tree class_star_type_node; -tree class_type_node, record_type_node, union_type_node, enum_type_node; -tree exception_type_node, unknown_type_node; -tree maybe_gc_cleanup; - -/* Used for virtual function tables. */ -tree vtbl_mask; - -/* Array type `(void *)[]' */ -tree vtbl_type_node; - -/* Static decls which do not have static initializers have no - initializers as far as GNU C is concerned. EMPTY_INIT_NODE - is a static initializer which makes varasm code place the decl - in data rather than in bss space. Such gymnastics are necessary - to avoid the problem that the linker will not include a library - file if all the library appears to contribute are bss variables. */ - -tree empty_init_node; - -/* In a destructor, the point at which all derived class destroying - has been done, just before any base class destroying will be done. */ - -tree dtor_label; - -/* In a constructor, the point at which we are ready to return - the pointer to the initialized object. */ - -tree ctor_label; - -/* A FUNCTION_DECL which can call `unhandled_exception'. - Not necessarily the one that the user will declare, - but sufficient to be called by routines that want to abort the program. */ - -tree unhandled_exception_fndecl; - -/* A FUNCTION_DECL which can call `abort'. Not necessarily the - one that the user will declare, but sufficient to be called - by routines that want to abort the program. */ - -tree abort_fndecl; - -extern rtx cleanup_label, return_label; - -/* If original DECL_RESULT of current function was a register, - but due to being an addressable named return value, would up - on the stack, this variable holds the named return value's - original location. */ -rtx original_result_rtx; - -/* Sequence of insns which represents base initialization. */ -rtx base_init_insns; - -/* C++: Keep these around to reduce calls to `get_identifier'. - Identifiers for `this' in member functions and the auto-delete - parameter for destructors. */ -tree this_identifier, in_charge_identifier; - -/* A list (chain of TREE_LIST nodes) of named label uses. - The TREE_PURPOSE field is the list of variables defined - the the label's scope defined at the point of use. - The TREE_VALUE field is the LABEL_DECL used. - The TREE_TYPE field holds `current_binding_level' at the - point of the label's use. - - Used only for jumps to as-yet undefined labels, since - jumps to defined labels can have their validity checked - by stmt.c. */ - -static tree named_label_uses; - -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -tree static_aggregates; - -/* A list of functions which were declared inline, but later had their - address taken. Used only for non-virtual member functions, since we can - find other functions easily enough. */ -tree pending_addressable_inlines; - -/* A list of overloaded functions which we should forget ever - existed, such as functions declared in a function's scope, - once we leave that function's scope. */ -static tree overloads_to_forget; - -/* -- end of C++ */ - -/* Two expressions that are constants with value zero. - The first is of type `int', the second of type `void *'. */ - -tree integer_zero_node; -tree null_pointer_node; - -/* A node for the integer constants 1, 2, and 3. */ - -tree integer_one_node, integer_two_node, integer_three_node; - -/* Nonzero if we have seen an invalid cross reference - to a struct, union, or enum, but not yet printed the message. */ - -tree pending_invalid_xref; -/* File and line to appear in the eventual error message. */ -char *pending_invalid_xref_file; -int pending_invalid_xref_line; - -/* While defining an enum type, this is 1 plus the last enumerator - constant value. */ - -static tree enum_next_value; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ - -tree last_function_parms; - -/* Parsing a function declarator leaves here a chain of structure - and enum types declared in the parmlist. */ - -static tree last_function_parm_tags; - -/* After parsing the declarator that starts a function definition, - `start_function' puts here the list of parameter names or chain of decls. - `store_parm_decls' finds it here. */ - -static tree current_function_parms; - -/* Similar, for last_function_parm_tags. */ -static tree current_function_parm_tags; - -/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function - that have names. Here so we can clear out their names' definitions - at the end of the function. */ - -static tree named_labels; - -/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ - -static tree shadowed_labels; - -#if 0 /* Not needed by C++ */ -/* Nonzero when store_parm_decls is called indicates a varargs function. - Value not meaningful after store_parm_decls. */ - -static int c_function_varargs; -#endif - -/* The FUNCTION_DECL for the function currently being compiled, - or 0 if between functions. */ -tree current_function_decl; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement that specifies a return value is seen. */ - -int current_function_returns_value; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement with no argument is seen. */ - -int current_function_returns_null; - -/* Set to 0 at beginning of a function definition, and whenever - a label (case or named) is defined. Set to value of expression - returned from function when that value can be transformed into - a named return value. */ - -tree current_function_return_value; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -extern int warn_redundant_decls; - -/* Set to nonzero by `grokdeclarator' for a function - whose return type is defaulted, if warnings for this are desired. */ - -static int warn_about_return_type; - -/* Nonzero when starting a function declared `extern inline'. */ - -static int current_extern_inline; - -/* Nonzero means give `double' the same size as `float'. */ - -extern int flag_short_double; - -/* Nonzero means don't recognize any builtin functions. */ - -extern int flag_no_builtin; - -/* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - -extern int flag_implement_inlines; - -/* Nonzero means handle things in ANSI, instead of GNU fashion. This - flag should be tested for language behavior that's different between - ANSI and GNU, but not so horrible as to merit a PEDANTIC label. */ - -extern int flag_ansi; - -/* Pointers to the base and current top of the language name stack. */ - -extern tree *current_lang_base, *current_lang_stack; - -/* C and C++ flags are in cp-decl2.c. */ - -/* Set to 0 at beginning of a constructor, set to 1 - if that function does an allocation before referencing its - instance variable. */ -int current_function_assigns_this; -int current_function_just_assigned_this; - -/* Set to 0 at beginning of a function. Set non-zero when - store_parm_decls is called. Don't call store_parm_decls - if this flag is non-zero! */ -int current_function_parms_stored; - -/* Current end of entries in the gc obstack for stack pointer variables. */ - -int current_function_obstack_index; - -/* Flag saying whether we have used the obstack in this function or not. */ - -int current_function_obstack_usage; - -/* Flag used when debugging cp-spew.c */ - -extern int spew_debug; - -/* Allocate a level of searching. */ -struct stack_level * -push_decl_level (stack, obstack) - struct stack_level *stack; - struct obstack *obstack; -{ - struct stack_level tem; - tem.prev = stack; - - return push_stack_level (obstack, (char *)&tem, sizeof (tem)); -} - -/* Discard a level of decl allocation. */ - -static struct stack_level * -pop_decl_level (stack) - struct stack_level *stack; -{ - tree *bp, *tp; - struct obstack *obstack = stack->obstack; - bp = stack->first; - tp = (tree *)obstack_next_free (obstack); - while (tp != bp) - { - --tp; - if (*tp != NULL_TREE) - IDENTIFIER_CLASS_VALUE (DECL_NAME (*tp)) = NULL_TREE; - } - return pop_stack_level (stack); -} - -/* For each binding contour we allocate a binding_level structure - * which records the names defined in that contour. - * Contours include: - * 0) the global one - * 1) one for each function definition, - * where internal declarations of the parameters appear. - * 2) one for each compound statement, - * to record its declarations. - * - * The current meaning of a name can be found by searching the levels from - * the current one out to the global one. - * - * Off to the side, may be the class_binding_level. This exists - * only to catch class-local declarations. It is otherwise - * nonexistent. - * - * Also there may be binding levels that catch cleanups that - * must be run when exceptions occur. - */ - -/* Note that the information in the `names' component of the global contour - is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ - -struct binding_level - { - /* A chain of _DECL nodes for all variables, constants, functions, - * and typedef types. These are in the reverse of the order supplied. - */ - tree names; - - /* A list of structure, union and enum definitions, - * for looking up tag names. - * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, - * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, - * or ENUMERAL_TYPE node. - * - * C++: the TREE_VALUE nodes can be simple types for component_bindings. - * - */ - tree tags; - - /* For each level, a list of shadowed outer-level local definitions - to be restored when this level is popped. - Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and - whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ - tree shadowed; - - /* Same, for IDENTIFIER_CLASS_VALUE. */ - tree class_shadowed; - - /* Same, for IDENTIFIER_TYPE_VALUE. */ - tree type_shadowed; - - /* For each level (except not the global one), - a chain of BLOCK nodes for all the levels - that were entered and exited one level down. */ - tree blocks; - - /* The BLOCK node for this level, if one has been preallocated. - If 0, the BLOCK is allocated (if needed) when the level is popped. */ - tree this_block; - - /* The binding level which this one is contained in (inherits from). */ - struct binding_level *level_chain; - - /* Number of decls in `names' that have incomplete - structure or union types. */ - unsigned short n_incomplete; - - /* 1 for the level that holds the parameters of a function. - 2 for the level that holds a class declaration. - 3 for levels that hold parameter declarations. */ - unsigned parm_flag : 4; - - /* 1 means make a BLOCK for this level regardless of all else. - 2 for temporary binding contours created by the compiler. */ - unsigned keep : 3; - - /* Nonzero if this level "doesn't exist" for tags. */ - unsigned tag_transparent : 1; - - /* Nonzero if this level can safely have additional - cleanup-needing variables added to it. */ - unsigned more_cleanups_ok : 1; - unsigned have_cleanups : 1; - - /* Nonzero if this level can safely have additional - exception-raising statements added to it. */ - unsigned more_exceptions_ok : 1; - unsigned have_exceptions : 1; - - /* Nonzero if we should accept any name as an identifier in - this scope. This happens in some template definitions. */ - unsigned accept_any : 1; - - /* Nonzero if this level is for completing a template class definition - inside a binding level that temporarily binds the parameters. This - means that definitions here should not be popped off when unwinding - this binding level. (Not actually implemented this way, - unfortunately.) */ - unsigned pseudo_global : 1; - - /* Two bits left for this word. */ - -#if PARANOID - unsigned char depth; -#endif - }; - -#define NULL_BINDING_LEVEL (struct binding_level *) NULL - -/* The binding level currently in effect. */ - -static struct binding_level *current_binding_level; - -/* The binding level of the current class, if any. */ - -static struct binding_level *class_binding_level; - -/* A chain of binding_level structures awaiting reuse. */ - -static struct binding_level *free_binding_level; - -/* The outermost binding level, for names of file scope. - This is created when the compiler is started and exists - through the entire run. */ - -static struct binding_level *global_binding_level; - -/* Binding level structures are initialized by copying this one. */ - -static struct binding_level clear_binding_level; - -/* Nonzero means unconditionally make a BLOCK for the next level pushed. */ - -static int keep_next_level_flag; - -#if PARANOID -/* Perform sanity checking on binding levels. Normally not needed. */ -void -binding_levels_sane () -{ - struct binding_level *b = current_binding_level; - static int n; - if (++n < 3) - return; - my_friendly_assert (global_binding_level != 0, 126); - my_friendly_assert (current_binding_level != 0, 127); - for (b = current_binding_level; b != global_binding_level; b = b->level_chain) - { - my_friendly_assert (b->level_chain != 0, 128); - my_friendly_assert (b->depth == 1 + b->level_chain->depth, 129); - } - if (class_binding_level) - for (b = class_binding_level; - b != global_binding_level && b != current_binding_level; - b = b->level_chain) - { - my_friendly_assert (b->level_chain != 0, 130); - my_friendly_assert (b->depth == 1 + b->level_chain->depth, 131); - } - my_friendly_assert (global_binding_level->depth == 0, 132); - my_friendly_assert (global_binding_level->level_chain == 0, 133); - return; -} - -#else -#define binding_levels_sane() ((void)(1)) -#endif - -#ifdef DEBUG_CP_BINDING_LEVELS -int debug_bindings_indentation; -#endif - -static void -#if !PARANOID && defined (__GNUC__) -__inline -#endif -push_binding_level (newlevel, tag_transparent, keep) - struct binding_level *newlevel; - int tag_transparent, keep; -{ - binding_levels_sane(); - /* Add this level to the front of the chain (stack) of levels that - are active. */ -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushing binding level "); - fprintf (stderr, HOST_PTR_PRINTF, newlevel); - fprintf (stderr, "\n"); -#endif - *newlevel = clear_binding_level; - if (class_binding_level) - { - newlevel->level_chain = class_binding_level; - class_binding_level = (struct binding_level *)0; - } - else - { - newlevel->level_chain = current_binding_level; - } - current_binding_level = newlevel; - newlevel->tag_transparent = tag_transparent; - newlevel->more_cleanups_ok = 1; - newlevel->more_exceptions_ok = 1; - newlevel->keep = keep; -#if PARANOID - newlevel->depth = (newlevel->level_chain - ? newlevel->level_chain->depth + 1 - : 0); -#endif - binding_levels_sane(); -} - -static void -#if !PARANOID && defined (__GNUC__) -__inline -#endif -pop_binding_level () -{ - binding_levels_sane(); -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "popping binding level "); - fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); - fprintf (stderr, "\n"); -#endif - if (global_binding_level) - { - /* cannot pop a level, if there are none left to pop. */ - if (current_binding_level == global_binding_level) - my_friendly_abort (123); - } - /* Pop the current level, and free the structure for reuse. */ - { - register struct binding_level *level = current_binding_level; - current_binding_level = current_binding_level->level_chain; - level->level_chain = free_binding_level; -#ifdef DEBUG_CP_BINDING_LEVELS - memset (level, 0x69, sizeof (*level)); -#else - free_binding_level = level; -#if PARANOID - level->depth = ~0; /* ~0 assumes that the depth is unsigned. */ -#endif -#endif - if (current_binding_level->parm_flag == 2) - { - class_binding_level = current_binding_level; - do - { - current_binding_level = current_binding_level->level_chain; - } - while (current_binding_level->parm_flag == 2); - } - } - binding_levels_sane(); -} - -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p () -{ - return current_binding_level == global_binding_level; -} - -void -keep_next_level () -{ - keep_next_level_flag = 1; -} - -/* Nonzero if the current level needs to have a BLOCK made. */ - -int -kept_level_p () -{ - return (current_binding_level->blocks != NULL_TREE - || current_binding_level->keep - || current_binding_level->names != NULL_TREE - || (current_binding_level->tags != NULL_TREE - && !current_binding_level->tag_transparent)); -} - -/* Identify this binding level as a level of parameters. */ - -void -declare_parm_level () -{ - current_binding_level->parm_flag = 1; -} - -/* Identify this binding level as a level of a default exception handler. */ - -void -declare_implicit_exception () -{ - current_binding_level->parm_flag = 3; -} - -/* Nonzero if current binding contour contains expressions - that might raise exceptions. */ - -int -have_exceptions_p () -{ - return current_binding_level->have_exceptions; -} - -void -declare_uninstantiated_type_level () -{ - current_binding_level->accept_any = 1; -} - -int -uninstantiated_type_level_p () -{ - return current_binding_level->accept_any; -} - -void -declare_pseudo_global_level () -{ - current_binding_level->pseudo_global = 1; -} - -int -pseudo_global_level_p () -{ - return current_binding_level->pseudo_global; -} - -/* Enter a new binding level. - If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, - not for that of tags. */ - -void -pushlevel (tag_transparent) - int tag_transparent; -{ - register struct binding_level *newlevel = NULL_BINDING_LEVEL; - -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushlevel"); - debug_bindings_indentation += 4; -#endif - - /* If this is the top level of a function, - just make sure that NAMED_LABELS is 0. - They should have been set to 0 at the end of the previous function. */ - - if (current_binding_level == global_binding_level) - my_friendly_assert (named_labels == NULL_TREE, 134); - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - /* Create a new `struct binding_level'. */ - newlevel = (struct binding_level *) xmalloc (sizeof (struct binding_level)); - } - push_binding_level (newlevel, tag_transparent, keep_next_level_flag); - GNU_xref_start_scope ((int) newlevel); - keep_next_level_flag = 0; - -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif -} - -void -pushlevel_temporary (tag_transparent) - int tag_transparent; -{ - pushlevel (tag_transparent); - current_binding_level->keep = 2; - clear_last_expr (); - - /* Note we don't call push_momentary() here. Otherwise, it would cause - cleanups to be allocated on the momentary obstack, and they will be - overwritten by the next statement. */ - - expand_start_bindings (0); -} - -/* Exit a binding level. - Pop the level off, and restore the state of the identifier-decl mappings - that were in effect when this level was entered. - - If KEEP == 1, this level had explicit declarations, so - and create a "block" (a BLOCK node) for the level - to record its declarations and subblocks for symbol table output. - - If KEEP == 2, this level's subblocks go to the front, - not the back of the current binding level. This happens, - for instance, when code for constructors and destructors - need to generate code at the end of a function which must - be moved up to the front of the function. - - If FUNCTIONBODY is nonzero, this level is the body of a function, - so create a block as if KEEP were set and also clear out all - label names. - - If REVERSE is nonzero, reverse the order of decls before putting - them into the BLOCK. */ - -tree -poplevel (keep, reverse, functionbody) - int keep; - int reverse; - int functionbody; -{ - register tree link; - /* The chain of decls was accumulated in reverse order. - Put it into forward order, just for cleanliness. */ - tree decls; - int tmp = functionbody; - int implicit_try_block = current_binding_level->parm_flag == 3; - int real_functionbody = current_binding_level->keep == 2 - ? ((functionbody = 0), tmp) : functionbody; - tree tags = functionbody >= 0 ? current_binding_level->tags : 0; - tree subblocks = functionbody >= 0 ? current_binding_level->blocks : 0; - tree block = NULL_TREE; - tree decl; - int block_previously_created; - -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "poplevel"); - debug_bindings_indentation += 4; -#endif - - binding_levels_sane(); - GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, - (HOST_WIDE_INT) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep, - current_binding_level->tag_transparent); - - if (current_binding_level->keep == 1) - keep = 1; - - /* This warning is turned off because it causes warnings for - declarations like `extern struct foo *x'. */ -#if 0 - /* Warn about incomplete structure types in this level. */ - for (link = tags; link; link = TREE_CHAIN (link)) - if (TYPE_SIZE (TREE_VALUE (link)) == NULL_TREE) - { - tree type = TREE_VALUE (link); - char *errmsg; - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - errmsg = "`struct %s' incomplete in scope ending here"; - break; - case UNION_TYPE: - errmsg = "`union %s' incomplete in scope ending here"; - break; - case ENUMERAL_TYPE: - errmsg = "`enum %s' incomplete in scope ending here"; - break; - } - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error (errmsg, TYPE_NAME_STRING (type)); - } -#endif /* 0 */ - - /* Get the decls in the order they were written. - Usually current_binding_level->names is in reverse order. - But parameter decls were previously put in forward order. */ - - if (reverse) - current_binding_level->names - = decls = nreverse (current_binding_level->names); - else - decls = current_binding_level->names; - - /* Output any nested inline functions within this block - if they weren't already output. */ - - for (decl = decls; decl; decl = TREE_CHAIN (decl)) - if (TREE_CODE (decl) == FUNCTION_DECL - && ! TREE_ASM_WRITTEN (decl) - && DECL_INITIAL (decl) != NULL_TREE - && TREE_ADDRESSABLE (decl)) - { - /* If this decl was copied from a file-scope decl - on account of a block-scope extern decl, - propagate TREE_ADDRESSABLE to the file-scope decl. */ - if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE) - TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else - output_inline_function (decl); - } - - /* If there were any declarations or structure tags in that level, - or if this level is a function body, - create a BLOCK to record them for the life of this function. */ - - block = NULL_TREE; - block_previously_created = (current_binding_level->this_block != NULL_TREE); - if (block_previously_created) - block = current_binding_level->this_block; - else if (keep == 1 || functionbody) - block = make_node (BLOCK); - if (block != NULL_TREE) - { - BLOCK_VARS (block) = decls; - BLOCK_TYPE_TAGS (block) = tags; - BLOCK_SUBBLOCKS (block) = subblocks; - remember_end_note (block); - } - - /* In each subblock, record that this is its superior. */ - - if (keep >= 0) - for (link = subblocks; link; link = TREE_CHAIN (link)) - BLOCK_SUPERCONTEXT (link) = block; - - /* Clear out the meanings of the local variables of this level. */ - - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != NULL_TREE) - { - /* If the ident. was used or addressed via a local extern decl, - don't forget that fact. */ - if (DECL_EXTERNAL (link)) - { - if (TREE_USED (link)) - TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1; - if (TREE_ADDRESSABLE (link)) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; - } - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE; - } - } - - /* Restore all name-meanings of the outer levels - that were shadowed by this level. */ - - for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->class_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->type_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - - /* If the level being exited is the top level of a function, - check over all the labels. */ - - if (functionbody) - { - /* If this is the top level block of a function, - the vars are the function's parameters. - Don't leave them in the BLOCK because they are - found in the FUNCTION_DECL instead. */ - - BLOCK_VARS (block) = 0; - - /* Clear out the definitions of all label names, - since their scopes end here. */ - - for (link = named_labels; link; link = TREE_CHAIN (link)) - { - register tree label = TREE_VALUE (link); - - if (DECL_INITIAL (label) == NULL_TREE) - { - error_with_decl (label, "label `%s' used but not defined"); - /* Avoid crashing later. */ - define_label (input_filename, 1, DECL_NAME (label)); - } - else if (warn_unused && !TREE_USED (label)) - warning_with_decl (label, - "label `%s' defined but not used"); - SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), 0); - - /* Put the labels into the "variables" of the - top-level block, so debugger can see them. */ - TREE_CHAIN (label) = BLOCK_VARS (block); - BLOCK_VARS (block) = label; - } - - named_labels = NULL_TREE; - } - - /* Any uses of undefined labels now operate under constraints - of next binding contour. */ - { - struct binding_level *level_chain; - level_chain = current_binding_level->level_chain; - if (level_chain) - { - tree labels; - for (labels = named_label_uses; labels; labels = TREE_CHAIN (labels)) - if (TREE_TYPE (labels) == (tree)current_binding_level) - { - TREE_TYPE (labels) = (tree)level_chain; - TREE_PURPOSE (labels) = level_chain->names; - } - } - } - - tmp = current_binding_level->keep; - - pop_binding_level (); - if (functionbody) - DECL_INITIAL (current_function_decl) = block; - else if (block) - { - if (!block_previously_created) - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); - } - - /* If we did not make a block for the level just exited, - any blocks made for inner levels - (since they cannot be recorded as subblocks in that level) - must be carried forward so they will later become subblocks - of something else. */ - else if (subblocks) - if (keep == 2) - current_binding_level->blocks = chainon (subblocks, current_binding_level->blocks); - else - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - /* Take care of compiler's internal binding structures. */ - if (tmp == 2 && !implicit_try_block) - { -#if 0 - /* We did not call push_momentary for this - binding contour, so there is nothing to pop. */ - pop_momentary (); -#endif - expand_end_bindings (getdecls (), keep, 1); - block = poplevel (keep, reverse, real_functionbody); - } - if (block) - TREE_USED (block) = 1; - binding_levels_sane(); -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif - return block; -} - -/* Delete the node BLOCK from the current binding level. - This is used for the block inside a stmt expr ({...}) - so that the block can be reinserted where appropriate. */ - -void -delete_block (block) - tree block; -{ - tree t; - if (current_binding_level->blocks == block) - current_binding_level->blocks = TREE_CHAIN (block); - for (t = current_binding_level->blocks; t;) - { - if (TREE_CHAIN (t) == block) - TREE_CHAIN (t) = TREE_CHAIN (block); - else - t = TREE_CHAIN (t); - } - TREE_CHAIN (block) = NULL_TREE; - /* Clear TREE_USED which is always set by poplevel. - The flag is set again if insert_block is called. */ - TREE_USED (block) = 0; -} - -/* Insert BLOCK at the end of the list of subblocks of the - current binding level. This is used when a BIND_EXPR is expanded, - to handle the BLOCK node inside the BIND_EXPR. */ - -void -insert_block (block) - tree block; -{ - TREE_USED (block) = 1; - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -/* Add BLOCK to the current list of blocks for this binding contour. */ -void -add_block_current_level (block) - tree block; -{ - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -/* Set the BLOCK node for the innermost scope - (the one we are currently in). */ - -void -set_block (block) - register tree block; -{ - current_binding_level->this_block = block; -} - -/* Do a pushlevel for class declarations. */ -void -pushlevel_class () -{ - binding_levels_sane(); -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "pushlevel_class"); - debug_bindings_indentation += 4; -#endif - pushlevel (0); - decl_stack = push_decl_level (decl_stack, &decl_obstack); - class_binding_level = current_binding_level; - class_binding_level->parm_flag = 2; - do - { - current_binding_level = current_binding_level->level_chain; - } - while (current_binding_level->parm_flag == 2); - binding_levels_sane(); -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif -} - -/* ...and a poplevel for class declarations. */ -tree -poplevel_class () -{ - register struct binding_level *level = class_binding_level; - tree block = NULL_TREE; - tree shadowed; - -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "poplevel_class"); - debug_bindings_indentation += 4; -#endif - binding_levels_sane(); - if (level == (struct binding_level *)0) - { - while (current_binding_level && class_binding_level == (struct binding_level *)0) - block = poplevel (0, 0, 0); - if (current_binding_level == (struct binding_level *)0) - fatal ("syntax error too serious"); - level = class_binding_level; - } - decl_stack = pop_decl_level (decl_stack); - for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); - for (shadowed = level->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); - for (shadowed = level->type_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); - - GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level, - (HOST_WIDE_INT) class_binding_level->level_chain, - class_binding_level->parm_flag, - class_binding_level->keep, - class_binding_level->tag_transparent); - - class_binding_level = level->level_chain; - if (class_binding_level->parm_flag != 2) - class_binding_level = (struct binding_level *)0; - -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "popping class binding level "); - fprintf (stderr, HOST_PTR_PRINTF, level); - fprintf (stderr, "\n"); - memset (level, 0x69, sizeof (*level)); - debug_bindings_indentation -= 4; -#else - level->level_chain = free_binding_level; - free_binding_level = level; -#endif - binding_levels_sane(); - - return block; -} - -/* For debugging. */ -int no_print_functions = 0; -int no_print_builtins = 0; - -void -print_binding_level (lvl) - struct binding_level *lvl; -{ - tree t; - int i = 0, len; - fprintf (stderr, " blocks="); - fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks); - fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d", - lvl->n_incomplete, lvl->parm_flag, lvl->keep); - if (lvl->tag_transparent) - fprintf (stderr, " tag-transparent"); - if (lvl->more_cleanups_ok) - fprintf (stderr, " more-cleanups-ok"); - if (lvl->have_cleanups) - fprintf (stderr, " have-cleanups"); - if (lvl->more_exceptions_ok) - fprintf (stderr, " more-exceptions-ok"); - if (lvl->have_exceptions) - fprintf (stderr, " have-exceptions"); - fprintf (stderr, "\n"); - if (lvl->names) - { - fprintf (stderr, " names:\t"); - /* We can probably fit 3 names to a line? */ - for (t = lvl->names; t; t = TREE_CHAIN (t)) - { - if (no_print_functions && (TREE_CODE(t) == FUNCTION_DECL)) - continue; - if (no_print_builtins - && (TREE_CODE(t) == TYPE_DECL) - && (!strcmp(DECL_SOURCE_FILE(t),""))) - continue; - - /* Function decls tend to have longer names. */ - if (TREE_CODE (t) == FUNCTION_DECL) - len = 3; - else - len = 2; - i += len; - if (i > 6) - { - fprintf (stderr, "\n\t"); - i = len; - } - print_node_brief (stderr, "", t, 0); - if (TREE_CODE (t) == ERROR_MARK) - break; - } - if (i) - fprintf (stderr, "\n"); - } - if (lvl->tags) - { - fprintf (stderr, " tags:\t"); - i = 0; - for (t = lvl->tags; t; t = TREE_CHAIN (t)) - { - if (TREE_PURPOSE (t) == NULL_TREE) - len = 3; - else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) - len = 2; - else - len = 4; - i += len; - if (i > 5) - { - fprintf (stderr, "\n\t"); - i = len; - } - if (TREE_PURPOSE (t) == NULL_TREE) - { - print_node_brief (stderr, ""); - } - else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) - print_node_brief (stderr, "", TREE_VALUE (t), 0); - else - { - print_node_brief (stderr, ""); - } - } - if (i) - fprintf (stderr, "\n"); - } - if (lvl->shadowed) - { - fprintf (stderr, " shadowed:"); - for (t = lvl->shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } - if (lvl->class_shadowed) - { - fprintf (stderr, " class-shadowed:"); - for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } - if (lvl->type_shadowed) - { - fprintf (stderr, " type-shadowed:"); - for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) - { -#if 0 - fprintf (stderr, "\n\t"); - print_node_brief (stderr, "<", TREE_PURPOSE (t), 0); - if (TREE_VALUE (t)) - print_node_brief (stderr, " ", TREE_VALUE (t), 0); - else - fprintf (stderr, " (none)"); - fprintf (stderr, ">"); -#else - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); -#endif - } - fprintf (stderr, "\n"); - } -} - -void -print_other_binding_stack (stack) - struct binding_level *stack; -{ - struct binding_level *level; - for (level = stack; level != global_binding_level; level = level->level_chain) - { - fprintf (stderr, "binding level "); - fprintf (stderr, HOST_PTR_PRINTF, level); - fprintf (stderr, "\n"); - print_binding_level (level); - } -} - -void -print_binding_stack () -{ - struct binding_level *b; - fprintf (stderr, "current_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); - fprintf (stderr, "\nclass_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, class_binding_level); - fprintf (stderr, "\nglobal_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, global_binding_level); - fprintf (stderr, "\n"); - if (class_binding_level) - { - for (b = class_binding_level; b; b = b->level_chain) - if (b == current_binding_level) - break; - if (b) - b = class_binding_level; - else - b = current_binding_level; - } - else - b = current_binding_level; - print_other_binding_stack (b); - fprintf (stderr, "global:\n"); - print_binding_level (global_binding_level); -} - -/* Subroutines for reverting temporarily to top-level for instantiation - of templates and such. We actually need to clear out the class- and - local-value slots of all identifiers, so that only the global values - are at all visible. Simply setting current_binding_level to the global - scope isn't enough, because more binding levels may be pushed. */ -struct saved_scope { - struct binding_level *old_binding_level; - tree old_bindings; - struct saved_scope *prev; - tree class_name, class_type, class_decl, function_decl; - struct binding_level *class_bindings; -}; -static struct saved_scope *current_saved_scope; -extern tree prev_class_type; - -void -push_to_top_level () -{ - struct saved_scope *s = - (struct saved_scope *) xmalloc (sizeof (struct saved_scope)); - struct binding_level *b = current_binding_level; - tree old_bindings = NULL_TREE; - -#ifdef DEBUG_CP_BINDING_LEVELS - fprintf (stderr, "PUSH_TO_TOP_LEVEL\n"); -#endif - - /* Have to include global_binding_level, because class-level decls - aren't listed anywhere useful. */ - for (; b; b = b->level_chain) - { - tree t; - for (t = b->names; t; t = TREE_CHAIN (t)) - if (b != global_binding_level) - { - tree binding, t1, t2 = t; - tree id = DECL_ASSEMBLER_NAME (t2); - - if (!id - || (!IDENTIFIER_LOCAL_VALUE (id) - && !IDENTIFIER_CLASS_VALUE (id))) - continue; - - for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1)) - if (TREE_VEC_ELT (t1, 0) == id) - goto skip_it; - - binding = make_tree_vec (4); - if (id) - { - my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); - TREE_VEC_ELT (binding, 0) = id; - TREE_VEC_ELT (binding, 1) = IDENTIFIER_TYPE_VALUE (id); - TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id); - TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); - IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE; - IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; - adjust_type_value (id); - } - TREE_CHAIN (binding) = old_bindings; - old_bindings = binding; - skip_it: - ; - } - /* Unwind type-value slots back to top level. */ - if (b != global_binding_level) - for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); - } - - s->old_binding_level = current_binding_level; - current_binding_level = global_binding_level; - - s->class_name = current_class_name; - s->class_type = current_class_type; - s->class_decl = current_class_decl; - s->function_decl = current_function_decl; - s->class_bindings = class_binding_level; - current_class_name = current_class_type = current_class_decl = NULL_TREE; - current_function_decl = NULL_TREE; - class_binding_level = (struct binding_level *)0; - - s->prev = current_saved_scope; - s->old_bindings = old_bindings; - current_saved_scope = s; - binding_levels_sane(); -} - -void -pop_from_top_level () -{ - struct saved_scope *s = current_saved_scope; - tree t; - -#ifdef DEBUG_CP_BINDING_LEVELS - fprintf (stderr, "POP_FROM_TOP_LEVEL\n"); -#endif - - binding_levels_sane(); - current_binding_level = s->old_binding_level; - current_saved_scope = s->prev; - for (t = s->old_bindings; t; t = TREE_CHAIN (t)) - { - tree id = TREE_VEC_ELT (t, 0); - if (id) - { - IDENTIFIER_TYPE_VALUE (id) = TREE_VEC_ELT (t, 1); - IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2); - IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3); - } - } - current_class_name = s->class_name; - current_class_type = s->class_type; - current_class_decl = s->class_decl; - if (current_class_type) - C_C_D = CLASSTYPE_INST_VAR (current_class_type); - else - C_C_D = NULL_TREE; - current_function_decl = s->function_decl; - class_binding_level = s->class_bindings; - free (s); - binding_levels_sane(); -} - -/* Push a definition of struct, union or enum tag "name". - "type" should be the type node. - We assume that the tag "name" is not already defined. - - Note that the definition may really be just a forward reference. - In that case, the TYPE_SIZE will be a NULL_TREE. - - C++ gratuitously puts all these tags in the name space. */ - -/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID, - record the shadowed value for this binding contour. TYPE is - the type that ID maps to. */ -void -set_identifier_type_value (id, type) - tree id; - tree type; -{ - if (current_binding_level != global_binding_level) - { - tree old_type_value = IDENTIFIER_TYPE_VALUE (id); - current_binding_level->type_shadowed - = tree_cons (id, old_type_value, current_binding_level->type_shadowed); - } - else if (class_binding_level) - { - tree old_type_value = IDENTIFIER_TYPE_VALUE (id); - class_binding_level->type_shadowed - = tree_cons (id, old_type_value, class_binding_level->type_shadowed); - } - SET_IDENTIFIER_TYPE_VALUE (id, type); -} - -/* - * local values can need to be shadowed too, but it only happens - * explicitly from pushdecl, in support of nested enums. - */ -void -set_identifier_local_value (id, type) - tree id; - tree type; -{ - if (current_binding_level != global_binding_level) - { - tree old_local_value = IDENTIFIER_LOCAL_VALUE (id); - current_binding_level->shadowed - = tree_cons (id, old_local_value, current_binding_level->shadowed); - } - else if (class_binding_level) - { - tree old_local_value = IDENTIFIER_LOCAL_VALUE (id); - class_binding_level->shadowed - = tree_cons (id, old_local_value, class_binding_level->shadowed); - } - IDENTIFIER_LOCAL_VALUE (id) = type; -} - -/* Subroutine "set_nested_typename" builds the nested-typename of - the type decl in question. (Argument CLASSNAME can actually be - a function as well, if that's the smallest containing scope.) */ - -static void -set_nested_typename (decl, classname, name, type) - tree decl, classname, name, type; -{ - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 136); - if (classname != NULL_TREE) - { - char *buf; - my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 137); - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 138); - buf = (char *) alloca (4 + IDENTIFIER_LENGTH (classname) - + IDENTIFIER_LENGTH (name)); - sprintf (buf, "%s::%s", IDENTIFIER_POINTER (classname), - IDENTIFIER_POINTER (name)); - DECL_NESTED_TYPENAME (decl) = get_identifier (buf); - SET_IDENTIFIER_TYPE_VALUE (DECL_NESTED_TYPENAME (decl), type); - } - else - DECL_NESTED_TYPENAME (decl) = name; -} - -#if 0 /* not yet, should get fixed properly later */ -/* Create a TYPE_DECL node with the correct DECL_ASSEMBLER_NAME. - Other routines shouldn't use build_decl directly; they'll produce - incorrect results with `-g' unless they duplicate this code. - - This is currently needed mainly for dbxout.c, but we can make - use of it in cp-method.c later as well. */ -tree -make_type_decl (name, type) - tree name, type; -{ - tree decl, id; - decl = build_decl (TYPE_DECL, name, type); - if (TYPE_NAME (type) == name) - /* Class/union/enum definition, or a redundant typedef for same. */ - { - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (decl) = id; - } - else if (TYPE_NAME (type) != NULL_TREE) - /* Explicit typedef, or implicit typedef for template expansion. */ - DECL_ASSEMBLER_NAME (decl) = DECL_ASSEMBLER_NAME (TYPE_NAME (type)); - else - { - /* Typedef for unnamed struct; some other situations. - TYPE_NAME is null; what's right here? */ - } - return decl; -} - -#endif -void -pushtag (name, type) - tree name, type; -{ - register struct binding_level *b; - - if (class_binding_level) - b = class_binding_level; - else - { - b = current_binding_level; - while (b->tag_transparent) b = b->level_chain; - } - - if (b == global_binding_level) - b->tags = perm_tree_cons (name, type, b->tags); - else - b->tags = saveable_tree_cons (name, type, b->tags); - - if (name) - { - /* Record the identifier as the type's name if it has none. */ - - if (TYPE_NAME (type) == NULL_TREE) - TYPE_NAME (type) = name; - - /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type - && (TREE_CODE (type) != RECORD_TYPE - || class_binding_level == (struct binding_level *)0 - || !CLASSTYPE_DECLARED_EXCEPTION (type))) - { - register tree d; - if (current_class_type == NULL_TREE - || TYPE_SIZE (current_class_type) != NULL_TREE) - { - if (current_lang_name == lang_name_cplusplus) - d = lookup_nested_type (type, current_class_type ? TYPE_NAME (current_class_type) : NULL_TREE); - else - d = NULL_TREE; - - if (d == NULL_TREE) - { -#if 0 /* not yet, should get fixed properly later */ - d = make_type_decl (name, type); - DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); -#else - d = build_decl (TYPE_DECL, name, type); - DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); -#endif - /* mark the binding layer marker as internal. (mrs) */ - DECL_SOURCE_LINE (d) = 0; - set_identifier_type_value (name, type); - } - else - d = TYPE_NAME (d); - - /* If it is anonymous, then we are called from pushdecl, - and we don't want to infinitely recurse. Also, if the - name is already in scope, we don't want to push it - again--pushdecl is only for pushing new decls. */ - if (! ANON_AGGRNAME_P (name) - && TYPE_NAME (type) - && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL - || lookup_name (name, 1) != TYPE_NAME (type))) - { - if (class_binding_level) - d = pushdecl_class_level (d); - else - d = pushdecl (d); - } - } - else - { - /* Make nested declarations go into class-level scope. */ - d = build_lang_field_decl (TYPE_DECL, name, type); - set_identifier_type_value (name, type); - d = pushdecl_class_level (d); - } - if (ANON_AGGRNAME_P (name)) - DECL_IGNORED_P (d) = 1; - TYPE_NAME (type) = d; - - if ((current_class_type == NULL_TREE - && current_function_decl == NULL_TREE) - || current_lang_name != lang_name_cplusplus) - /* Non-nested class. */ - DECL_NESTED_TYPENAME (d) = name; - else if (current_function_decl != NULL_TREE) - { - /* Function-nested class. */ - set_nested_typename (d, DECL_ASSEMBLER_NAME (current_function_decl), - name, type); - /* This builds the links for classes nested in fn scope. */ - DECL_CONTEXT (d) = current_function_decl; - } - else if (TYPE_SIZE (current_class_type) == NULL_TREE) - { - /* Class-nested class. */ - set_nested_typename (d, DECL_NESTED_TYPENAME (TYPE_NAME (current_class_type)), - name, type); - /* This builds the links for classes nested in type scope. */ - DECL_CONTEXT (d) = current_class_type; - DECL_CLASS_CONTEXT (d) = current_class_type; - } - } - if (b->parm_flag == 2) - { - TREE_NONLOCAL_FLAG (type) = 1; - IDENTIFIER_CLASS_VALUE (name) = TYPE_NAME (type); - if (TYPE_SIZE (current_class_type) == NULL_TREE) - CLASSTYPE_TAGS (current_class_type) = b->tags; - } - } - - if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - /* Use the canonical TYPE_DECL for this node. */ - TYPE_STUB_DECL (type) = TYPE_NAME (type); - else - { - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE - will be the tagged type we just added to the current - binding level. This fake NULL-named TYPE_DECL node helps - dwarfout.c to know when it needs to output a - representation of a tagged type, and it also gives us a - convenient place to record the "scope start" address for - the tagged type. */ - -#if 0 /* not yet, should get fixed properly later */ - TYPE_STUB_DECL (type) = pushdecl (make_type_decl (NULL, type)); -#else - TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type)); -#endif - } -} - -/* Counter used to create anonymous type names. */ -static int anon_cnt = 0; - -/* Return an IDENTIFIER which can be used as a name for - anonymous structs and unions. */ -tree -make_anon_name () -{ - char buf[32]; - - sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++); - return get_identifier (buf); -} - -/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames. - This keeps dbxout from getting confused. */ -void -clear_anon_tags () -{ - register struct binding_level *b; - register tree tags; - static int last_cnt = 0; - - /* Fast out if no new anon names were declared. */ - if (last_cnt == anon_cnt) - return; - - b = current_binding_level; - while (b->tag_transparent) - b = b->level_chain; - tags = b->tags; - while (tags) - { - /* A NULL purpose means we have already processed all tags - from here to the end of the list. */ - if (TREE_PURPOSE (tags) == NULL_TREE) - break; - if (ANON_AGGRNAME_P (TREE_PURPOSE (tags))) - TREE_PURPOSE (tags) = NULL_TREE; - tags = TREE_CHAIN (tags); - } - last_cnt = anon_cnt; -} - -/* Subroutine of duplicate_decls: return truthvalue of whether - or not types of these decls match. */ -static int -decls_match (newdecl, olddecl) - tree newdecl, olddecl; -{ - int types_match; - - if (TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (olddecl) == FUNCTION_DECL) - { - tree f1 = TREE_TYPE (newdecl); - tree f2 = TREE_TYPE (olddecl); - tree p1 = TYPE_ARG_TYPES (f1); - tree p2 = TYPE_ARG_TYPES (f2); - - /* When we parse a static member function definition, - we put together a FUNCTION_DECL which thinks its type - is METHOD_TYPE. Change that to FUNCTION_TYPE, and - proceed. */ - if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl)) - revert_static_member_fn (&f1, &newdecl, &p1); - else if (TREE_CODE (f2) == METHOD_TYPE - && DECL_STATIC_FUNCTION_P (newdecl)) - revert_static_member_fn (&f2, &olddecl, &p2); - - /* Here we must take care of the case where new default - parameters are specified. Also, warn if an old - declaration becomes ambiguous because default - parameters may cause the two to be ambiguous. */ - if (TREE_CODE (f1) != TREE_CODE (f2)) - { - if (TREE_CODE (f1) == OFFSET_TYPE) - compiler_error_with_decl (newdecl, "`%s' redeclared as member function"); - else - compiler_error_with_decl (newdecl, "`%s' redeclared as non-member function"); - return 0; - } - - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)), - TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 1)) - types_match = compparms (p1, p2, 1); - else types_match = 0; - } - else - { - if (TREE_TYPE (newdecl) == error_mark_node) - types_match = TREE_TYPE (olddecl) == error_mark_node; - else if (TREE_TYPE (olddecl) == NULL_TREE) - types_match = TREE_TYPE (newdecl) == NULL_TREE; - else - types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 1); - } - - return types_match; -} - -/* Handle when a new declaration NEWDECL has the same name as an old - one OLDDECL in the same binding contour. Prints an error message - if appropriate. - - If safely possible, alter OLDDECL to look like NEWDECL, and return 1. - Otherwise, return 0. */ - -static int -duplicate_decls (newdecl, olddecl) - register tree newdecl, olddecl; -{ - extern struct obstack permanent_obstack; - unsigned olddecl_uid = DECL_UID (olddecl); - int olddecl_friend = 0, types_match; - int new_defines_function; - register unsigned saved_old_decl_uid; - register int saved_old_decl_friend_p; - - if (TREE_CODE (olddecl) == TREE_LIST - && TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* If a new decl finds a list of old decls, then - we assume that the new decl has C linkage, and - that the old decls have C++ linkage. In this case, - we must look through the list to see whether - there is an ambiguity or not. */ - tree olddecls = olddecl; - - /* If the overload list is empty, just install the decl. */ - if (TREE_VALUE (olddecls) == NULL_TREE) - { - TREE_VALUE (olddecls) = newdecl; - return 1; - } - - while (olddecls) - { - if (decls_match (newdecl, TREE_VALUE (olddecls))) - { - if (TREE_CODE (newdecl) == VAR_DECL) - ; - else if (DECL_LANGUAGE (newdecl) - != DECL_LANGUAGE (TREE_VALUE (olddecls))) - { - error_with_decl (newdecl, "declaration of `%s' with different language linkage"); - error_with_decl (TREE_VALUE (olddecls), "previous declaration here"); - } - types_match = 1; - break; - } - olddecls = TREE_CHAIN (olddecls); - } - if (olddecls) - olddecl = TREE_VALUE (olddecl); - else - return 1; - } - else - { - if (TREE_CODE (olddecl) != TREE_LIST) - olddecl_friend = DECL_LANG_SPECIFIC (olddecl) && DECL_FRIEND_P (olddecl); - types_match = decls_match (newdecl, olddecl); - } - - if ((TREE_TYPE (newdecl) && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK) - || (TREE_TYPE (olddecl) && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK)) - types_match = 0; - - /* If this decl has linkage, and the old one does too, maybe no error. */ - if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) - { - error_with_decl (newdecl, "`%s' redeclared as different kind of symbol"); - if (TREE_CODE (olddecl) == TREE_LIST) - olddecl = TREE_VALUE (olddecl); - error_with_decl (olddecl, "previous declaration of `%s'"); - - /* New decl is completely inconsistent with the old one => - tell caller to replace the old one. */ - - return 0; - } - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* Now that functions must hold information normally held - by field decls, there is extra work to do so that - declaration information does not get destroyed during - definition. */ - if (DECL_VINDEX (olddecl)) - DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); - if (DECL_CONTEXT (olddecl)) - DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - if (DECL_CLASS_CONTEXT (olddecl)) - DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); - if (DECL_CHAIN (newdecl) == NULL_TREE) - DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl); - if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) - DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); - } - - if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL - && IDENTIFIER_IMPLICIT_DECL (DECL_ASSEMBLER_NAME (newdecl)) == olddecl) - /* If -traditional, avoid error for redeclaring fcn - after implicit decl. */ - ; - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl)) - { - if (!types_match) - { - error_with_decl (newdecl, "declaration of `%s'"); - error_with_decl (olddecl, "conflicts with built-in declaration `%s'"); - } - } - else if (!types_match) - { - tree oldtype = TREE_TYPE (olddecl); - tree newtype = TREE_TYPE (newdecl); - int give_error = 0; - - /* Already complained about this, so don't do so again. */ - if (current_class_type == NULL_TREE - || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) - { - give_error = 1; - error_with_decl (newdecl, "conflicting types for `%s'"); - } - - /* Check for function type mismatch - involving an empty arglist vs a nonempty one. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && comptypes (TREE_TYPE (oldtype), - TREE_TYPE (newtype), 1) - && ((TYPE_ARG_TYPES (oldtype) == NULL_TREE - && DECL_INITIAL (olddecl) == NULL_TREE) - || (TYPE_ARG_TYPES (newtype) == NULL_TREE - && DECL_INITIAL (newdecl) == NULL_TREE))) - { - /* Classify the problem further. */ - register tree t = TYPE_ARG_TYPES (oldtype); - if (t == NULL_TREE) - t = TYPE_ARG_TYPES (newtype); - for (; t; t = TREE_CHAIN (t)) - { - register tree type = TREE_VALUE (t); - - if (TREE_CHAIN (t) == NULL_TREE && type != void_type_node) - { - error ("A parameter list with an ellipsis can't match"); - error ("an empty parameter name list declaration."); - break; - } - - if (TYPE_MAIN_VARIANT (type) == float_type_node - || C_PROMOTING_INTEGER_TYPE_P (type)) - { - error ("An argument type that has a default promotion"); - error ("can't match an empty parameter name list declaration."); - break; - } - } - } - if (give_error) - error_with_decl (olddecl, "previous declaration of `%s'"); - - /* There is one thing GNU C++ cannot tolerate: a constructor - which takes the type of object being constructed. - Farm that case out here. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_CONSTRUCTOR_P (newdecl)) - { - tree tmp = TREE_CHAIN (TYPE_ARG_TYPES (newtype)); - - if (tmp != NULL_TREE - && (TYPE_MAIN_VARIANT (TREE_VALUE (tmp)) - == TYPE_METHOD_BASETYPE (newtype))) - { - tree parm = TREE_CHAIN (DECL_ARGUMENTS (newdecl)); - tree argtypes - = hash_tree_chain (build_reference_type (TREE_VALUE (tmp)), - TREE_CHAIN (tmp)); - - DECL_ARG_TYPE (parm) - = TREE_TYPE (parm) - = TYPE_REFERENCE_TO (TREE_VALUE (tmp)); - - TREE_TYPE (newdecl) = newtype - = build_cplus_method_type (TYPE_METHOD_BASETYPE (newtype), - TREE_TYPE (newtype), argtypes); - error ("constructor cannot take as argument the type being constructed"); - SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl), current_class_type); - } - } - } - else - { - char *errmsg = redeclaration_error_message (newdecl, olddecl); - if (errmsg) - { - error_with_decl (newdecl, errmsg); - if (DECL_NAME (olddecl) != NULL_TREE) - error_with_decl (olddecl, - (DECL_INITIAL (olddecl) - && current_binding_level == global_binding_level) - ? "`%s' previously defined here" - : "`%s' previously declared here"); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_INITIAL (olddecl) != NULL_TREE - && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == NULL_TREE - && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE) - { - /* Prototype decl follows defn w/o prototype. */ - warning_with_decl (newdecl, "prototype for `%s'"); - warning_with_decl (olddecl, - "follows non-prototype definition here"); - } - - /* These bits are logically part of the type. */ - if (pedantic - && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) - || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))) - error_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl"); - } - - /* Deal with C++: must preserve virtual function table size. */ - if (TREE_CODE (olddecl) == TYPE_DECL) - { - if (TYPE_LANG_SPECIFIC (TREE_TYPE (newdecl)) - && TYPE_LANG_SPECIFIC (TREE_TYPE (olddecl))) - { - CLASSTYPE_VSIZE (TREE_TYPE (newdecl)) - = CLASSTYPE_VSIZE (TREE_TYPE (olddecl)); - CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (newdecl)) - = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (olddecl)); - } - /* why assert here? Just because debugging information is - messed up? (mrs) */ - /* it happens on something like: - typedef struct Thing { - Thing(); - int x; - } Thing; - */ -#if 0 - my_friendly_assert (DECL_IGNORED_P (olddecl) == DECL_IGNORED_P (newdecl), 139); -#endif - } - - /* Special handling ensues if new decl is a function definition. */ - new_defines_function = (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_INITIAL (newdecl) != NULL_TREE); - - /* Optionally warn about more than one declaration for the same name, - but don't warn about a function declaration followed by a definition. */ - if (warn_redundant_decls - && DECL_SOURCE_LINE (olddecl) != 0 - && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)) - { - warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope"); - warning_with_decl (olddecl, "previous declaration of `%s'"); - } - - /* Copy all the DECL_... slots specified in the new decl - except for any that we copy here from the old type. */ - - if (types_match) - { - /* Automatically handles default parameters. */ - tree oldtype = TREE_TYPE (olddecl); - /* Merge the data types specified in the two decls. */ - tree newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); - - if (TREE_CODE (newdecl) == VAR_DECL) - DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); - /* Do this after calling `common_type' so that default - parameters don't confuse us. */ - else if (TREE_CODE (newdecl) == FUNCTION_DECL - && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)) - != TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)))) - { - tree ctype = NULL_TREE; - ctype = DECL_CLASS_CONTEXT (newdecl); - TREE_TYPE (newdecl) = build_exception_variant (ctype, newtype, - TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))); - TREE_TYPE (olddecl) = build_exception_variant (ctype, newtype, - TYPE_RAISES_EXCEPTIONS (oldtype)); - - if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE(olddecl), 0)) - { - error_with_decl (newdecl, "declaration of `%s' raises different exceptions..."); - error_with_decl (olddecl, "...from previous declaration here"); - } - } - TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; - - /* Lay the type out, unless already done. */ - if (oldtype != TREE_TYPE (newdecl)) - { - if (TREE_TYPE (newdecl) != error_mark_node) - layout_type (TREE_TYPE (newdecl)); - if (TREE_CODE (newdecl) != FUNCTION_DECL - && TREE_CODE (newdecl) != TYPE_DECL - && TREE_CODE (newdecl) != CONST_DECL) - layout_decl (newdecl, 0); - } - else - { - /* Since the type is OLDDECL's, make OLDDECL's size go with. */ - DECL_SIZE (newdecl) = DECL_SIZE (olddecl); - } - - /* Merge the type qualifiers. */ - if (TREE_READONLY (newdecl)) - TREE_READONLY (olddecl) = 1; - if (TREE_THIS_VOLATILE (newdecl)) - TREE_THIS_VOLATILE (olddecl) = 1; - - /* Merge the initialization information. */ - if (DECL_INITIAL (newdecl) == NULL_TREE) - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - /* Keep the old rtl since we can safely use it, unless it's the - call to abort() used for abstract virtuals. */ - if ((DECL_LANG_SPECIFIC (olddecl) - && !DECL_ABSTRACT_VIRTUAL_P (olddecl)) - || DECL_RTL (olddecl) != DECL_RTL (abort_fndecl)) - DECL_RTL (newdecl) = DECL_RTL (olddecl); - } - /* If cannot merge, then use the new type and qualifiers, - and don't preserve the old rtl. */ - else - { - /* Clean out any memory we had of the old declaration. */ - tree oldstatic = value_member (olddecl, static_aggregates); - if (oldstatic) - TREE_VALUE (oldstatic) = error_mark_node; - - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - TREE_READONLY (olddecl) = TREE_READONLY (newdecl); - TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); - TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl); - } - - /* Merge the storage class information. */ - if (DECL_EXTERNAL (newdecl)) - { - TREE_STATIC (newdecl) = TREE_STATIC (olddecl); - DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl); - - /* For functions, static overrides non-static. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - if (! TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0; - } - else - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); - } - else - { - TREE_STATIC (olddecl) = TREE_STATIC (newdecl); - /* A `const' which was not declared `extern' and is - in static storage is invisible. */ - if (TREE_CODE (newdecl) == VAR_DECL - && TREE_READONLY (newdecl) && TREE_STATIC (newdecl) - && ! DECL_THIS_EXTERN (newdecl)) - TREE_PUBLIC (newdecl) = 0; - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - } - - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE) - DECL_INLINE (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - if (new_defines_function) - /* If defining a function declared with other language - linkage, use the previously declared language linkage. */ - DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); - else - { - /* If redeclaring a builtin function, and not a definition, - it stays built in. */ - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN (newdecl) = 1; - DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl)); - /* If we're keeping the built-in definition, keep the rtl, - regardless of declaration matches. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); - } - else - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); - - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - if (DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl)) - /* Previously saved insns go together with - the function's previous definition. */ - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - /* Don't clear out the arguments if we're redefining a function. */ - if (DECL_ARGUMENTS (olddecl)) - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - } - } - - /* Now preserve various other info from the definition. */ - TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl); - TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl); - - /* Don't really know how much of the language-specific - values we should copy from old to new. */ -#if 1 - if (DECL_LANG_SPECIFIC (olddecl)) - DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); -#endif - - /* We are about to copy the contexts of newdecl into olddecl, so save a - few tidbits of information from olddecl that we may need to restore - after the copying takes place. */ - - saved_old_decl_uid = DECL_UID (olddecl); - saved_old_decl_friend_p - = DECL_LANG_SPECIFIC (olddecl) ? DECL_FRIEND_P (olddecl) : 0; - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - int function_size; - struct lang_decl *ol = DECL_LANG_SPECIFIC (olddecl); - struct lang_decl *nl = DECL_LANG_SPECIFIC (newdecl); - - function_size = sizeof (struct tree_decl); - - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - function_size - sizeof (struct tree_common)); - - if ((char *)newdecl + ((function_size + sizeof (struct lang_decl) - + obstack_alignment_mask (&permanent_obstack)) - & ~ obstack_alignment_mask (&permanent_obstack)) - == obstack_next_free (&permanent_obstack)) - { - DECL_MAIN_VARIANT (newdecl) = olddecl; - DECL_LANG_SPECIFIC (olddecl) = ol; - bcopy ((char *)nl, (char *)ol, sizeof (struct lang_decl)); - - obstack_free (&permanent_obstack, newdecl); - } - else if (LANG_DECL_PERMANENT (ol)) - { - if (DECL_MAIN_VARIANT (olddecl) == olddecl) - { - /* Save these lang_decls that would otherwise be lost. */ - extern tree free_lang_decl_chain; - tree free_lang_decl = (tree) ol; - TREE_CHAIN (free_lang_decl) = free_lang_decl_chain; - free_lang_decl_chain = free_lang_decl; - } - else - { - /* Storage leak. */ - } - } - } - else - { - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common) - + tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *)); - } - - DECL_UID (olddecl) = olddecl_uid; - if (olddecl_friend) - DECL_FRIEND_P (olddecl) = 1; - - /* Restore some pieces of information which were originally in olddecl. */ - - DECL_UID (olddecl) = saved_old_decl_uid; - if (DECL_LANG_SPECIFIC (olddecl)) - DECL_FRIEND_P (olddecl) |= saved_old_decl_friend_p; - - return 1; -} - -void -adjust_type_value (id) - tree id; -{ - tree t; - - if (current_binding_level != global_binding_level) - { - if (current_binding_level != class_binding_level) - { - t = IDENTIFIER_LOCAL_VALUE (id); - if (t && TREE_CODE (t) == TYPE_DECL) - { - set_it: - SET_IDENTIFIER_TYPE_VALUE (id, TREE_TYPE (t)); - return; - } - } - else - my_friendly_abort (7); - - if (current_class_type) - { - t = IDENTIFIER_CLASS_VALUE (id); - if (t && TREE_CODE (t) == TYPE_DECL) - goto set_it; - } - } - - t = IDENTIFIER_GLOBAL_VALUE (id); - if (t && TREE_CODE (t) == TYPE_DECL) - goto set_it; - if (t && TREE_CODE (t) == TEMPLATE_DECL) - SET_IDENTIFIER_TYPE_VALUE (id, NULL_TREE); -} - -/* Record a decl-node X as belonging to the current lexical scope. - Check for errors (such as an incompatible declaration for the same - name already seen in the same scope). - - Returns either X or an old decl for the same name. - If an old decl is returned, it may have been smashed - to agree with what X says. */ - -tree -pushdecl (x) - tree x; -{ - register tree t; -#if 0 /* not yet, should get fixed properly later */ - register tree name; -#else - register tree name = DECL_ASSEMBLER_NAME (x); -#endif - register struct binding_level *b = current_binding_level; - -#if 0 - static int nglobals; int len; - - len = list_length (global_binding_level->names); - if (len < nglobals) - my_friendly_abort (8); - else if (len > nglobals) - nglobals = len; -#endif - - /* Don't change DECL_CONTEXT of virtual methods. */ - if (x != current_function_decl - && (TREE_CODE (x) != FUNCTION_DECL - || !DECL_VIRTUAL_P (x))) - DECL_CONTEXT (x) = current_function_decl; - /* A local declaration for a function doesn't constitute nesting. */ - if (TREE_CODE (x) == FUNCTION_DECL && DECL_INITIAL (x) == 0) - DECL_CONTEXT (x) = 0; - -#if 0 /* not yet, should get fixed properly later */ - /* For functions and class static data, we currently look up the encoded - form of the name. For types, we want the real name. The former will - probably be changed soon, according to MDT. */ - if (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL) - name = DECL_ASSEMBLER_NAME (x); - else - name = DECL_NAME (x); -#else - /* Type are looked up using the DECL_NAME, as that is what the rest of the - compiler wants to use. */ - if (TREE_CODE (x) == TYPE_DECL) - name = DECL_NAME (x); -#endif - - if (name) - { - char *file; - int line; - - t = lookup_name_current_level (name); - if (t == error_mark_node) - { - /* error_mark_node is 0 for a while during initialization! */ - t = NULL_TREE; - error_with_decl (x, "`%s' used prior to declaration"); - } - - if (t != NULL_TREE) - { - if (TREE_CODE (t) == PARM_DECL) - { - if (DECL_CONTEXT (t) == NULL_TREE) - fatal ("parse errors have confused me too much"); - } - file = DECL_SOURCE_FILE (t); - line = DECL_SOURCE_LINE (t); - } - - if (t != NULL_TREE && TREE_CODE (t) != TREE_CODE (x)) - { - if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (x) == TYPE_DECL) - { - /* We do nothing special here, because C++ does such nasty - things with TYPE_DECLs. Instead, just let the TYPE_DECL - get shadowed, and know that if we need to find a TYPE_DECL - for a given name, we can look in the IDENTIFIER_TYPE_VALUE - slot of the identifier. */ - ; - } - else if (duplicate_decls (x, t)) - return t; - } - else if (t != NULL_TREE && duplicate_decls (x, t)) - { - /* If this decl is `static' and an `extern' was seen previously, - that is erroneous. But don't complain if -traditional, - since traditional compilers don't complain. - - Note that this does not apply to the C++ case of declaring - a variable `extern const' and then later `const'. */ - if (!flag_traditional && TREE_PUBLIC (name) - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x) && ! DECL_INLINE (x)) - { - /* Due to interference in memory reclamation (X may be - obstack-deallocated at this point), we must guard against - one really special case. */ - if (current_function_decl == x) - current_function_decl = t; - if (IDENTIFIER_IMPLICIT_DECL (name)) - warning ("`%s' was declared implicitly `extern' and later `static'", - lang_printable_name (t)); - else - warning ("`%s' was declared `extern' and later `static'", - lang_printable_name (t)); - warning_with_file_and_line (file, line, - "previous declaration of `%s'", - lang_printable_name (t)); - } - return t; - } - - /* If declaring a type as a typedef, and the type has no known - typedef name, install this TYPE_DECL as its typedef name. - - C++: If it had an anonymous aggregate or enum name, - give it a `better' one. */ - if (TREE_CODE (x) == TYPE_DECL) - { - tree name = TYPE_NAME (TREE_TYPE (x)); - - if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL) - { - /* If these are different names, and we're at the global - binding level, make two equivalent definitions. */ - name = x; - if (global_bindings_p ()) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else - { - tree tname = DECL_NAME (name); - if (global_bindings_p () && ANON_AGGRNAME_P (tname)) - { - /* do gratuitous C++ typedefing, and make sure that - we access this type either through TREE_TYPE field - or via the tags list. */ - TYPE_NAME (TREE_TYPE (x)) = x; - pushtag (tname, TREE_TYPE (x)); - } - } - my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); - if (DECL_NAME (name) && !DECL_NESTED_TYPENAME (name)) - set_nested_typename (x, current_class_name, DECL_NAME (name), - TREE_TYPE (x)); - if (TYPE_NAME (TREE_TYPE (x)) && TYPE_IDENTIFIER (TREE_TYPE (x))) - set_identifier_type_value (DECL_NAME (x), TREE_TYPE (x)); -/* was using TYPE_IDENTIFIER (TREE_TYPE (x)) */ - } - - /* Multiple external decls of the same identifier ought to match. */ - - if (DECL_EXTERNAL (x) && IDENTIFIER_GLOBAL_VALUE (name) != NULL_TREE - && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) - || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))) - /* We get warnings about inline functions where they are defined. - Avoid duplicate warnings where they are used. */ - && !DECL_INLINE (x)) - { - if (! comptypes (TREE_TYPE (x), - TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)), 1)) - { - warning_with_decl (x, - "type mismatch with previous external decl"); - warning_with_decl (IDENTIFIER_GLOBAL_VALUE (name), - "previous external decl of `%s'"); - } - } - - /* In PCC-compatibility mode, extern decls of vars with no current decl - take effect at top level no matter where they are. */ - if (flag_traditional && DECL_EXTERNAL (x) - && lookup_name (name, 0) == NULL_TREE) - b = global_binding_level; - - /* This name is new in its binding level. - Install the new declaration and return it. */ - if (b == global_binding_level) - { - /* Install a global value. */ - - /* Rule for VAR_DECLs, but not for other kinds of _DECLs: - A `const' which was not declared `extern' is invisible. */ - if (TREE_CODE (x) == VAR_DECL - && TREE_READONLY (x) && ! DECL_THIS_EXTERN (x)) - TREE_PUBLIC (x) = 0; - - /* If the first global decl has external linkage, - warn if we later see static one. */ - if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x)) - TREE_PUBLIC (name) = 1; - - /* Don't install a TYPE_DECL if we already have another - sort of _DECL with that name. */ - if (TREE_CODE (x) != TYPE_DECL - || t == NULL_TREE - || TREE_CODE (t) == TYPE_DECL) -#if 0 - /* This has not be thoroughly tested yet. */ - /* It allows better dwarf debugging. */ - IDENTIFIER_GLOBAL_VALUE (name) - = TREE_CODE_CLASS (TREE_CODE (x)) == 'd' - ? x : build_decl (TYPE_DECL, NULL, TREE_TYPE (x)); -#else - IDENTIFIER_GLOBAL_VALUE (name) = x; -#endif - - /* Don't forget if the function was used via an implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_USED (x) = 1; - - /* Don't forget if its address was taken in that way. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_ADDRESSABLE (x) = 1; - - /* Warn about mismatches against previous implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE - /* If this real decl matches the implicit, don't complain. */ - && ! (TREE_CODE (x) == FUNCTION_DECL - && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) - warning ("`%s' was previously implicitly declared to return `int'", - lang_printable_name (x)); - - /* If this decl is `static' and an `extern' was seen previously, - that is erroneous. Don't do this for TYPE_DECLs. */ - if (TREE_PUBLIC (name) - && TREE_CODE (x) != TYPE_DECL - && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x)) - { - if (IDENTIFIER_IMPLICIT_DECL (name)) - warning ("`%s' was declared implicitly `extern' and later `static'", - lang_printable_name (x)); - else - warning ("`%s' was declared `extern' and later `static'", - lang_printable_name (x)); - } - } - else - { - /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); - tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name); - set_identifier_local_value (name, x); - - /* If this is an extern function declaration, see if we - have a global definition or declaration for the function. */ - if (oldlocal == NULL_TREE - && DECL_EXTERNAL (x) && !DECL_INLINE (x) - && oldglobal != NULL_TREE - && TREE_CODE (x) == FUNCTION_DECL - && TREE_CODE (oldglobal) == FUNCTION_DECL) - { - /* We have one. Their types must agree. */ - if (! comptypes (TREE_TYPE (x), TREE_TYPE (oldglobal), 1)) - warning_with_decl (x, "extern declaration of `%s' doesn't match global one"); - else - { - /* Inner extern decl is inline if global one is. - Copy enough to really inline it. */ - if (DECL_INLINE (oldglobal)) - { - DECL_INLINE (x) = DECL_INLINE (oldglobal); - DECL_INITIAL (x) = (current_function_decl == oldglobal - ? NULL_TREE : DECL_INITIAL (oldglobal)); - DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal); - DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal); - DECL_RESULT (x) = DECL_RESULT (oldglobal); - TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal); - DECL_ABSTRACT_ORIGIN (x) = oldglobal; - } - /* Inner extern decl is built-in if global one is. */ - if (DECL_BUILT_IN (oldglobal)) - { - DECL_BUILT_IN (x) = DECL_BUILT_IN (oldglobal); - DECL_SET_FUNCTION_CODE (x, DECL_FUNCTION_CODE (oldglobal)); - } - /* Keep the arg types from a file-scope fcn defn. */ - if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != NULL_TREE - && DECL_INITIAL (oldglobal) - && TYPE_ARG_TYPES (TREE_TYPE (x)) == NULL_TREE) - TREE_TYPE (x) = TREE_TYPE (oldglobal); - } - } - /* If we have a local external declaration, - and no file-scope declaration has yet been seen, - then if we later have a file-scope decl it must not be static. */ - if (oldlocal == NULL_TREE - && oldglobal == NULL_TREE - && DECL_EXTERNAL (x) - && TREE_PUBLIC (x)) - { - TREE_PUBLIC (name) = 1; - } - - if (DECL_FROM_INLINE (x)) - /* Inline decls shadow nothing. */; - - /* Warn if shadowing an argument at the top level of the body. */ - else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) - && TREE_CODE (oldlocal) == PARM_DECL - && TREE_CODE (x) != PARM_DECL) - { - /* Go to where the parms should be and see if we - find them there. */ - struct binding_level *b = current_binding_level->level_chain; - - if (cleanup_label) - b = b->level_chain; - - /* ARM $8.3 */ - if (b->parm_flag == 1) - pedwarn ("declaration of `%s' shadows a parameter", - IDENTIFIER_POINTER (name)); - } - /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && DECL_SOURCE_LINE (x) != 0 - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) - { - char *warnstring = NULL; - - if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL) - warnstring = "declaration of `%s' shadows a parameter"; - else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE) - warnstring = "declaration of `%s' shadows a member of `this'"; - else if (oldlocal != NULL_TREE) - warnstring = "declaration of `%s' shadows previous local"; - else if (oldglobal != NULL_TREE) - warnstring = "declaration of `%s' shadows global declaration"; - - if (warnstring) - warning (warnstring, IDENTIFIER_POINTER (name)); - } - - /* If storing a local value, there may already be one (inherited). - If so, record it for restoration when this binding level ends. */ - if (oldlocal != NULL_TREE) - b->shadowed = tree_cons (name, oldlocal, b->shadowed); - } - - /* Keep count of variables in this level with incomplete type. */ - if (TREE_CODE (x) != TEMPLATE_DECL - && TREE_CODE (x) != CPLUS_CATCH_DECL - && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE - && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE)) - { - if (++b->n_incomplete == 0) - error ("too many incomplete variables at this point"); - } - } - - if (TREE_CODE (x) == TYPE_DECL && name != NULL_TREE) - { - adjust_type_value (name); - if (current_class_name) - { - if (!DECL_NESTED_TYPENAME (x)) - set_nested_typename (x, current_class_name, DECL_NAME (x), - TREE_TYPE (x)); - adjust_type_value (DECL_NESTED_TYPENAME (x)); - } - } - - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = b->names; - b->names = x; - if (! (b != global_binding_level || TREE_PERMANENT (x))) - my_friendly_abort (124); - - return x; -} - -/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, - if appropriate. */ -tree -pushdecl_top_level (x) - tree x; -{ - register tree t; - register struct binding_level *b = current_binding_level; - - current_binding_level = global_binding_level; - t = pushdecl (x); - current_binding_level = b; - if (class_binding_level) - b = class_binding_level; - /* Now, the type_shadowed stack may screw us. Munge it so it does - what we want. */ - if (TREE_CODE (x) == TYPE_DECL) - { - tree name = DECL_NAME (x); - tree newval; - tree *ptr = (tree *)0; - for (; b != global_binding_level; b = b->level_chain) - { - tree shadowed = b->type_shadowed; - for (; shadowed; shadowed = TREE_CHAIN (shadowed)) - if (TREE_PURPOSE (shadowed) == name) - { - ptr = &TREE_VALUE (shadowed); - /* Can't break out of the loop here because sometimes - a binding level will have duplicate bindings for - PT names. It's gross, but I haven't time to fix it. */ - } - } - newval = TREE_TYPE (x); - if (ptr == (tree *)0) - { - /* @@ This shouldn't be needed. My test case "zstring.cc" trips - up here if this is changed to an assertion. --KR */ - SET_IDENTIFIER_TYPE_VALUE (name, newval); - } - else - { -#if 0 - /* Disabled this 11/10/92, since there are many cases which - behave just fine when *ptr doesn't satisfy either of these. - For example, nested classes declared as friends of their enclosing - class will not meet this criteria. (bpk) */ - my_friendly_assert (*ptr == NULL_TREE || *ptr == newval, 141); -#endif - *ptr = newval; - } - } - return t; -} - -/* Like push_overloaded_decl, only it places X in GLOBAL_BINDING_LEVEL, - if appropriate. */ -void -push_overloaded_decl_top_level (x, forget) - tree x; - int forget; -{ - struct binding_level *b = current_binding_level; - - current_binding_level = global_binding_level; - push_overloaded_decl (x, forget); - current_binding_level = b; -} - -/* Make the declaration of X appear in CLASS scope. */ -tree -pushdecl_class_level (x) - tree x; -{ - /* Don't use DECL_ASSEMBLER_NAME here! Everything that looks in class - scope looks for the pre-mangled name. */ - register tree name = DECL_NAME (x); - - if (name) - { - tree oldclass = IDENTIFIER_CLASS_VALUE (name); - if (oldclass) - class_binding_level->class_shadowed - = tree_cons (name, oldclass, class_binding_level->class_shadowed); - IDENTIFIER_CLASS_VALUE (name) = x; - obstack_ptr_grow (&decl_obstack, x); - if (TREE_CODE (x) == TYPE_DECL && !DECL_NESTED_TYPENAME (x)) - set_nested_typename (x, current_class_name, name, TREE_TYPE (x)); - } - return x; -} - -/* Tell caller how to interpret a TREE_LIST which contains - chains of FUNCTION_DECLS. */ -int -overloaded_globals_p (list) - tree list; -{ - my_friendly_assert (TREE_CODE (list) == TREE_LIST, 142); - - /* Don't commit caller to seeing them as globals. */ - if (TREE_NONLOCAL_FLAG (list)) - return -1; - /* Do commit caller to seeing them as globals. */ - if (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE) - return 1; - /* Do commit caller to not seeing them as globals. */ - return 0; -} - -/* DECL is a FUNCTION_DECL which may have other definitions already in place. - We get around this by making IDENTIFIER_GLOBAL_VALUE (DECL_NAME (DECL)) - point to a list of all the things that want to be referenced by that name. - It is then up to the users of that name to decide what to do with that - list. - - DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT - slot. It is dealt with the same way. - - The value returned may be a previous declaration if we guessed wrong - about what language DECL should belong to (C or C++). Otherwise, - it's always DECL (and never something that's not a _DECL). */ -tree -push_overloaded_decl (decl, forgettable) - tree decl; - int forgettable; -{ - tree orig_name = DECL_NAME (decl); - tree glob = IDENTIFIER_GLOBAL_VALUE (orig_name); - - DECL_OVERLOADED (decl) = 1; - if (glob) - { - if (TREE_CODE (glob) != TREE_LIST) - { - if (DECL_LANGUAGE (decl) == lang_c) - { - if (TREE_CODE (glob) == FUNCTION_DECL) - { - if (DECL_LANGUAGE (glob) == lang_c) - { - error_with_decl (decl, "C-language function `%s' overloaded here"); - error_with_decl (glob, "Previous C-language version of this function was `%s'"); - } - } - else - my_friendly_abort (9); - } - if (forgettable - && ! flag_traditional - && TREE_PERMANENT (glob) == 1 - && !global_bindings_p ()) - overloads_to_forget = tree_cons (orig_name, glob, overloads_to_forget); - /* We cache the value of builtin functions as ADDR_EXPRs - in the name space. Convert it to some kind of _DECL after - remembering what to forget. */ - if (TREE_CODE (glob) == ADDR_EXPR) - glob = TREE_OPERAND (glob, 0); - - if (TREE_CODE (glob) == FUNCTION_DECL - && DECL_LANGUAGE (glob) != DECL_LANGUAGE (decl) - && comptypes (TREE_TYPE (glob), TREE_TYPE (decl), 1)) - { - if (current_lang_stack == current_lang_base) - { - DECL_LANGUAGE (decl) = DECL_LANGUAGE (glob); - return glob; - } - else - { - error_with_decl (decl, "conflicting language contexts for declaration of `%s';"); - error_with_decl (glob, "conflicts with previous declaration here"); - } - } - if (pedantic && TREE_CODE (glob) == VAR_DECL) - { - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (glob)) == 'd', 143); - error_with_decl (glob, "non-function declaration `%s'"); - error_with_decl (decl, "conflicts with function declaration `%s'"); - } - glob = tree_cons (orig_name, glob, NULL_TREE); - glob = tree_cons (TREE_PURPOSE (glob), decl, glob); - IDENTIFIER_GLOBAL_VALUE (orig_name) = glob; - TREE_TYPE (glob) = unknown_type_node; - return decl; - } - - if (TREE_VALUE (glob) == NULL_TREE) - { - TREE_VALUE (glob) = decl; - return decl; - } - if (TREE_CODE (decl) != TEMPLATE_DECL) - { - tree name = DECL_ASSEMBLER_NAME (decl); - tree tmp; - - for (tmp = glob; tmp; tmp = TREE_CHAIN (tmp)) - { - if (TREE_CODE (TREE_VALUE (tmp)) == FUNCTION_DECL - && DECL_LANGUAGE (TREE_VALUE (tmp)) != DECL_LANGUAGE (decl) - && comptypes (TREE_TYPE (TREE_VALUE (tmp)), TREE_TYPE (decl), - 1)) - { - error_with_decl (decl, - "conflicting language contexts for declaration of `%s';"); - error_with_decl (TREE_VALUE (tmp), - "conflicts with previous declaration here"); - } - if (TREE_CODE (TREE_VALUE (tmp)) != TEMPLATE_DECL - && DECL_ASSEMBLER_NAME (TREE_VALUE (tmp)) == name) - return decl; - } - } - } - if (DECL_LANGUAGE (decl) == lang_c) - { - tree decls = glob; - while (decls && DECL_LANGUAGE (TREE_VALUE (decls)) == lang_cplusplus) - decls = TREE_CHAIN (decls); - if (decls) - { - error_with_decl (decl, "C-language function `%s' overloaded here"); - error_with_decl (TREE_VALUE (decls), "Previous C-language version of this function was `%s'"); - } - } - - if (forgettable - && ! flag_traditional - && (glob == NULL_TREE || TREE_PERMANENT (glob) == 1) - && !global_bindings_p () - && !pseudo_global_level_p ()) - overloads_to_forget = tree_cons (orig_name, glob, overloads_to_forget); - glob = tree_cons (orig_name, decl, glob); - IDENTIFIER_GLOBAL_VALUE (orig_name) = glob; - TREE_TYPE (glob) = unknown_type_node; - return decl; -} - -/* Generate an implicit declaration for identifier FUNCTIONID - as a function of type int (). Print a warning if appropriate. */ - -tree -implicitly_declare (functionid) - tree functionid; -{ - register tree decl; - int temp = allocation_temporary_p (); - - push_obstacks_nochange (); - - /* Save the decl permanently so we can warn if definition follows. - In ANSI C, warn_implicit is usually false, so the saves little space. - But in C++, it's usually true, hence the extra code. */ - if (temp && (flag_traditional || !warn_implicit - || current_binding_level == global_binding_level)) - end_temporary_allocation (); - - /* We used to reuse an old implicit decl here, - but this loses with inline functions because it can clobber - the saved decl chains. */ - decl = build_lang_decl (FUNCTION_DECL, functionid, default_function_type); - - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* ANSI standard says implicit declarations are in the innermost block. - So we record the decl in the standard fashion. - If flag_traditional is set, pushdecl does it top-level. */ - pushdecl (decl); - rest_of_decl_compilation (decl, NULL_PTR, 0, 0); - - if (warn_implicit - /* Only one warning per identifier. */ - && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE) - { - pedwarn ("implicit declaration of function `%s'", - IDENTIFIER_POINTER (functionid)); - } - - SET_IDENTIFIER_IMPLICIT_DECL (functionid, decl); - - pop_obstacks (); - - return decl; -} - -/* Return zero if the declaration NEWDECL is valid - when the declaration OLDDECL (assumed to be for the same name) - has already been seen. - Otherwise return an error message format string with a %s - where the identifier should go. */ - -static char * -redeclaration_error_message (newdecl, olddecl) - tree newdecl, olddecl; -{ - if (TREE_CODE (newdecl) == TYPE_DECL) - { - /* Because C++ can put things into name space for free, - constructs like "typedef struct foo { ... } foo" - would look like an erroneous redeclaration. */ - if (TREE_TYPE (olddecl) == TREE_TYPE (newdecl)) - return 0; - else - return "redefinition of `%s'"; - } - else if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* If this is a pure function, its olddecl will actually be - the original initialization to `0' (which we force to call - abort()). Don't complain about redefinition in this case. */ - if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl)) - return 0; - - /* Declarations of functions can insist on internal linkage - but they can't be inconsistent with internal linkage, - so there can be no error on that account. - However defining the same name twice is no good. */ - if (DECL_INITIAL (olddecl) != NULL_TREE - && DECL_INITIAL (newdecl) != NULL_TREE - /* However, defining once as extern inline and a second - time in another way is ok. */ - && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) - && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) - { - if (DECL_NAME (olddecl) == NULL_TREE) - return "`%s' not declared in class"; - else - return "redefinition of `%s'"; - } - return 0; - } - else if (current_binding_level == global_binding_level) - { - /* Objects declared at top level: */ - /* If at least one is a reference, it's ok. */ - if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) - return 0; - /* Reject two definitions. */ - if (DECL_INITIAL (olddecl) != NULL_TREE - && DECL_INITIAL (newdecl) != NULL_TREE) - return "redefinition of `%s'"; - /* Now we have two tentative defs, or one tentative and one real def. */ - /* Insist that the linkage match. */ - if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl)) - return "conflicting declarations of `%s'"; - return 0; - } - else - { - /* Objects declared with block scope: */ - /* Reject two definitions, and reject a definition - together with an external reference. */ - if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))) - return "redeclaration of `%s'"; - return 0; - } -} - -/* Get the LABEL_DECL corresponding to identifier ID as a label. - Create one if none exists so far for the current function. - This function is called for both label definitions and label references. */ - -tree -lookup_label (id) - tree id; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (id); - - if ((decl == NULL_TREE - || DECL_SOURCE_LINE (decl) == 0) - && (named_label_uses == 0 - || TREE_PURPOSE (named_label_uses) != current_binding_level->names - || TREE_VALUE (named_label_uses) != decl)) - { - named_label_uses - = tree_cons (current_binding_level->names, decl, named_label_uses); - TREE_TYPE (named_label_uses) = (tree)current_binding_level; - } - - /* Use a label already defined or ref'd with this name. */ - if (decl != NULL_TREE) - { - /* But not if it is inherited and wasn't declared to be inheritable. */ - if (DECL_CONTEXT (decl) != current_function_decl - && ! C_DECLARED_LABEL_FLAG (decl)) - return shadow_label (id); - return decl; - } - - decl = build_decl (LABEL_DECL, id, void_type_node); - - /* A label not explicitly declared must be local to where it's ref'd. */ - DECL_CONTEXT (decl) = current_function_decl; - - DECL_MODE (decl) = VOIDmode; - - /* Say where one reference is to the label, - for the sake of the error if it is not defined. */ - DECL_SOURCE_LINE (decl) = lineno; - DECL_SOURCE_FILE (decl) = input_filename; - - SET_IDENTIFIER_LABEL_VALUE (id, decl); - - named_labels = tree_cons (NULL_TREE, decl, named_labels); - TREE_VALUE (named_label_uses) = decl; - - return decl; -} - -/* Make a label named NAME in the current function, - shadowing silently any that may be inherited from containing functions - or containing scopes. - - Note that valid use, if the label being shadowed - comes from another scope in the same function, - requires calling declare_nonlocal_label right away. */ - -tree -shadow_label (name) - tree name; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (name); - - if (decl != NULL_TREE) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - SET_IDENTIFIER_LABEL_VALUE (name, 0); - SET_IDENTIFIER_LABEL_VALUE (decl, 0); - } - - return lookup_label (name); -} - -/* Define a label, specifying the location in the source file. - Return the LABEL_DECL node for the label, if the definition is valid. - Otherwise return 0. */ - -tree -define_label (filename, line, name) - char *filename; - int line; - tree name; -{ - tree decl = lookup_label (name); - - /* After labels, make any new cleanups go into their - own new (temporary) binding contour. */ - current_binding_level->more_cleanups_ok = 0; - - /* If label with this name is known from an outer context, shadow it. */ - if (decl != NULL_TREE && DECL_CONTEXT (decl) != current_function_decl) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - SET_IDENTIFIER_LABEL_VALUE (name, 0); - decl = lookup_label (name); - } - - if (DECL_INITIAL (decl) != NULL_TREE) - { - error_with_decl (decl, "duplicate label `%s'"); - return 0; - } - else - { - tree uses, prev; - - /* Mark label as having been defined. */ - DECL_INITIAL (decl) = error_mark_node; - /* Say where in the source. */ - DECL_SOURCE_FILE (decl) = filename; - DECL_SOURCE_LINE (decl) = line; - - for (prev = NULL_TREE, uses = named_label_uses; - uses; - prev = uses, uses = TREE_CHAIN (uses)) - if (TREE_VALUE (uses) == decl) - { - struct binding_level *b = current_binding_level; - while (b) - { - tree new_decls = b->names; - tree old_decls = ((tree)b == TREE_TYPE (uses) - ? TREE_PURPOSE (uses) : NULL_TREE); - while (new_decls != old_decls) - { - if (TREE_CODE (new_decls) == VAR_DECL - /* Don't complain about crossing initialization - of internal entities. They can't be accessed, - and they should be cleaned up - by the time we get to the label. */ - && DECL_SOURCE_LINE (new_decls) != 0 - && ((DECL_INITIAL (new_decls) != NULL_TREE - && DECL_INITIAL (new_decls) != error_mark_node) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) - { - if (IDENTIFIER_ERROR_LOCUS (decl) == NULL_TREE) - error_with_decl (decl, "invalid jump to label `%s'"); - SET_IDENTIFIER_ERROR_LOCUS (decl, current_function_decl); - error_with_decl (new_decls, "crosses initialization of `%s'"); - } - new_decls = TREE_CHAIN (new_decls); - } - if ((tree)b == TREE_TYPE (uses)) - break; - b = b->level_chain; - } - - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (uses); - else - named_label_uses = TREE_CHAIN (uses); - } - current_function_return_value = NULL_TREE; - return decl; - } -} - -/* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */ -/* XXX Note decl is never actually used. (bpk) */ -void -define_case_label (decl) - tree decl; -{ - tree cleanup = last_cleanup_this_contour (); - if (cleanup) - { - static int explained = 0; - error_with_decl (TREE_PURPOSE (cleanup), "destructor needed for `%s'"); - error ("where case label appears here"); - if (!explained) - { - error ("(enclose actions of previous case statements requiring"); - error ("destructors in their own binding contours.)"); - explained = 1; - } - } - - /* After labels, make any new cleanups go into their - own new (temporary) binding contour. */ - - current_binding_level->more_cleanups_ok = 0; - current_function_return_value = NULL_TREE; -} - -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls () -{ - return current_binding_level->names; -} - -/* Return the list of type-tags (for structs, etc) of the current level. */ - -tree -gettags () -{ - return current_binding_level->tags; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static void -storedecls (decls) - tree decls; -{ - current_binding_level->names = decls; -} - -/* Similarly, store the list of tags of the current level. */ - -static void -storetags (tags) - tree tags; -{ - current_binding_level->tags = tags; -} - -/* Given NAME, an IDENTIFIER_NODE, - return the structure (or union or enum) definition for that name. - Searches binding levels from BINDING_LEVEL up to the global level. - If THISLEVEL_ONLY is nonzero, searches only the specified context - (but skips any tag-transparent contexts to find one that is - meaningful for tags). - FORM says which kind of type the caller wants; - it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. - If the wrong kind of type is found, and it's not a template, an error is - reported. */ - -static tree -lookup_tag (form, name, binding_level, thislevel_only) - enum tree_code form; - struct binding_level *binding_level; - tree name; - int thislevel_only; -{ - register struct binding_level *level; - - for (level = binding_level; level; level = level->level_chain) - { - register tree tail; - if (ANON_AGGRNAME_P (name)) - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - /* There's no need for error checking here, because - anon names are unique throughout the compilation. */ - if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name) - return TREE_VALUE (tail); - } - else - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_PURPOSE (tail) == name) - { - enum tree_code code = TREE_CODE (TREE_VALUE (tail)); - /* Should tighten this up; it'll probably permit - UNION_TYPE and a struct template, for example. */ - if (code != form - && !(form != ENUMERAL_TYPE - && (code == TEMPLATE_DECL - || code == UNINSTANTIATED_P_TYPE))) - - { - /* Definition isn't the kind we were looking for. */ - error ("`%s' defined as wrong kind of tag", - IDENTIFIER_POINTER (name)); - } - return TREE_VALUE (tail); - } - } - if (thislevel_only && ! level->tag_transparent) - return NULL_TREE; - if (current_class_type && level->level_chain == global_binding_level) - { - /* Try looking in this class's tags before heading into - global binding level. */ - tree context = current_class_type; - while (context) - { - switch (TREE_CODE_CLASS (TREE_CODE (context))) - { - case 't': - { - tree these_tags = CLASSTYPE_TAGS (context); - if (ANON_AGGRNAME_P (name)) - while (these_tags) - { - if (TYPE_IDENTIFIER (TREE_VALUE (these_tags)) - == name) - return TREE_VALUE (tail); - these_tags = TREE_CHAIN (these_tags); - } - else - while (these_tags) - { - if (TREE_PURPOSE (these_tags) == name) - { - if (TREE_CODE (TREE_VALUE (these_tags)) != form) - { - error ("`%s' defined as wrong kind of tag in class scope", - IDENTIFIER_POINTER (name)); - } - return TREE_VALUE (tail); - } - these_tags = TREE_CHAIN (these_tags); - } - /* If this type is not yet complete, then don't - look at its context. */ - if (TYPE_SIZE (context) == NULL_TREE) - goto no_context; - /* Go to next enclosing type, if any. */ - context = DECL_CONTEXT (TYPE_NAME (context)); - break; - case 'd': - context = DECL_CONTEXT (context); - break; - default: - my_friendly_abort (10); - } - continue; - } - no_context: - break; - } - } - } - return NULL_TREE; -} - -void -set_current_level_tags_transparency (tags_transparent) - int tags_transparent; -{ - current_binding_level->tag_transparent = tags_transparent; -} - -/* Given a type, find the tag that was defined for it and return the tag name. - Otherwise return 0. However, the value can never be 0 - in the cases in which this is used. - - C++: If NAME is non-zero, this is the new name to install. This is - done when replacing anonymous tags with real tag names. */ - -static tree -lookup_tag_reverse (type, name) - tree type; - tree name; -{ - register struct binding_level *level; - - for (level = current_binding_level; level; level = level->level_chain) - { - register tree tail; - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_VALUE (tail) == type) - { - if (name) - TREE_PURPOSE (tail) = name; - return TREE_PURPOSE (tail); - } - } - } - return NULL_TREE; -} - -/* Given type TYPE which was not declared in C++ language context, - attempt to find a name by which it is referred. */ -tree -typedecl_for_tag (tag) - tree tag; -{ - struct binding_level *b = current_binding_level; - - if (TREE_CODE (TYPE_NAME (tag)) == TYPE_DECL) - return TYPE_NAME (tag); - - while (b) - { - tree decls = b->names; - while (decls) - { - if (TREE_CODE (decls) == TYPE_DECL && TREE_TYPE (decls) == tag) - break; - decls = TREE_CHAIN (decls); - } - if (decls) - return decls; - b = b->level_chain; - } - return NULL_TREE; -} - -/* Called when we must retroactively globalize a type we previously - thought needed to be nested. This happens, for example, when - a `friend class' declaration is seen for an undefined type. */ - -static void -globalize_nested_type (type) - tree type; -{ - tree t, prev = NULL_TREE, d = TYPE_NAME (type); - struct binding_level *b; - - my_friendly_assert (TREE_CODE (d) == TYPE_DECL, 144); - /* If the type value has already been globalized, then we're set. */ - if (IDENTIFIER_GLOBAL_VALUE (DECL_NAME (d)) == d) - return; - if (IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (d))) - { - /* If this type already made it into the global tags, - silently return. */ - if (value_member (type, global_binding_level->tags)) - return; - } - - set_identifier_type_value (DECL_NESTED_TYPENAME (d), NULL_TREE); - DECL_NESTED_TYPENAME (d) = DECL_NAME (d); - DECL_CONTEXT (d) = NULL_TREE; - if (class_binding_level) - b = class_binding_level; - else - b = current_binding_level; - while (b != global_binding_level) - { - prev = NULL_TREE; - if (b->parm_flag == 2) - for (t = b->tags; t != NULL_TREE; prev = t, t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == type) - goto found; - b = b->level_chain; - } - /* We failed to find this tag anywhere up the binding chains. - B is now the global binding level... check there. */ - prev = NULL_TREE; - if (b->parm_flag == 2) - for (t = b->tags; t != NULL_TREE; prev = t, t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == type) - goto foundglobal; - /* It wasn't in global scope either, so this is an anonymous forward ref - of some kind; let it happen. */ - return; - -foundglobal: - print_node_brief (stderr, "Tried to globalize already-global type ", - type, 0); - my_friendly_abort (11); - -found: - /* Pull the tag out of the nested binding contour. */ - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (t); - else - b->tags = TREE_CHAIN (t); - - set_identifier_type_value (TREE_PURPOSE (t), TREE_VALUE (t)); - global_binding_level->tags - = perm_tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), - global_binding_level->tags); - - /* Pull the tag out of the class's tags (if there). - It won't show up if it appears e.g. in a parameter declaration - or definition of a member function of this type. */ - if (current_class_type != NULL_TREE) - { - for (t = CLASSTYPE_TAGS (current_class_type), prev = NULL_TREE; - t != NULL_TREE; - prev = t, t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == type) - break; - - if (t != NULL_TREE) - { - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (t); - else - CLASSTYPE_TAGS (current_class_type) = TREE_CHAIN (t); - } - } - - pushdecl_top_level (d); -} - -static void -maybe_globalize_type (type) - tree type; -{ - if ((((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - && ! TYPE_BEING_DEFINED (type)) - || TREE_CODE (type) == ENUMERAL_TYPE) - && TYPE_SIZE (type) == NULL_TREE - /* This part is gross. We keep calling here with types that - are instantiations of templates, when that type should is - global, or doesn't have the type decl established yet, - so globalizing will fail (because it won't find the type in any - non-global scope). So we short-circuit that path. */ - && !(TYPE_NAME (type) != NULL_TREE - && TYPE_IDENTIFIER (type) != NULL_TREE - && ! IDENTIFIER_HAS_TYPE_VALUE (TYPE_IDENTIFIER (type))) - ) - globalize_nested_type (type); -} - -/* Lookup TYPE in CONTEXT (a chain of nested types or a FUNCTION_DECL). - Return the type value, or NULL_TREE if not found. */ -static tree -lookup_nested_type (type, context) - tree type; - tree context; -{ - if (context == NULL_TREE) - return NULL_TREE; - while (context) - { - switch (TREE_CODE (context)) - { - case TYPE_DECL: - { - tree ctype = TREE_TYPE (context); - tree match = value_member (type, CLASSTYPE_TAGS (ctype)); - if (match) - return TREE_VALUE (match); - context = DECL_CONTEXT (context); - - /* When we have a nested class whose member functions have - local types (e.g., a set of enums), we'll arrive here - with the DECL_CONTEXT as the actual RECORD_TYPE node for - the enclosing class. Instead, we want to make sure we - come back in here with the TYPE_DECL, not the RECORD_TYPE. */ - if (context && TREE_CODE (context) == RECORD_TYPE) - context = TREE_CHAIN (context); - } - break; - case FUNCTION_DECL: - return TYPE_IDENTIFIER (type) ? lookup_name (TYPE_IDENTIFIER (type), 1) : NULL_TREE; - break; - default: - my_friendly_abort (12); - } - } - return NULL_TREE; -} - -/* Look up NAME in the current binding level and its superiors in the - namespace of variables, functions and typedefs. Return a ..._DECL - node of some kind representing its definition if there is only one - such declaration, or return a TREE_LIST with all the overloaded - definitions if there are many, or return 0 if it is undefined. - - If PREFER_TYPE is > 0, we prefer TYPE_DECLs. - If PREFER_TYPE is = 0, we prefer non-TYPE_DECLs. - If PREFER_TYPE is < 0, we arbitrate according to lexical context. */ - -tree -lookup_name (name, prefer_type) - tree name; - int prefer_type; -{ - register tree val; - - if (current_binding_level != global_binding_level - && IDENTIFIER_LOCAL_VALUE (name)) - val = IDENTIFIER_LOCAL_VALUE (name); - /* In C++ class fields are between local and global scope, - just before the global scope. */ - else if (current_class_type) - { - val = IDENTIFIER_CLASS_VALUE (name); - if (val == NULL_TREE - && TYPE_SIZE (current_class_type) == NULL_TREE - && CLASSTYPE_LOCAL_TYPEDECLS (current_class_type)) - { - /* Try to find values from base classes - if we are presently defining a type. - We are presently only interested in TYPE_DECLs. */ - val = lookup_field (current_class_type, name, 0, prefer_type < 0); - if (val == error_mark_node) - return val; - if (val && TREE_CODE (val) != TYPE_DECL) - val = NULL_TREE; - } - - /* yylex() calls this with -2, since we should never start digging for - the nested name at the point where we haven't even, for example, - created the COMPONENT_REF or anything like that. */ - if (val == NULL_TREE) - val = lookup_nested_field (name, prefer_type != -2); - - if (val == NULL_TREE) - val = IDENTIFIER_GLOBAL_VALUE (name); - } - else - val = IDENTIFIER_GLOBAL_VALUE (name); - - if (val) - { - extern int looking_for_typename; - - /* Arbitrate between finding a TYPE_DECL and finding - other kinds of _DECLs. */ - if (TREE_CODE (val) == TYPE_DECL || looking_for_typename < 0) - return val; - - if (IDENTIFIER_HAS_TYPE_VALUE (name)) - { - register tree val_as_type = TYPE_NAME (IDENTIFIER_TYPE_VALUE (name)); - - if (val == val_as_type || prefer_type > 0 - || looking_for_typename > 0) - return val_as_type; - if (prefer_type == 0) - return val; - return arbitrate_lookup (name, val, val_as_type); - } - if (TREE_TYPE (val) == error_mark_node) - return error_mark_node; - } - - return val; -} - -/* Similar to `lookup_name' but look only at current binding level. */ - -tree -lookup_name_current_level (name) - tree name; -{ - register tree t; - - if (current_binding_level == global_binding_level) - return IDENTIFIER_GLOBAL_VALUE (name); - - if (IDENTIFIER_LOCAL_VALUE (name) == NULL_TREE) - return 0; - - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) - if (DECL_NAME (t) == name) - break; - - return t; -} - -/* Arrange for the user to get a source line number, even when the - compiler is going down in flames, so that she at least has a - chance of working around problems in the compiler. We used to - call error(), but that let the segmentation fault continue - through; now, it's much more passive by asking them to send the - maintainers mail about the problem. */ - -static void -sigsegv (sig) - int sig; -{ - signal (SIGSEGV, SIG_DFL); -#ifdef SIGIOT - signal (SIGIOT, SIG_DFL); -#endif -#ifdef SIGILL - signal (SIGILL, SIG_DFL); -#endif -#ifdef SIGABRT - signal (SIGABRT, SIG_DFL); -#endif - my_friendly_abort (0); -} - -/* Array for holding types considered "built-in". These types - are output in the module in which `main' is defined. */ -static tree *builtin_type_tdescs_arr; -static int builtin_type_tdescs_len, builtin_type_tdescs_max; - -/* Push the declarations of builtin types into the namespace. - RID_INDEX, if < RID_MAX is the index of the builtin type - in the array RID_POINTERS. NAME is the name used when looking - up the builtin type. TYPE is the _TYPE node for the builtin type. */ - -static void -record_builtin_type (rid_index, name, type) - enum rid rid_index; - char *name; - tree type; -{ - tree rname = NULL_TREE, tname = NULL_TREE; - tree tdecl; - - if ((int) rid_index < (int) RID_MAX) - rname = ridpointers[(int) rid_index]; - if (name) - tname = get_identifier (name); - - if (tname) - { -#if 0 /* not yet, should get fixed properly later */ - tdecl = pushdecl (make_type_decl (tname, type)); -#else - tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); -#endif - set_identifier_type_value (tname, NULL_TREE); - if ((int) rid_index < (int) RID_MAX) - IDENTIFIER_GLOBAL_VALUE (tname) = tdecl; - } - if (rname != NULL_TREE) - { - if (tname != NULL_TREE) - { - set_identifier_type_value (rname, NULL_TREE); - IDENTIFIER_GLOBAL_VALUE (rname) = tdecl; - } - else - { -#if 0 /* not yet, should get fixed properly later */ - tdecl = pushdecl (make_type_decl (rname, type)); -#else - tdecl = pushdecl (build_decl (TYPE_DECL, rname, type)); -#endif - set_identifier_type_value (rname, NULL_TREE); - } - } - - if (flag_dossier) - { - if (builtin_type_tdescs_len+5 >= builtin_type_tdescs_max) - { - builtin_type_tdescs_max *= 2; - builtin_type_tdescs_arr - = (tree *)xrealloc (builtin_type_tdescs_arr, - builtin_type_tdescs_max * sizeof (tree)); - } - builtin_type_tdescs_arr[builtin_type_tdescs_len++] = type; - if (TREE_CODE (type) != POINTER_TYPE) - { - builtin_type_tdescs_arr[builtin_type_tdescs_len++] - = build_pointer_type (type); - builtin_type_tdescs_arr[builtin_type_tdescs_len++] - = build_type_variant (TYPE_POINTER_TO (type), 1, 0); - } - if (TREE_CODE (type) != VOID_TYPE) - { - builtin_type_tdescs_arr[builtin_type_tdescs_len++] - = build_reference_type (type); - builtin_type_tdescs_arr[builtin_type_tdescs_len++] - = build_type_variant (TYPE_REFERENCE_TO (type), 1, 0); - } - } -} - -static void -output_builtin_tdesc_entries () -{ - extern struct obstack permanent_obstack; - - /* If there's more than one main in this file, don't crash. */ - if (builtin_type_tdescs_arr == 0) - return; - - push_obstacks (&permanent_obstack, &permanent_obstack); - while (builtin_type_tdescs_len > 0) - { - tree type = builtin_type_tdescs_arr[--builtin_type_tdescs_len]; - tree tdesc = build_t_desc (type, 0); - TREE_ASM_WRITTEN (tdesc) = 0; - build_t_desc (type, 2); - } - free (builtin_type_tdescs_arr); - builtin_type_tdescs_arr = 0; - pop_obstacks (); -} - -/* Push overloaded decl, in global scope, with one argument so it - can be used as a callback from define_function. */ -static void -push_overloaded_decl_1 (x) - tree x; -{ - push_overloaded_decl (x, 0); -} - -/* Create the predefined scalar types of C, - and some nodes representing standard constants (0, 1, (void *)0). - Initialize the global binding level. - Make definitions for built-in primitive functions. */ - -void -init_decl_processing () -{ - tree decl; - register tree endlink, int_endlink, double_endlink, ptr_endlink; - tree fields[20]; - /* Either char* or void*. */ - tree traditional_ptr_type_node; - /* Data type of memcpy. */ - tree memcpy_ftype; - int wchar_type_size; - - /* Have to make these distinct before we try using them. */ - lang_name_cplusplus = get_identifier ("C++"); - lang_name_c = get_identifier ("C"); - - /* Initially, C. */ - current_lang_name = lang_name_c; - - current_function_decl = NULL_TREE; - named_labels = NULL_TREE; - named_label_uses = NULL_TREE; - current_binding_level = NULL_BINDING_LEVEL; - free_binding_level = NULL_BINDING_LEVEL; - - /* Because most segmentation signals can be traced back into user - code, catch them and at least give the user a chance of working - around compiler bugs. */ - signal (SIGSEGV, sigsegv); - - /* We will also catch aborts in the back-end through sigsegv and give the - user a chance to see where the error might be, and to defeat aborts in - the back-end when there have been errors previously in their code. */ -#ifdef SIGIOT - signal (SIGIOT, sigsegv); -#endif -#ifdef SIGILL - signal (SIGILL, sigsegv); -#endif -#ifdef SIGABRT - signal (SIGABRT, sigsegv); -#endif - - gcc_obstack_init (&decl_obstack); - if (flag_dossier) - { - builtin_type_tdescs_max = 100; - builtin_type_tdescs_arr = (tree *)xmalloc (100 * sizeof (tree)); - } - - /* Must lay these out before anything else gets laid out. */ - error_mark_node = make_node (ERROR_MARK); - TREE_PERMANENT (error_mark_node) = 1; - TREE_TYPE (error_mark_node) = error_mark_node; - error_mark_list = build_tree_list (error_mark_node, error_mark_node); - TREE_TYPE (error_mark_list) = error_mark_node; - - pushlevel (0); /* make the binding_level structure for global names. */ - global_binding_level = current_binding_level; - - this_identifier = get_identifier (THIS_NAME); - in_charge_identifier = get_identifier (IN_CHARGE_NAME); - - /* Define `int' and `char' first so that dbx will output them first. */ - - integer_type_node = make_signed_type (INT_TYPE_SIZE); - record_builtin_type (RID_INT, NULL_PTR, integer_type_node); - - /* Define `char', which is like either `signed char' or `unsigned char' - but not the same as either. */ - - char_type_node = - (flag_signed_char - ? make_signed_type (CHAR_TYPE_SIZE) - : make_unsigned_type (CHAR_TYPE_SIZE)); - record_builtin_type (RID_CHAR, "char", char_type_node); - - long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); - record_builtin_type (RID_LONG, "long int", long_integer_type_node); - - unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); - record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); - - long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long unsigned int", long_unsigned_type_node); - record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); - - /* `unsigned long' is the standard type for sizeof. - Traditionally, use a signed type. - Note that stddef.h uses `unsigned long', - and this must agree, even of long and int are the same size. */ - if (flag_traditional) - sizetype = long_integer_type_node; - else - sizetype - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); - - ptrdiff_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); - - TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype; - TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype; - - short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); - record_builtin_type (RID_SHORT, "short int", short_integer_type_node); - long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long long int", long_long_integer_type_node); - short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); - record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node); - record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node); - long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long long unsigned int", long_long_unsigned_type_node); - record_builtin_type (RID_MAX, "long long unsigned", long_long_unsigned_type_node); - - /* Define both `signed char' and `unsigned char'. */ - signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); - record_builtin_type (RID_MAX, "signed char", signed_char_type_node); - unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node); - - /* These are types that type_for_size and type_for_mode use. */ - intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node)); - intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node)); - intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); - intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); - unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); - unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node)); - unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); - unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); - - float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; - record_builtin_type (RID_FLOAT, NULL, float_type_node); - layout_type (float_type_node); - - double_type_node = make_node (REAL_TYPE); - if (flag_short_double) - TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE; - else - TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; - record_builtin_type (RID_DOUBLE, NULL, double_type_node); - layout_type (double_type_node); - - long_double_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; - record_builtin_type (RID_MAX, "long double", long_double_type_node); - layout_type (long_double_type_node); - - integer_zero_node = build_int_2 (0, 0); - TREE_TYPE (integer_zero_node) = integer_type_node; - integer_one_node = build_int_2 (1, 0); - TREE_TYPE (integer_one_node) = integer_type_node; - integer_two_node = build_int_2 (2, 0); - TREE_TYPE (integer_two_node) = integer_type_node; - integer_three_node = build_int_2 (3, 0); - TREE_TYPE (integer_three_node) = integer_type_node; - empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - - /* These are needed by stor-layout.c. */ - size_zero_node = size_int (0); - size_one_node = size_int (1); - - void_type_node = make_node (VOID_TYPE); - record_builtin_type (RID_VOID, NULL, void_type_node); - layout_type (void_type_node); /* Uses integer_zero_node. */ - void_list_node = build_tree_list (NULL_TREE, void_type_node); - TREE_PARMLIST (void_list_node) = 1; - - null_pointer_node = build_int_2 (0, 0); - TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); - layout_type (TREE_TYPE (null_pointer_node)); - - /* Used for expressions that do nothing, but are not errors. */ - void_zero_node = build_int_2 (0, 0); - TREE_TYPE (void_zero_node) = void_type_node; - - string_type_node = build_pointer_type (char_type_node); - const_string_type_node = build_pointer_type (build_type_variant (char_type_node, 1, 0)); - record_builtin_type (RID_MAX, NULL, string_type_node); - - /* make a type for arrays of 256 characters. - 256 is picked randomly because we have a type for integers from 0 to 255. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node - = build_array_type (char_type_node, unsigned_char_type_node); - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, unsigned_char_type_node); - - /* This is just some anonymous class type. Nobody should ever - need to look inside this envelope. */ - class_star_type_node = build_pointer_type (make_lang_type (RECORD_TYPE)); - - default_function_type - = build_function_type (integer_type_node, NULL_TREE); - build_pointer_type (default_function_type); - - ptr_type_node = build_pointer_type (void_type_node); - const_ptr_type_node = build_pointer_type (build_type_variant (void_type_node, 1, 0)); - record_builtin_type (RID_MAX, NULL, ptr_type_node); - endlink = void_list_node; - int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); - double_endlink = tree_cons (NULL_TREE, double_type_node, endlink); - ptr_endlink = tree_cons (NULL_TREE, ptr_type_node, endlink); - - double_ftype_double - = build_function_type (double_type_node, double_endlink); - - double_ftype_double_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, double_type_node, double_endlink)); - - int_ftype_int - = build_function_type (integer_type_node, int_endlink); - - long_ftype_long - = build_function_type (long_integer_type_node, - tree_cons (NULL_TREE, long_integer_type_node, endlink)); - - void_ftype_ptr_ptr_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - int_endlink))); - - int_ftype_cptr_cptr_sizet - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)))); - - void_ftype_ptr_int_int - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, integer_type_node, - int_endlink))); - - string_ftype_ptr_ptr /* strcpy prototype */ - = build_function_type (string_type_node, - tree_cons (NULL_TREE, string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - int_ftype_string_string /* strcmp prototype */ - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - sizet_ftype_string /* strlen prototype */ - = build_function_type (sizetype, - tree_cons (NULL_TREE, const_string_type_node, - endlink)); - - traditional_ptr_type_node - = (flag_traditional ? string_type_node : ptr_type_node); - - memcpy_ftype /* memcpy prototype */ - = build_function_type (traditional_ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)))); - -#ifdef VTABLE_USES_MASK - /* This is primarily for virtual function definition. We - declare an array of `void *', which can later be - converted to the appropriate function pointer type. - To do pointers to members, we need a mask which can - distinguish an index value into a virtual function table - from an address. */ - vtbl_mask = build_int_2 (~((HOST_WIDE_INT) VINDEX_MAX - 1), -1); -#endif - - vtbl_type_node - = build_array_type (ptr_type_node, NULL_TREE); - layout_type (vtbl_type_node); - vtbl_type_node = build_type_variant (vtbl_type_node, 1, 0); - record_builtin_type (RID_MAX, NULL, vtbl_type_node); - - builtin_function ("__builtin_constant_p", int_ftype_int, - BUILT_IN_CONSTANT_P, NULL_PTR); - - builtin_function ("__builtin_alloca", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)), - BUILT_IN_ALLOCA, "alloca"); -#if 0 - builtin_function ("alloca", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)), - BUILT_IN_ALLOCA, NULL_PTR); -#endif - - builtin_function ("__builtin_abs", int_ftype_int, - BUILT_IN_ABS, NULL_PTR); - builtin_function ("__builtin_fabs", double_ftype_double, - BUILT_IN_FABS, NULL_PTR); - builtin_function ("__builtin_labs", long_ftype_long, - BUILT_IN_LABS, NULL_PTR); - builtin_function ("__builtin_ffs", int_ftype_int, - BUILT_IN_FFS, NULL_PTR); - builtin_function ("__builtin_fsqrt", double_ftype_double, - BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("__builtin_sin", double_ftype_double, - BUILT_IN_SIN, "sin"); - builtin_function ("__builtin_cos", double_ftype_double, - BUILT_IN_COS, "cos"); - builtin_function ("__builtin_saveregs", - build_function_type (ptr_type_node, NULL_TREE), - BUILT_IN_SAVEREGS, NULL_PTR); -/* EXPAND_BUILTIN_VARARGS is obsolete. */ -#if 0 - builtin_function ("__builtin_varargs", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)), - BUILT_IN_VARARGS, NULL_PTR); -#endif - builtin_function ("__builtin_classify_type", default_function_type, - BUILT_IN_CLASSIFY_TYPE, NULL_PTR); - builtin_function ("__builtin_next_arg", - build_function_type (ptr_type_node, endlink), - BUILT_IN_NEXT_ARG, NULL_PTR); - builtin_function ("__builtin_args_info", - build_function_type (integer_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink)), - BUILT_IN_ARGS_INFO, NULL_PTR); - - /* Currently under experimentation. */ - builtin_function ("__builtin_memcpy", memcpy_ftype, - BUILT_IN_MEMCPY, "memcpy"); - builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet, - BUILT_IN_MEMCMP, "memcmp"); - builtin_function ("__builtin_strcmp", int_ftype_string_string, - BUILT_IN_STRCMP, "strcmp"); - builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr, - BUILT_IN_STRCPY, "strcpy"); - builtin_function ("__builtin_strlen", sizet_ftype_string, - BUILT_IN_STRLEN, "strlen"); - - if (!flag_no_builtin) - { -#if 0 /* These do not work well with libg++. */ - builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR); - builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR); -#endif - builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR); - builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP, - NULL_PTR); - builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, NULL_PTR); - builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, NULL_PTR); - builtin_function ("strlen", sizet_ftype_string, BUILT_IN_STRLEN, NULL_PTR); - builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); - builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); - } - -#if 0 - /* Support for these has not been written in either expand_builtin - or build_function_call. */ - builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, 0); - builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, 0); - builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, 0); - builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, 0); - builtin_function ("__builtin_fmod", double_ftype_double_double, BUILT_IN_FMOD, 0); - builtin_function ("__builtin_frem", double_ftype_double_double, BUILT_IN_FREM, 0); - builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET, 0); - builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, 0); - builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, 0); -#endif - - /* C++ extensions */ - - unknown_type_node = make_node (UNKNOWN_TYPE); -#if 0 /* not yet, should get fixed properly later */ - pushdecl (make_type_decl (get_identifier ("unknown type"), - unknown_type_node)); -#else - decl = pushdecl (build_decl (TYPE_DECL, get_identifier ("unknown type"), - unknown_type_node)); - /* Make sure the "unknown type" typedecl gets ignored for debug info. */ - DECL_IGNORED_P (decl) = 1; -#endif - TYPE_SIZE (unknown_type_node) = TYPE_SIZE (void_type_node); - TYPE_ALIGN (unknown_type_node) = 1; - TYPE_MODE (unknown_type_node) = TYPE_MODE (void_type_node); - /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ - TREE_TYPE (unknown_type_node) = unknown_type_node; - /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result. */ - TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; - TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; - - /* This is special for C++ so functions can be overloaded. */ - wchar_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); - wchar_type_size = TYPE_PRECISION (wchar_type_node); - signed_wchar_type_node = make_signed_type (wchar_type_size); - unsigned_wchar_type_node = make_unsigned_type (wchar_type_size); - wchar_type_node - = TREE_UNSIGNED (wchar_type_node) - ? unsigned_wchar_type_node - : signed_wchar_type_node; - record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node); - - /* This is for wide string constants. */ - wchar_array_type_node - = build_array_type (wchar_type_node, unsigned_char_type_node); - - /* This is a hack that should go away when we deliver the - real gc code. */ - if (flag_gc) - { - builtin_function ("__gc_main", default_function_type, NOT_BUILT_IN, 0); - pushdecl (lookup_name (get_identifier ("__gc_main"), 0)); - } - - /* Simplify life by making a "vtable_entry_type". Give its - fields names so that the debugger can use them. */ - - vtable_entry_type = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_DELTA_NAME), short_integer_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_INDEX_NAME), short_integer_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier (VTABLE_PFN_NAME), ptr_type_node); - finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, - double_type_node); - - /* Make this part of an invisible union. */ - fields[3] = copy_node (fields[2]); - TREE_TYPE (fields[3]) = short_integer_type_node; - DECL_NAME (fields[3]) = get_identifier (VTABLE_DELTA2_NAME); - DECL_MODE (fields[3]) = TYPE_MODE (short_integer_type_node); - DECL_SIZE (fields[3]) = TYPE_SIZE (short_integer_type_node); - TREE_UNSIGNED (fields[3]) = 0; - TREE_CHAIN (fields[2]) = fields[3]; - vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0); - record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); - - if (flag_dossier) - { - /* Must build __t_desc type. Currently, type descriptors look like this: - - struct __t_desc - { - const char *name; - int size; - int bits; - struct __t_desc *points_to; - int ivars_count, meths_count; - struct __i_desc *ivars[]; - struct __m_desc *meths[]; - struct __t_desc *parents[]; - struct __t_desc *vbases[]; - int offsets[]; - }; - - ...as per Linton's paper. */ - - __t_desc_type_node = make_lang_type (RECORD_TYPE); - __i_desc_type_node = make_lang_type (RECORD_TYPE); - __m_desc_type_node = make_lang_type (RECORD_TYPE); - __t_desc_array_type = build_array_type (TYPE_POINTER_TO (__t_desc_type_node), NULL_TREE); - __i_desc_array_type = build_array_type (TYPE_POINTER_TO (__i_desc_type_node), NULL_TREE); - __m_desc_array_type = build_array_type (TYPE_POINTER_TO (__m_desc_type_node), NULL_TREE); - - fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"), - string_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("size"), - unsigned_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("bits"), - unsigned_type_node); - fields[3] = build_lang_field_decl (FIELD_DECL, get_identifier ("points_to"), - TYPE_POINTER_TO (__t_desc_type_node)); - fields[4] = build_lang_field_decl (FIELD_DECL, - get_identifier ("ivars_count"), - integer_type_node); - fields[5] = build_lang_field_decl (FIELD_DECL, - get_identifier ("meths_count"), - integer_type_node); - fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("ivars"), - build_pointer_type (__i_desc_array_type)); - fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("meths"), - build_pointer_type (__m_desc_array_type)); - fields[8] = build_lang_field_decl (FIELD_DECL, get_identifier ("parents"), - build_pointer_type (__t_desc_array_type)); - fields[9] = build_lang_field_decl (FIELD_DECL, get_identifier ("vbases"), - build_pointer_type (__t_desc_array_type)); - fields[10] = build_lang_field_decl (FIELD_DECL, get_identifier ("offsets"), - build_pointer_type (integer_type_node)); - finish_builtin_type (__t_desc_type_node, "__t_desc", fields, 10, integer_type_node); - - /* ivar descriptors look like this: - - struct __i_desc - { - const char *name; - int offset; - struct __t_desc *type; - }; - */ - - fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"), - string_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("offset"), - integer_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"), - TYPE_POINTER_TO (__t_desc_type_node)); - finish_builtin_type (__i_desc_type_node, "__i_desc", fields, 2, integer_type_node); - - /* method descriptors look like this: - - struct __m_desc - { - const char *name; - int vindex; - struct __t_desc *vcontext; - struct __t_desc *return_type; - void (*address)(); - short parm_count; - short required_parms; - struct __t_desc *parm_types[]; - }; - */ - - fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"), - string_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("vindex"), - integer_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("vcontext"), - TYPE_POINTER_TO (__t_desc_type_node)); - fields[3] = build_lang_field_decl (FIELD_DECL, get_identifier ("return_type"), - TYPE_POINTER_TO (__t_desc_type_node)); - fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("address"), - build_pointer_type (default_function_type)); - fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_count"), - short_integer_type_node); - fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("required_parms"), - short_integer_type_node); - fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_types"), - build_pointer_type (build_array_type (TYPE_POINTER_TO (__t_desc_type_node), NULL_TREE))); - finish_builtin_type (__m_desc_type_node, "__m_desc", fields, 7, integer_type_node); - } - - /* Now, C++. */ - current_lang_name = lang_name_cplusplus; - if (flag_dossier) - { - int i = builtin_type_tdescs_len; - while (i > 0) - { - tree tdesc = build_t_desc (builtin_type_tdescs_arr[--i], 0); - TREE_ASM_WRITTEN (tdesc) = 1; - TREE_PUBLIC (TREE_OPERAND (tdesc, 0)) = 1; - } - } - - auto_function (ansi_opname[(int) NEW_EXPR], - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, sizetype, - void_list_node)), - NOT_BUILT_IN); - auto_function (ansi_opname[(int) DELETE_EXPR], - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)), - NOT_BUILT_IN); - - abort_fndecl - = define_function ("abort", - build_function_type (void_type_node, void_list_node), - NOT_BUILT_IN, 0, 0); - - unhandled_exception_fndecl - = define_function ("__unhandled_exception", - build_function_type (void_type_node, NULL_TREE), - NOT_BUILT_IN, 0, 0); - - /* Perform other language dependent initializations. */ - init_class_processing (); - init_init_processing (); - init_search_processing (); - - if (flag_handle_exceptions) - { - if (flag_handle_exceptions == 2) - /* Too much trouble to inline all the trys needed for this. */ - flag_this_is_variable = 2; - init_exception_processing (); - } - if (flag_gc) - init_gc_processing (); - if (flag_no_inline) - flag_inline_functions = 0, flag_default_inline = 0; - if (flag_cadillac) - init_cadillac (); - - /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ - declare_function_name (); - - /* Warnings about failure to return values are too valuable to forego. */ - warn_return_type = 1; -} - -/* Make a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. - FUNCTION_CODE tells later passes how to compile calls to this function. - See tree.h for its possible values. - - If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, - the name to be called if we can't opencode the function. */ - -tree -define_function (name, type, function_code, pfn, library_name) - char *name; - tree type; - enum built_in_function function_code; - void (*pfn)(); - char *library_name; -{ - tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, - we cannot change DECL_ASSEMBLER_NAME until we have installed this - function in the namespace. */ - if (pfn) (*pfn) (decl); - if (library_name) - DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); - make_function_rtl (decl); - if (function_code != NOT_BUILT_IN) - { - DECL_BUILT_IN (decl) = 1; - DECL_SET_FUNCTION_CODE (decl, function_code); - } - return decl; -} - -/* Called when a declaration is seen that contains no names to declare. - If its type is a reference to a structure, union or enum inherited - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. - - C++: may have to grok the declspecs to learn about static, - complain for anonymous unions. */ - -void -shadow_tag (declspecs) - tree declspecs; -{ - int found_tag = 0; - int warned = 0; - register tree link; - register enum tree_code code, ok_code = ERROR_MARK; - register tree t = NULL_TREE; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - register tree value = TREE_VALUE (link); - - code = TREE_CODE (value); - if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE) - /* Used to test also that TYPE_SIZE (value) != 0. - That caused warning for `struct foo;' at top level in the file. */ - { - register tree name = TYPE_NAME (value); - - if (name == NULL_TREE) - name = lookup_tag_reverse (value, NULL_TREE); - - if (name && TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - if (class_binding_level) - t = lookup_tag (code, name, class_binding_level, 1); - else - t = lookup_tag (code, name, current_binding_level, 1); - - if (t == NULL_TREE) - { - push_obstacks (&permanent_obstack, &permanent_obstack); - if (IS_AGGR_TYPE_CODE (code)) - t = make_lang_type (code); - else - t = make_node (code); - pushtag (name, t); - pop_obstacks (); - ok_code = code; - break; - } - else if (name != NULL_TREE || code == ENUMERAL_TYPE) - ok_code = code; - - if (ok_code != ERROR_MARK) - found_tag++; - else - { - if (!warned) - pedwarn ("useless keyword or type name in declaration"); - warned = 1; - } - } - } - - /* This is where the variables in an anonymous union are - declared. An anonymous union declaration looks like: - union { ... } ; - because there is no declarator after the union, the parser - sends that declaration here. */ - if (ok_code == UNION_TYPE - && t != NULL_TREE - && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (TYPE_NAME (t))) - || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))) - { - /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have - function members. */ - if (TYPE_FIELDS (t)) - { - tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, NULL_TREE); - finish_anon_union (decl); - } - else - error ("anonymous union cannot have a function member"); - } - else if (ok_code == RECORD_TYPE - && found_tag == 1 - && TYPE_LANG_SPECIFIC (t) - && CLASSTYPE_DECLARED_EXCEPTION (t)) - { - if (TYPE_SIZE (t)) - error_with_aggr_type (t, "redeclaration of exception `%s'"); - else - { - tree ename, decl; - - push_obstacks (&permanent_obstack, &permanent_obstack); - - pushclass (t, 0); - finish_exception (t, NULL_TREE); - - ename = TYPE_NAME (t); - if (TREE_CODE (ename) == TYPE_DECL) - ename = DECL_NAME (ename); - decl = build_lang_field_decl (VAR_DECL, ename, t); - finish_exception_decl (current_class_name, decl); - end_exception_decls (); - - pop_obstacks (); - } - } - else if (!warned && found_tag > 1) - warning ("multiple types in one declaration"); -} - -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ - -tree -groktypename (typename) - tree typename; -{ - if (TREE_CODE (typename) != TREE_LIST) - return typename; - return grokdeclarator (TREE_VALUE (typename), - TREE_PURPOSE (typename), - TYPENAME, 0, NULL_TREE); -} - -/* Decode a declarator in an ordinary declaration or data definition. - This is called as soon as the type information and variable name - have been parsed, before parsing the initializer if any. - Here we create the ..._DECL node, fill in its type, - and put it on the list of decls for the current context. - The ..._DECL node is returned as the value. - - Exception: for arrays where the length is not specified, - the type is left null, to be filled in by `finish_decl'. - - Function definitions do not come here; they go to start_function - instead. However, external and forward declarations of functions - do go through here. Structure field declarations are done by - grokfield and not through here. */ - -/* Set this to zero to debug not using the temporary obstack - to parse initializers. */ -int debug_temp_inits = 1; - -tree -start_decl (declarator, declspecs, initialized, raises) - tree declspecs, declarator; - int initialized; - tree raises; -{ - register tree decl; - register tree type, tem; - tree context; - extern int have_extern_spec; - extern int used_extern_spec; - - int init_written = initialized; - - /* This should only be done once on the top most decl. */ - if (have_extern_spec && !used_extern_spec) - { - declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); - used_extern_spec = 1; - } - - decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, raises); - if (decl == NULL_TREE || decl == void_type_node) - return NULL_TREE; - - type = TREE_TYPE (decl); - - /* Don't lose if destructors must be executed at file-level. */ - if (TREE_STATIC (decl) - && TYPE_NEEDS_DESTRUCTOR (type) - && !TREE_PERMANENT (decl)) - { - push_obstacks (&permanent_obstack, &permanent_obstack); - decl = copy_node (decl); - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree itype = TYPE_DOMAIN (type); - if (itype && ! TREE_PERMANENT (itype)) - { - itype = build_index_type (copy_to_permanent (TYPE_MAX_VALUE (itype))); - type = build_cplus_array_type (TREE_TYPE (type), itype); - TREE_TYPE (decl) = type; - } - } - pop_obstacks (); - } - - /* Interesting work for this is done in `finish_exception_decl'. */ - if (TREE_CODE (type) == RECORD_TYPE - && CLASSTYPE_DECLARED_EXCEPTION (type)) - return decl; - - /* Corresponding pop_obstacks is done in `finish_decl'. */ - push_obstacks_nochange (); - - context - = (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) - ? DECL_CLASS_CONTEXT (decl) - : DECL_CONTEXT (decl); - - if (processing_template_decl) - { - tree d; - if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Declarator is a call_expr; extract arguments from it, since - grokdeclarator didn't do it. */ - tree args; - args = copy_to_permanent (last_function_parms); - if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - { - tree t = TREE_TYPE (decl); - tree decl; - - t = TYPE_METHOD_BASETYPE (t); /* type method belongs to */ - if (TREE_CODE (t) != UNINSTANTIATED_P_TYPE) - { - t = build_pointer_type (t); /* base type of `this' */ -#if 1 - /* I suspect this is wrong. */ - t = build_type_variant (t, flag_this_is_variable <= 0, - 0); /* type of `this' */ -#else - t = build_type_variant (t, 0, 0); /* type of `this' */ -#endif - t = build (PARM_DECL, t, this_identifier); - TREE_CHAIN (t) = args; - args = t; - } - } - DECL_ARGUMENTS (decl) = args; - } - d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl)); - TREE_PUBLIC (d) = TREE_PUBLIC (decl) = 0; - TREE_STATIC (d) = TREE_STATIC (decl); - DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl) - && !(context && !DECL_THIS_EXTERN (decl))); - DECL_TEMPLATE_RESULT (d) = decl; - DECL_OVERLOADED (d) = 1; - decl = d; - } - - if (context && TYPE_SIZE (context) != NULL_TREE) - { - /* If it was not explicitly declared `extern', - revoke any previous claims of DECL_EXTERNAL. */ - if (DECL_THIS_EXTERN (decl) == 0) - DECL_EXTERNAL (decl) = 0; - if (DECL_LANG_SPECIFIC (decl)) - DECL_IN_AGGR_P (decl) = 0; - pushclass (context, 2); - } - - /* If this type of object needs a cleanup, and control may - jump past it, make a new binding level so that it is cleaned - up only when it is initialized first. */ - if (TYPE_NEEDS_DESTRUCTOR (type) - && current_binding_level->more_cleanups_ok == 0) - pushlevel_temporary (1); - - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `finish_decl' to ignore the initializer once it is parsed. */ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - error ("typedef `%s' is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - break; - - case FUNCTION_DECL: - error ("function `%s' is initialized like a variable", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - break; - - default: - /* Don't allow initializations for incomplete types - except for arrays which might be completed by the initialization. */ - if (TYPE_SIZE (type) != NULL_TREE) - ; /* A complete type is ok. */ - else if (TREE_CODE (type) != ARRAY_TYPE) - { - error ("variable `%s' has initializer but incomplete type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - else if (TYPE_SIZE (TREE_TYPE (type)) == NULL_TREE) - { - error ("elements of array `%s' have incomplete type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - initialized = 0; - } - } - - if (!initialized - && TREE_CODE (decl) != TYPE_DECL - && TREE_CODE (decl) != TEMPLATE_DECL - && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl)) - { - if (TYPE_SIZE (type) == NULL_TREE) - { - error ("aggregate `%s' has incomplete type and cannot be initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - /* Change the type so that assemble_variable will give - DECL an rtl we can live with: (mem (const_int 0)). */ - TREE_TYPE (decl) = error_mark_node; - type = error_mark_node; - } - else - { - /* If any base type in the hierarchy of TYPE needs a constructor, - then we set initialized to 1. This way any nodes which are - created for the purposes of initializing this aggregate - will live as long as it does. This is necessary for global - aggregates which do not have their initializers processed until - the end of the file. */ - initialized = TYPE_NEEDS_CONSTRUCTING (type); - } - } - - if (initialized) - { - if (current_binding_level != global_binding_level - && DECL_EXTERNAL (decl)) - warning ("declaration of `%s' has `extern' and is initialized", - IDENTIFIER_POINTER (DECL_NAME (decl))); - DECL_EXTERNAL (decl) = 0; - if (current_binding_level == global_binding_level) - TREE_STATIC (decl) = 1; - - /* Tell `pushdecl' this is an initialized decl - even though we don't yet have the initializer expression. - Also tell `finish_decl' it may store the real initializer. */ - DECL_INITIAL (decl) = error_mark_node; - } - - /* Add this decl to the current binding level, but not if it - comes from another scope, e.g. a static member variable. - TEM may equal DECL or it may be a previous decl of the same name. */ - if ((TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE) - || (TREE_CODE (decl) == TEMPLATE_DECL && !global_bindings_p ()) - || TREE_CODE (type) == LANG_TYPE) - tem = decl; - else - { - tem = pushdecl (decl); - if (TREE_CODE (tem) == TREE_LIST) - { - tree tem2 = value_member (decl, tem); - if (tem2 != NULL_TREE) - tem = TREE_VALUE (tem2); - else - { - while (tem && ! decls_match (decl, TREE_VALUE (tem))) - tem = TREE_CHAIN (tem); - if (tem == NULL_TREE) - tem = decl; - else - tem = TREE_VALUE (tem); - } - } - } - -#if 0 - /* We don't do this yet for GNU C++. */ - /* For a local variable, define the RTL now. */ - if (current_binding_level != global_binding_level - /* But not if this is a duplicate decl - and we preserved the rtl from the previous one - (which may or may not happen). */ - && DECL_RTL (tem) == NULL_RTX) - { - if (TYPE_SIZE (TREE_TYPE (tem)) != NULL_TREE) - expand_decl (tem); - else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE - && DECL_INITIAL (tem) != NULL_TREE) - expand_decl (tem); - } -#endif - - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_OVERLOADED (decl)) - /* @@ Also done in start_function. */ - tem = push_overloaded_decl (tem, 1); - else if (TREE_CODE (decl) == TEMPLATE_DECL) - { - tree result = DECL_TEMPLATE_RESULT (decl); - if (DECL_CONTEXT (result) != NULL_TREE) - { - tree type; - type = DECL_CONTEXT (result); - my_friendly_assert (TREE_CODE (type) == UNINSTANTIATED_P_TYPE, 145); - if (/* TREE_CODE (result) == VAR_DECL */ 1) - { -#if 0 - tree tmpl = UPT_TEMPLATE (type); - - fprintf (stderr, "%s:%d: adding ", __FILE__, __LINE__); - print_node_brief (stderr, "", DECL_NAME (tem), 0); - fprintf (stderr, " to class %s\n", - IDENTIFIER_POINTER (DECL_NAME (tmpl))); - DECL_TEMPLATE_MEMBERS (tmpl) - = perm_tree_cons (DECL_NAME (tem), tem, - DECL_TEMPLATE_MEMBERS (tmpl)); -#endif - return tem; - } - my_friendly_abort (13); - } - else if (TREE_CODE (result) == FUNCTION_DECL) - tem = push_overloaded_decl (tem, 0); - else if (TREE_CODE (result) == VAR_DECL - || TREE_CODE (result) == TYPE_DECL) - { - error ("invalid template `%s'", - IDENTIFIER_POINTER (DECL_NAME (result))); - return NULL_TREE; - } - else - my_friendly_abort (14); - } - - if (init_written - && ! (TREE_CODE (tem) == PARM_DECL - || (TREE_READONLY (tem) - && (TREE_CODE (tem) == VAR_DECL - || TREE_CODE (tem) == FIELD_DECL)))) - { - /* When parsing and digesting the initializer, - use temporary storage. Do this even if we will ignore the value. */ - if (current_binding_level == global_binding_level && debug_temp_inits) - { - if (TYPE_NEEDS_CONSTRUCTING (type) || TREE_CODE (type) == REFERENCE_TYPE) - /* In this case, the initializer must lay down in permanent - storage, since it will be saved until `finish_file' is run. */ - ; - else - temporary_allocation (); - } - } - - if (flag_cadillac) - cadillac_start_decl (tem); - - return tem; -} - -static void -make_temporary_for_reference (decl, ctor_call, init, cleanupp) - tree decl, ctor_call, init; - tree *cleanupp; -{ - tree type = TREE_TYPE (decl); - tree target_type = TREE_TYPE (type); - tree tmp, tmp_addr; - - if (ctor_call) - { - tmp_addr = TREE_VALUE (TREE_OPERAND (ctor_call, 1)); - if (TREE_CODE (tmp_addr) == NOP_EXPR) - tmp_addr = TREE_OPERAND (tmp_addr, 0); - my_friendly_assert (TREE_CODE (tmp_addr) == ADDR_EXPR, 146); - tmp = TREE_OPERAND (tmp_addr, 0); - } - else - { - tmp = get_temp_name (target_type, - current_binding_level == global_binding_level); - tmp_addr = build_unary_op (ADDR_EXPR, tmp, 0); - } - - TREE_TYPE (tmp_addr) = build_pointer_type (target_type); - DECL_INITIAL (decl) = convert (TYPE_POINTER_TO (target_type), tmp_addr); - TREE_TYPE (DECL_INITIAL (decl)) = type; - if (TYPE_NEEDS_CONSTRUCTING (target_type)) - { - if (current_binding_level == global_binding_level) - { - /* lay this variable out now. Otherwise `output_addressed_constants' - gets confused by its initializer. */ - make_decl_rtl (tmp, NULL_PTR, 1); - static_aggregates = perm_tree_cons (init, tmp, static_aggregates); - } - else - { - if (ctor_call != NULL_TREE) - init = ctor_call; - else - init = build_method_call (tmp, constructor_name (target_type), - build_tree_list (NULL_TREE, init), - NULL_TREE, LOOKUP_NORMAL); - DECL_INITIAL (decl) = build (COMPOUND_EXPR, type, init, - DECL_INITIAL (decl)); - *cleanupp = maybe_build_cleanup (tmp); - } - } - else - { - DECL_INITIAL (tmp) = init; - TREE_STATIC (tmp) = current_binding_level == global_binding_level; - finish_decl (tmp, init, 0, 0); - } - if (TREE_STATIC (tmp)) - preserve_initializer (); -} - -/* Handle initialization of references. - These three arguments from from `finish_decl', and have the - same meaning here that they do there. */ -/* quotes on semantics can be found in ARM 8.4.3. */ -static void -grok_reference_init (decl, type, init, cleanupp) - tree decl, type, init; - tree *cleanupp; -{ - char *errstr = NULL; - int is_reference; - tree tmp; - tree this_ptr_type, actual_init; - - if (init == NULL_TREE) - { - if (DECL_LANG_SPECIFIC (decl) == 0 - || DECL_IN_AGGR_P (decl) == 0) - { - error ("variable declared as reference not initialized"); - if (TREE_CODE (decl) == VAR_DECL) - SET_DECL_REFERENCE_SLOT (decl, error_mark_node); - } - return; - } - - if (TREE_CODE (init) == TREE_LIST) - init = build_compound_expr (init); - is_reference = TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE; - tmp = is_reference ? convert_from_reference (init) : init; - - if (is_reference) - { - if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TYPE_MAIN_VARIANT (TREE_TYPE (tmp)), 0)) - errstr = "initialization of `%s' from dissimilar reference type"; - else if (TYPE_READONLY (TREE_TYPE (type)) - >= TYPE_READONLY (TREE_TYPE (TREE_TYPE (init)))) - { - is_reference = 0; - init = tmp; - } - } - else - { - if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE - && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) - { - /* Note: default conversion is only called in very - special cases. */ - init = default_conversion (init); - } - if (TREE_CODE (TREE_TYPE (type)) == TREE_CODE (TREE_TYPE (init))) - { - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TYPE_MAIN_VARIANT (TREE_TYPE (init)), 0)) - { - /* This section implements ANSI C++ June 5 1992 WP 8.4.3.5. */ - - /* A reference to a volatile T cannot be initialized with - a const T, and vice-versa. */ - if (TYPE_VOLATILE (TREE_TYPE (type)) && TREE_READONLY (init)) - errstr = "cannot initialize a reference to a volatile T with a const T"; - else if (TYPE_READONLY (TREE_TYPE (type)) && TREE_THIS_VOLATILE (init)) - errstr = "cannot initialize a reference to a const T with a volatile T"; - /* A reference to a plain T can be initialized only with - a plain T. */ - else if (!TYPE_VOLATILE (TREE_TYPE (type)) - && !TYPE_READONLY (TREE_TYPE (type))) - { - if (TREE_READONLY (init)) - errstr = "cannot initialize a reference to T with a const T"; - else if (TREE_THIS_VOLATILE (init)) - errstr = "cannot initialize a reference to T with a volatile T"; - } - } - else - init = convert (TREE_TYPE (type), init); - } - else if (init != error_mark_node - && ! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TYPE_MAIN_VARIANT (TREE_TYPE (init)), 0)) - errstr = "invalid type conversion for reference"; - } - - if (errstr) - { - /* Things did not go smoothly; look for operator& type conversion. */ - if (IS_AGGR_TYPE (TREE_TYPE (tmp))) - { - tmp = build_type_conversion (CONVERT_EXPR, type, init, 0); - if (tmp != NULL_TREE) - { - init = tmp; - if (tmp == error_mark_node) - errstr = "ambiguous pointer conversion"; - else - errstr = NULL; - is_reference = 1; - } - else - { - tmp = build_type_conversion (CONVERT_EXPR, TREE_TYPE (type), init, 0); - if (tmp != NULL_TREE) - { - init = tmp; - if (tmp == error_mark_node) - errstr = "ambiguous pointer conversion"; - else - errstr = NULL; - is_reference = 0; - } - } - } - /* Look for constructor. */ - else if (IS_AGGR_TYPE (TREE_TYPE (type)) - && TYPE_HAS_CONSTRUCTOR (TREE_TYPE (type))) - { - tmp = get_temp_name (TREE_TYPE (type), - current_binding_level == global_binding_level); - tmp = build_method_call (tmp, constructor_name (TREE_TYPE (type)), - build_tree_list (NULL_TREE, init), - NULL_TREE, LOOKUP_NORMAL); - if (tmp == NULL_TREE || tmp == error_mark_node) - { - if (TREE_CODE (decl) == VAR_DECL) - SET_DECL_REFERENCE_SLOT (decl, error_mark_node); - error_with_decl (decl, "constructor failed to build reference initializer"); - return; - } - make_temporary_for_reference (decl, tmp, init, cleanupp); - goto done; - } - } - - if (errstr) - { - error_with_decl (decl, errstr); - if (TREE_CODE (decl) == VAR_DECL) - SET_DECL_REFERENCE_SLOT (decl, error_mark_node); - return; - } - - /* In the case of initialization, it is permissible - to assign one reference to another. */ - this_ptr_type = build_pointer_type (TREE_TYPE (type)); - - if (is_reference) - { - if (TREE_SIDE_EFFECTS (init)) - DECL_INITIAL (decl) = save_expr (init); - else - DECL_INITIAL (decl) = init; - } - else if (lvalue_p (init)) - { - tmp = build_unary_op (ADDR_EXPR, init, 0); - if (TREE_CODE (tmp) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (tmp, 0)) == WITH_CLEANUP_EXPR) - { - /* Associate the cleanup with the reference so that we - don't get burned by "aggressive" cleanup policy. */ - *cleanupp = TREE_OPERAND (TREE_OPERAND (tmp, 0), 2); - TREE_OPERAND (TREE_OPERAND (tmp, 0), 2) = error_mark_node; - } - if (IS_AGGR_TYPE (TREE_TYPE (this_ptr_type))) - DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type), tmp); - else - DECL_INITIAL (decl) = convert (this_ptr_type, tmp); - - DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl)); - if (DECL_INITIAL (decl) == current_class_decl) - DECL_INITIAL (decl) = copy_node (current_class_decl); - TREE_TYPE (DECL_INITIAL (decl)) = type; - } - else if ((actual_init = unary_complex_lvalue (ADDR_EXPR, init))) - { - /* The initializer for this decl goes into its - DECL_REFERENCE_SLOT. Make sure that we can handle - multiple evaluations without ill effect. */ - if (TREE_CODE (actual_init) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (actual_init, 0)) == TARGET_EXPR) - actual_init = save_expr (actual_init); - DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type), actual_init); - DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl)); - TREE_TYPE (DECL_INITIAL (decl)) = type; - } - else if (TYPE_READONLY (TREE_TYPE (type))) - /* Section 8.4.3 allows us to make a temporary for - the initialization of const&. */ - make_temporary_for_reference (decl, NULL_TREE, init, cleanupp); - else - { - error_with_decl (decl, "type mismatch in initialization of `%s' (use `const')"); - DECL_INITIAL (decl) = error_mark_node; - } - - done: - /* ?? Can this be optimized in some cases to - hand back the DECL_INITIAL slot?? */ - if (TYPE_SIZE (TREE_TYPE (type))) - { - init = convert_from_reference (decl); - if (TREE_PERMANENT (decl)) - init = copy_to_permanent (init); - SET_DECL_REFERENCE_SLOT (decl, init); - } - - if (TREE_STATIC (decl) && ! TREE_CONSTANT (DECL_INITIAL (decl))) - { - expand_static_init (decl, DECL_INITIAL (decl)); - DECL_INITIAL (decl) = NULL_TREE; - } -} - -/* Finish processing of a declaration; - install its line number and initial value. - If the length of an array type is not known before, - it must be determined now, from the initial value, or it is an error. - - Call `pop_obstacks' iff NEED_POP is nonzero. - - For C++, `finish_decl' must be fairly evasive: it must keep initializers - for aggregates that have constructors alive on the permanent obstack, - so that the global initializing functions can be written at the end. - - INIT0 holds the value of an initializer that should be allowed to escape - the normal rules. - - For functions that take default parameters, DECL points to its - "maximal" instantiation. `finish_decl' must then also declared its - subsequently lower and lower forms of instantiation, checking for - ambiguity as it goes. This can be sped up later. */ - -void -finish_decl (decl, init, asmspec_tree, need_pop) - tree decl, init; - tree asmspec_tree; - int need_pop; -{ - register tree type; - tree cleanup = NULL_TREE, ttype; - int was_incomplete; - int temporary = allocation_temporary_p (); - char *asmspec = NULL; - int was_readonly = 0; - - /* If this is 0, then we did not change obstacks. */ - if (! decl) - { - if (init) - error ("assignment (not initialization) in declaration"); - return; - } - - if (asmspec_tree) - { - asmspec = TREE_STRING_POINTER (asmspec_tree); - /* Zero out old RTL, since we will rewrite it. */ - DECL_RTL (decl) = NULL_RTX; - } - - /* If the type of the thing we are declaring either has - a constructor, or has a virtual function table pointer, - AND its initialization was accepted by `start_decl', - then we stayed on the permanent obstack through the - declaration, otherwise, changed obstacks as GCC would. */ - - type = TREE_TYPE (decl); - - was_incomplete = (DECL_SIZE (decl) == NULL_TREE); - - /* Take care of TYPE_DECLs up front. */ - if (TREE_CODE (decl) == TYPE_DECL) - { - if (init && DECL_INITIAL (decl)) - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = type = TREE_TYPE (init); - DECL_INITIAL (decl) = init = NULL_TREE; - } - if (IS_AGGR_TYPE (type) && DECL_NAME (decl)) - { - if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) - warning ("shadowing previous type declaration of `%s'", - IDENTIFIER_POINTER (DECL_NAME (decl))); - set_identifier_type_value (DECL_NAME (decl), type); - CLASSTYPE_GOT_SEMICOLON (type) = 1; - } - GNU_xref_decl (current_function_decl, decl); - rest_of_decl_compilation (decl, NULL_PTR, - DECL_CONTEXT (decl) == NULL_TREE, 0); - goto finish_end; - } - if (type != error_mark_node && IS_AGGR_TYPE (type) - && CLASSTYPE_DECLARED_EXCEPTION (type)) - { - finish_exception_decl (NULL_TREE, decl); - CLASSTYPE_GOT_SEMICOLON (type) = 1; - goto finish_end; - } - if (TREE_CODE (decl) != FUNCTION_DECL) - { - ttype = target_type (type); -#if 0 /* WTF? -KR - Leave this out until we can figure out why it was - needed/desirable in the first place. Then put a comment - here explaining why. Or just delete the code if no ill - effects arise. */ - if (TYPE_NAME (ttype) - && TREE_CODE (TYPE_NAME (ttype)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (ttype))) - { - tree old_id = TYPE_IDENTIFIER (ttype); - char *newname = (char *)alloca (IDENTIFIER_LENGTH (old_id) + 2); - /* Need to preserve template data for UPT nodes. */ - tree old_template = IDENTIFIER_TEMPLATE (old_id); - newname[0] = '_'; - bcopy (IDENTIFIER_POINTER (old_id), newname + 1, - IDENTIFIER_LENGTH (old_id) + 1); - old_id = get_identifier (newname); - lookup_tag_reverse (ttype, old_id); - TYPE_IDENTIFIER (ttype) = old_id; - IDENTIFIER_TEMPLATE (old_id) = old_template; - } -#endif - } - - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl) - && TYPE_NEEDS_CONSTRUCTING (type)) - { - - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ - was_readonly = 1; - TREE_READONLY (decl) = 0; - } - - if (TREE_CODE (decl) == FIELD_DECL) - { - if (init && init != error_mark_node) - my_friendly_assert (TREE_PERMANENT (init), 147); - - if (asmspec) - { - /* This must override the asm specifier which was placed - by grokclassfn. Lay this out fresh. - - @@ Should emit an error if this redefines an asm-specified - @@ name, or if we have already used the function's name. */ - DECL_RTL (TREE_TYPE (decl)) = NULL_RTX; - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); - make_decl_rtl (decl, asmspec, 0); - } - } - /* If `start_decl' didn't like having an initialization, ignore it now. */ - else if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) - init = NULL_TREE; - else if (DECL_EXTERNAL (decl)) - ; - else if (TREE_CODE (type) == REFERENCE_TYPE) - { - grok_reference_init (decl, type, init, &cleanup); - init = NULL_TREE; - } - - GNU_xref_decl (current_function_decl, decl); - - if (TREE_CODE (decl) == FIELD_DECL || DECL_EXTERNAL (decl)) - ; - else if (TREE_CODE (decl) == CONST_DECL) - { - my_friendly_assert (TREE_CODE (decl) != REFERENCE_TYPE, 148); - - DECL_INITIAL (decl) = init; - - /* This will keep us from needing to worry about our obstacks. */ - my_friendly_assert (init != NULL_TREE, 149); - init = NULL_TREE; - } - else if (init) - { - if (TYPE_NEEDS_CONSTRUCTING (type)) - { - if (TREE_CODE (type) == ARRAY_TYPE) - init = digest_init (type, init, (tree *) 0); - else if (TREE_CODE (init) == CONSTRUCTOR - && CONSTRUCTOR_ELTS (init) != NULL_TREE) - { - error_with_decl (decl, "`%s' must be initialized by constructor, not by `{...}'"); - init = error_mark_node; - } -#if 0 - /* fix this in `build_functional_cast' instead. - Here's the trigger code: - - struct ostream - { - ostream (); - ostream (int, char *); - ostream (char *); - operator char *(); - ostream (void *); - operator void *(); - operator << (int); - }; - int buf_size = 1024; - static char buf[buf_size]; - const char *debug(int i) { - char *b = &buf[0]; - ostream o = ostream(buf_size, b); - o << i; - return buf; - } - */ - - else if (TREE_CODE (init) == TARGET_EXPR - && TREE_CODE (TREE_OPERAND (init, 1) == NEW_EXPR)) - { - /* User wrote something like `foo x = foo (args)' */ - my_friendly_assert (TREE_CODE (TREE_OPERAND (init, 0)) == VAR_DECL, 150); - my_friendly_assert (DECL_NAME (TREE_OPERAND (init, 0)) == NULL_TREE, 151); - - /* User wrote exactly `foo x = foo (args)' */ - if (TYPE_MAIN_VARIANT (type) == TREE_TYPE (init)) - { - init = build (CALL_EXPR, TREE_TYPE (init), - TREE_OPERAND (TREE_OPERAND (init, 1), 0), - TREE_OPERAND (TREE_OPERAND (init, 1), 1), 0); - TREE_SIDE_EFFECTS (init) = 1; - } - } -#endif - - /* We must hide the initializer so that expand_decl - won't try to do something it does not understand. */ - if (current_binding_level == global_binding_level) - { - tree value = digest_init (type, empty_init_node, (tree *) 0); - DECL_INITIAL (decl) = value; - } - else - DECL_INITIAL (decl) = error_mark_node; - } - else - { - if (TREE_CODE (init) != TREE_VEC) - init = store_init_value (decl, init); - - if (init) - /* Don't let anyone try to initialize this variable - until we are ready to do so. */ - DECL_INITIAL (decl) = error_mark_node; - } - } - else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' - && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) - { - tree ctype = type; - while (TREE_CODE (ctype) == ARRAY_TYPE) - ctype = TREE_TYPE (ctype); - if (! TYPE_NEEDS_CONSTRUCTOR (ctype)) - { - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype)) - error_with_decl (decl, "structure `%s' with uninitialized const members"); - if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype)) - error_with_decl (decl, "structure `%s' with uninitialized reference members"); - } - - if (TREE_CODE (decl) == VAR_DECL - && !TYPE_NEEDS_CONSTRUCTING (type) - && (TYPE_READONLY (type) || TREE_READONLY (decl))) - error_with_decl (decl, "uninitialized const `%s'"); - - /* Initialize variables in need of static initialization - with `empty_init_node' to keep assemble_variable from putting them - in the wrong program space. (Common storage is okay for non-public - uninitialized data; the linker can't match it with storage from other - files, and we may save some disk space.) */ - if (flag_pic == 0 - && TREE_STATIC (decl) - && TREE_PUBLIC (decl) - && ! DECL_EXTERNAL (decl) - && TREE_CODE (decl) == VAR_DECL - && TYPE_NEEDS_CONSTRUCTING (type) - && (DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node)) - { - tree value = digest_init (type, empty_init_node, (tree *) 0); - DECL_INITIAL (decl) = value; - } - } - else if (TREE_CODE (decl) == VAR_DECL - && TREE_CODE (type) != REFERENCE_TYPE - && (TYPE_READONLY (type) || TREE_READONLY (decl))) - { - /* ``Unless explicitly declared extern, a const object does not have - external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 - However, if it's `const int foo = 1; const int foo;', don't complain - about the second decl, since it does have an initializer before. */ - if (! DECL_INITIAL (decl) && (!pedantic || !current_class_type)) - error_with_decl (decl, "uninitialized const `%s'"); - } - - /* For top-level declaration, the initial value was read in - the temporary obstack. MAXINDEX, rtl, etc. to be made below - must go in the permanent obstack; but don't discard the - temporary data yet. */ - - if (current_binding_level == global_binding_level && temporary) - end_temporary_allocation (); - - /* Deduce size of array from initialization, if not already known. */ - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == NULL_TREE - && TREE_CODE (decl) != TYPE_DECL) - { - int do_default - = (TREE_STATIC (decl) - /* Even if pedantic, an external linkage array - may have incomplete type at first. */ - ? pedantic && DECL_EXTERNAL (decl) - : !DECL_EXTERNAL (decl)); - tree initializer = init ? init : DECL_INITIAL (decl); - int failure = complete_array_type (type, initializer, do_default); - - if (failure == 1) - error_with_decl (decl, "initializer fails to determine size of `%s'"); - - if (failure == 2) - { - if (do_default) - error_with_decl (decl, "array size missing in `%s'"); - else if (!pedantic && TREE_STATIC (decl)) - DECL_EXTERNAL (decl) = 1; - } - - if (pedantic && TYPE_DOMAIN (type) != NULL_TREE - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) - error_with_decl (decl, "zero-size array `%s'"); - - layout_decl (decl, 0); - } - - if (TREE_CODE (decl) == VAR_DECL) - { - if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE) - { - /* A static variable with an incomplete type: - that is an error if it is initialized or `static'. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - if (!DECL_EXTERNAL (decl) || DECL_INITIAL (decl) != NULL_TREE) - error_with_decl (decl, "storage size of `%s' isn't known"); - init = NULL_TREE; - } - else if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) - { - /* An automatic variable with an incomplete type: that is an error. - Don't talk about array types here, since we took care of that - message in grokdeclarator. */ - error_with_decl (decl, "storage size of `%s' isn't known"); - TREE_TYPE (decl) = error_mark_node; - } - else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - - if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) - && DECL_SIZE (decl) != NULL_TREE - && ! TREE_CONSTANT (DECL_SIZE (decl))) - error_with_decl (decl, "storage size of `%s' isn't constant"); - - if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type)) - { - int yes = suspend_momentary (); - - /* If INIT comes from a functional cast, use the cleanup - we built for that. Otherwise, make our own cleanup. */ - if (init && TREE_CODE (init) == WITH_CLEANUP_EXPR - && comptypes (TREE_TYPE (decl), TREE_TYPE (init), 1)) - { - cleanup = TREE_OPERAND (init, 2); - init = TREE_OPERAND (init, 0); - current_binding_level->have_cleanups = 1; - current_binding_level->more_exceptions_ok = 0; - } - else - cleanup = maybe_build_cleanup (decl); - resume_momentary (yes); - } - } - /* PARM_DECLs get cleanups, too. */ - else if (TREE_CODE (decl) == PARM_DECL && TYPE_NEEDS_DESTRUCTOR (type)) - { - if (temporary) - end_temporary_allocation (); - cleanup = maybe_build_cleanup (decl); - if (temporary) - resume_temporary_allocation (); - } - - /* Output the assembler code and/or RTL code for variables and functions, - unless the type is an undefined structure or union. - If not, it will get done when the type is completed. */ - - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == RESULT_DECL) - { - int toplev = current_binding_level == global_binding_level; - int was_temp - = ((flag_traditional - || (TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (type))) - && allocation_temporary_p ()); - - if (was_temp) - end_temporary_allocation (); - - /* If we are in need of a cleanup, get out of any implicit - handlers that have been established so far. */ - if (cleanup && current_binding_level->parm_flag == 3) - { - pop_implicit_try_blocks (decl); - current_binding_level->more_exceptions_ok = 0; - } - - if (TREE_CODE (decl) == VAR_DECL - && current_binding_level != global_binding_level - && ! TREE_STATIC (decl) - && type_needs_gc_entry (type)) - DECL_GC_OFFSET (decl) = size_int (++current_function_obstack_index); - - if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) - make_decl_rtl (decl, NULL_PTR, toplev); - else if (TREE_CODE (decl) == VAR_DECL - && TREE_READONLY (decl) - && DECL_INITIAL (decl) != NULL_TREE - && DECL_INITIAL (decl) != error_mark_node - && DECL_INITIAL (decl) != empty_init_node) - { - DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl)); - - if (asmspec) - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); - - if (! toplev - && TREE_STATIC (decl) - && ! TREE_SIDE_EFFECTS (decl) - && ! TREE_PUBLIC (decl) - && ! DECL_EXTERNAL (decl) - && ! TYPE_NEEDS_DESTRUCTOR (type) - && DECL_MODE (decl) != BLKmode) - { - /* If this variable is really a constant, then fill its DECL_RTL - slot with something which won't take up storage. - If something later should take its address, we can always give - it legitimate RTL at that time. */ - DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); - store_expr (DECL_INITIAL (decl), DECL_RTL (decl), 0); - TREE_ASM_WRITTEN (decl) = 1; - } - else if (toplev) - { - /* Keep GCC from complaining that this variable - is defined but never used. */ - TREE_USED (decl) = 1; - /* If this is a static const, change its apparent linkage - if it belongs to a #pragma interface. */ - if (TREE_STATIC (decl) && !interface_unknown) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = interface_only; - } - make_decl_rtl (decl, asmspec, toplev); - } - else - rest_of_decl_compilation (decl, asmspec, toplev, 0); - } - else if (TREE_CODE (decl) == VAR_DECL - && DECL_LANG_SPECIFIC (decl) - && DECL_IN_AGGR_P (decl)) - { - if (TREE_STATIC (decl)) - if (init == NULL_TREE -#ifdef DEFAULT_STATIC_DEFS - /* If this code is dead, then users must - explicitly declare static member variables - outside the class def'n as well. */ - && TYPE_NEEDS_CONSTRUCTING (type) -#endif - ) - { - DECL_EXTERNAL (decl) = 1; - make_decl_rtl (decl, asmspec, 1); - } - else - rest_of_decl_compilation (decl, asmspec, toplev, 0); - else - /* Just a constant field. Should not need any rtl. */ - goto finish_end0; - } - else - rest_of_decl_compilation (decl, asmspec, toplev, 0); - - if (was_temp) - resume_temporary_allocation (); - - if (type != error_mark_node - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - abstract_virtuals_error (decl, type); - else if ((TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) - && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (type))) - abstract_virtuals_error (decl, TREE_TYPE (type)); - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* C++: Handle overloaded functions with default parameters. */ - if (DECL_OVERLOADED (decl)) - { - tree parmtypes = TYPE_ARG_TYPES (type); - tree prev = NULL_TREE; - tree original_name = DECL_NAME (decl); - struct lang_decl *tmp_lang_decl = DECL_LANG_SPECIFIC (decl); - /* All variants will share an uncollectible lang_decl. */ - copy_decl_lang_specific (decl); - - while (parmtypes && parmtypes != void_list_node) - { - if (TREE_PURPOSE (parmtypes)) - { - tree fnname, fndecl; - tree *argp = prev - ? & TREE_CHAIN (prev) - : & TYPE_ARG_TYPES (type); - - *argp = NULL_TREE; - fnname = build_decl_overload (original_name, TYPE_ARG_TYPES (type), 0); - *argp = parmtypes; - fndecl = build_decl (FUNCTION_DECL, fnname, type); - DECL_EXTERNAL (fndecl) = DECL_EXTERNAL (decl); - TREE_PUBLIC (fndecl) = TREE_PUBLIC (decl); - DECL_INLINE (fndecl) = DECL_INLINE (decl); - /* Keep G++ from thinking this function is unused. - It is only used to speed up search in name space. */ - TREE_USED (fndecl) = 1; - TREE_ASM_WRITTEN (fndecl) = 1; - DECL_INITIAL (fndecl) = NULL_TREE; - DECL_LANG_SPECIFIC (fndecl) = DECL_LANG_SPECIFIC (decl); - fndecl = pushdecl (fndecl); - DECL_INITIAL (fndecl) = error_mark_node; - DECL_RTL (fndecl) = DECL_RTL (decl); - } - prev = parmtypes; - parmtypes = TREE_CHAIN (parmtypes); - } - DECL_LANG_SPECIFIC (decl) = tmp_lang_decl; - } - } - else if (DECL_EXTERNAL (decl)) - ; - else if (TREE_STATIC (decl) && type != error_mark_node) - { - /* Cleanups for static variables are handled by `finish_file'. */ - if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE) - expand_static_init (decl, init); - else if (TYPE_NEEDS_DESTRUCTOR (type)) - static_aggregates = perm_tree_cons (NULL_TREE, decl, - static_aggregates); - - /* Make entry in appropriate vector. */ - if (flag_gc && type_needs_gc_entry (type)) - build_static_gc_entry (decl, type); - } - else if (current_binding_level != global_binding_level) - { - /* This is a declared decl which must live until the - end of the binding contour. It may need a cleanup. */ - - /* Recompute the RTL of a local array now - if it used to be an incomplete type. */ - if (was_incomplete && ! TREE_STATIC (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == NULL_TREE) - DECL_INITIAL (decl) = NULL_TREE; - expand_decl (decl); - } - else if (! TREE_ASM_WRITTEN (decl) - && (TYPE_SIZE (type) != NULL_TREE - || TREE_CODE (type) == ARRAY_TYPE)) - { - /* Do this here, because we did not expand this decl's - rtl in start_decl. */ - if (DECL_RTL (decl) == NULL_RTX) - expand_decl (decl); - else if (cleanup) - { - expand_decl_cleanup (NULL_TREE, cleanup); - /* Cleanup used up here. */ - cleanup = NULL_TREE; - } - } - - if (DECL_SIZE (decl) && type != error_mark_node) - { - /* Compute and store the initial value. */ - expand_decl_init (decl); - - if (init || TYPE_NEEDS_CONSTRUCTING (type)) - { - emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - expand_aggr_init (decl, init, 0); - } - - /* Set this to 0 so we can tell whether an aggregate - which was initialized was ever used. */ - if (TYPE_NEEDS_CONSTRUCTING (type)) - TREE_USED (decl) = 0; - - /* Store the cleanup, if there was one. */ - if (cleanup) - { - if (! expand_decl_cleanup (decl, cleanup)) - error_with_decl (decl, "parser lost in parsing declaration of `%s'"); - } - } - } - finish_end0: - - /* Undo call to `pushclass' that was done in `start_decl' - due to initialization of qualified member variable. - I.e., Foo::x = 10; */ - { - tree context = DECL_CONTEXT (decl); - if (context - && TREE_CODE_CLASS (TREE_CODE (context)) == 't' - && (TREE_CODE (decl) == VAR_DECL - /* We also have a pushclass done that we need to undo here - if we're at top level and declare a method. */ - || (TREE_CODE (decl) == FUNCTION_DECL - /* If size hasn't been set, we're still defining it, - and therefore inside the class body; don't pop - the binding level.. */ - && TYPE_SIZE (context) != NULL_TREE - /* The binding level gets popped elsewhere for a - friend declaration inside another class. */ - && TYPE_IDENTIFIER (context) == current_class_name - ))) - popclass (1); - } - } - - finish_end: - - if (need_pop) - { - /* Resume permanent allocation, if not within a function. */ - /* The corresponding push_obstacks_nochange is in start_decl, - start_method, groktypename, and in grokfield. */ - pop_obstacks (); - } - - if (was_readonly) - TREE_READONLY (decl) = 1; - - if (flag_cadillac) - cadillac_finish_decl (decl); -} - -static void -expand_static_init (decl, init) - tree decl; - tree init; -{ - tree oldstatic = value_member (decl, static_aggregates); - if (oldstatic) - { - if (TREE_PURPOSE (oldstatic)) - error_with_decl (decl, "multiple initializations given for `%s'"); - } - else if (current_binding_level != global_binding_level) - { - /* Emit code to perform this initialization but once. */ - tree temp; - - /* Remember this information until end of file. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* Emit code to perform this initialization but once. */ - temp = get_temp_name (integer_type_node, 1); - rest_of_decl_compilation (temp, NULL_PTR, 0, 0); - expand_start_cond (build_binary_op (EQ_EXPR, temp, - integer_zero_node, 1), 0); - expand_assignment (temp, integer_one_node, 0, 0); - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - { - expand_aggr_init (decl, init, 0); - do_pending_stack_adjust (); - } - else - expand_assignment (decl, init, 0, 0); - expand_end_cond (); - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) - { - static_aggregates = perm_tree_cons (temp, decl, static_aggregates); - TREE_STATIC (static_aggregates) = 1; - } - - /* Resume old (possibly temporary) allocation. */ - pop_obstacks (); - } - else - { - /* This code takes into account memory allocation - policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING - does not hold for this object, then we must make permanent - the storage currently in the temporary obstack. */ - if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - preserve_initializer (); - static_aggregates = perm_tree_cons (init, decl, static_aggregates); - } -} - -/* Make TYPE a complete type based on INITIAL_VALUE. - Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ - -int -complete_array_type (type, initial_value, do_default) - tree type, initial_value; - int do_default; -{ - register tree maxindex = NULL_TREE; - int value = 0; - - if (initial_value) - { - /* Note MAXINDEX is really the maximum index, - one less than the size. */ - if (TREE_CODE (initial_value) == STRING_CST) - maxindex = build_int_2 (TREE_STRING_LENGTH (initial_value) - 1, 0); - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - register int nelts - = list_length (CONSTRUCTOR_ELTS (initial_value)); - maxindex = build_int_2 (nelts - 1, 0); - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - - /* Prevent further error messages. */ - maxindex = build_int_2 (1, 0); - } - } - - if (!maxindex) - { - if (do_default) - maxindex = build_int_2 (1, 0); - value = 2; - } - - if (maxindex) - { - TYPE_DOMAIN (type) = build_index_type (maxindex); - if (!TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (type); - } - - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; -} - -/* Return zero if something is declared to be a member of type - CTYPE when in the context of CUR_TYPE. STRING is the error - message to print in that case. Otherwise, quietly return 1. */ -static int -member_function_or_else (ctype, cur_type, string) - tree ctype, cur_type; - char *string; -{ - if (ctype && ctype != cur_type) - { - error (string, TYPE_NAME_STRING (ctype)); - return 0; - } - return 1; -} - -/* Subroutine of `grokdeclarator'. */ - -/* CTYPE is class type, or null if non-class. - TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE - or METHOD_TYPE. - DECLARATOR is the function's name. - VIRTUALP is truthvalue of whether the function is virtual or not. - FLAGS are to be passed through to `grokclassfn'. - QUALS are qualifiers indicating whether the function is `const' - or `volatile'. - RAISES is a list of exceptions that this function can raise. - CHECK is 1 if we must find this method in CTYPE, 0 if we should - not look, and -1 if we should not call `grokclassfn' at all. */ -static tree -grokfndecl (ctype, type, declarator, virtualp, flags, quals, raises, check, publicp) - tree ctype, type; - tree declarator; - int virtualp; - enum overload_flags flags; - tree quals, raises; - int check, publicp; -{ - tree cname, decl; - int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; - - if (ctype) - cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL - ? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype); - else - cname = NULL_TREE; - - if (raises) - { - type = build_exception_variant (ctype, type, raises); - raises = TYPE_RAISES_EXCEPTIONS (type); - } - decl = build_lang_decl (FUNCTION_DECL, declarator, type); - /* propagate volatile out from type to decl */ - if (TYPE_VOLATILE (type)) - TREE_THIS_VOLATILE (decl) = 1; - - /* Should probably propagate const out from type to decl I bet (mrs). */ - if (staticp) - { - DECL_STATIC_FUNCTION_P (decl) = 1; - DECL_CONTEXT (decl) = ctype; - DECL_CLASS_CONTEXT (decl) = ctype; - } - - if (publicp) - TREE_PUBLIC (decl) = 1; - - DECL_EXTERNAL (decl) = 1; - if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) - { - error ("functions cannot have method qualifiers"); - quals = NULL_TREE; - } - - /* Only two styles of delete's are valid. */ - if (declarator == ansi_opname[(int) DELETE_EXPR]) - { - tree args = TYPE_ARG_TYPES (type); - int style1, style2; - - if (ctype && args && TREE_CODE (type) == METHOD_TYPE) - /* remove this */ - args = TREE_CHAIN (args); - - style1 = type_list_equal (args, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)); - style2 = style1 != 0 ? 0 : - type_list_equal (args, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, sizetype, - void_list_node))); - - if (ctype == NULL_TREE) - { - if (! style1) - /* ANSI C++ June 5 1992 WP 12.5.5.2 */ - error ("global operator delete must be declared as taking a single argument of type void*"); - } - else - if (! style1 && ! style2) - /* ANSI C++ June 5 1992 WP 12.5.4.1 */ - error ("operator delete cannot be overloaded"); - } - else if (DECL_NAME (decl) == ansi_opname[(int) POSTINCREMENT_EXPR] - || DECL_NAME (decl) == ansi_opname[(int) POSTDECREMENT_EXPR]) - { - /* According to ARM $13.4.7, postfix operator++ must take an int as - its second argument. */ - tree parmtypes, argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - - if (argtypes) - { - parmtypes = TREE_CHAIN (argtypes); - if (parmtypes != NULL_TREE - && TREE_VALUE (parmtypes) != void_type_node - && TREE_VALUE (parmtypes) != integer_type_node) - error ("postfix operator%s may only take `int' as its argument", - POSTINCREMENT_EXPR ? "++" : "--"); - } - } - - /* Caller will do the rest of this. */ - if (check < 0) - return decl; - - if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator) - { - tree tmp; - /* Just handle constructors here. We could do this - inside the following if stmt, but I think - that the code is more legible by breaking this - case out. See comments below for what each of - the following calls is supposed to do. */ - DECL_CONSTRUCTOR_P (decl) = 1; - - grokclassfn (ctype, declarator, decl, flags, quals); - if (check) - check_classfn (ctype, declarator, decl); - grok_ctor_properties (ctype, decl); - if (check == 0) - { - /* FIXME: this should only need to look at IDENTIFIER_GLOBAL_VALUE. */ - tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0); - if (tmp == NULL_TREE) - IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; - else if (TREE_CODE (tmp) != TREE_CODE (decl)) - error_with_decl (decl, "inconsistent declarations for `%s'"); - else - { - duplicate_decls (decl, tmp); - decl = tmp; - /* avoid creating circularities. */ - DECL_CHAIN (decl) = NULL_TREE; - } - make_decl_rtl (decl, NULL_PTR, 1); - } - } - else - { - tree tmp; - - /* Function gets the ugly name, field gets the nice one. - This call may change the type of the function (because - of default parameters)! */ - if (ctype != NULL_TREE) - grokclassfn (ctype, cname, decl, flags, quals); - - if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, virtualp); - - if (ctype != NULL_TREE && check) - check_classfn (ctype, cname, decl); - - if (ctype == NULL_TREE || check) - return decl; - - /* Now install the declaration of this function so that - others may find it (esp. its DECL_FRIENDLIST). - Pretend we are at top level, we will get true - reference later, perhaps. - - FIXME: This should only need to look at IDENTIFIER_GLOBAL_VALUE. */ - tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0); - if (tmp == NULL_TREE) - IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl; - else if (TREE_CODE (tmp) != TREE_CODE (decl)) - error_with_decl (decl, "inconsistent declarations for `%s'"); - else - { - duplicate_decls (decl, tmp); - decl = tmp; - /* avoid creating circularities. */ - DECL_CHAIN (decl) = NULL_TREE; - } - make_decl_rtl (decl, NULL_PTR, 1); - - /* If this declaration supersedes the declaration of - a method declared virtual in the base class, then - mark this field as being virtual as well. */ - { - tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype)); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo)) || flag_all_virtual == 1) - { - tmp = get_first_matching_virtual (base_binfo, decl, - flags == DTOR_FLAG); - if (tmp) - { - /* The TMP we really want is the one from the deepest - baseclass on this path, taking care not to - duplicate if we have already found it (via another - path to its virtual baseclass. */ - if (staticp) - { - error_with_decl (decl, "method `%s' may not be declared static"); - error_with_decl (tmp, "(since `%s' declared virtual in base class.)"); - break; - } - virtualp = 1; - - if ((TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (base_binfo)) - || TYPE_USES_MULTIPLE_INHERITANCE (ctype)) - && BINFO_TYPE (base_binfo) != DECL_CONTEXT (tmp)) - tmp = get_first_matching_virtual (TYPE_BINFO (DECL_CONTEXT (tmp)), - decl, flags == DTOR_FLAG); - if (value_member (tmp, DECL_VINDEX (decl)) == NULL_TREE) - { - /* The argument types may have changed... */ - tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - tree base_variant = TREE_TYPE (TREE_VALUE (argtypes)); - - argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))), - TREE_CHAIN (argtypes)); - /* But the return type has not. */ - type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes); - if (raises) - { - type = build_exception_variant (ctype, type, raises); - raises = TYPE_RAISES_EXCEPTIONS (type); - } - TREE_TYPE (decl) = type; - DECL_VINDEX (decl) - = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl)); - } - } - } - } - } - if (virtualp) - { - if (DECL_VINDEX (decl) == NULL_TREE) - DECL_VINDEX (decl) = error_mark_node; - IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; - if (ctype && CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) - /* If this function is derived from a template, don't - make it public. This shouldn't be here, but there's - no good way to override the interface pragmas for one - function or class only. Bletch. */ - && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (ctype)) == NULL_TREE - && (write_virtuals == 2 - || (write_virtuals == 3 - && ! CLASSTYPE_INTERFACE_UNKNOWN (ctype)))) - TREE_PUBLIC (decl) = 1; - } - } - return decl; -} - -static tree -grokvardecl (type, declarator, specbits, initialized) - tree type; - tree declarator; - RID_BIT_TYPE specbits; - int initialized; -{ - tree decl; - - /* This implements the "one definition rule" for global variables. - Note that declarator can come in as null when we're doing work - on an anonymous union. */ - if (declarator && IDENTIFIER_GLOBAL_VALUE (declarator) - && current_binding_level == global_binding_level - && TREE_STATIC (IDENTIFIER_GLOBAL_VALUE (declarator)) - && (! (specbits & RIDBIT (RID_EXTERN)) - || initialized)) - { - error ("redefinition of `%s'", IDENTIFIER_POINTER (declarator)); - error_with_decl (IDENTIFIER_GLOBAL_VALUE (declarator), - "previously defined here"); - } - - if (TREE_CODE (type) == OFFSET_TYPE) - { - /* If you declare a static member so that it - can be initialized, the code will reach here. */ - tree field = lookup_field (TYPE_OFFSET_BASETYPE (type), - declarator, 0, 0); - if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL) - { - tree basetype = TYPE_OFFSET_BASETYPE (type); - error ("`%s' is not a static member of class `%s'", - IDENTIFIER_POINTER (declarator), - TYPE_NAME_STRING (basetype)); - type = TREE_TYPE (type); - decl = build_lang_field_decl (VAR_DECL, declarator, type); - DECL_CONTEXT (decl) = basetype; - DECL_CLASS_CONTEXT (decl) = basetype; - } - else - { - tree f_type = TREE_TYPE (field); - tree o_type = TREE_TYPE (type); - - if (TYPE_SIZE (f_type) == NULL_TREE) - { - if (TREE_CODE (f_type) != TREE_CODE (o_type) - || (TREE_CODE (f_type) == ARRAY_TYPE - && TREE_TYPE (f_type) != TREE_TYPE (o_type))) - error ("redeclaration of type for `%s'", - IDENTIFIER_POINTER (declarator)); - else if (TYPE_SIZE (o_type) != NULL_TREE) - TREE_TYPE (field) = type; - } - else if (f_type != o_type) - error ("redeclaration of type for `%s'", - IDENTIFIER_POINTER (declarator)); - decl = field; - if (initialized && DECL_INITIAL (decl) - /* Complain about multiply-initialized - member variables, but don't be faked - out if initializer is faked up from `empty_init_node'. */ - && (TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR - || CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) != NULL_TREE)) - error_with_aggr_type (DECL_CONTEXT (decl), - "multiple initializations of static member `%s::%s'", - IDENTIFIER_POINTER (DECL_NAME (decl))); - } - } - else decl = build_decl (VAR_DECL, declarator, type); - - if (specbits & RIDBIT (RID_EXTERN)) - { - DECL_THIS_EXTERN (decl) = 1; - DECL_EXTERNAL (decl) = !initialized; - } - - /* In class context, static means one per class, - public visibility, and static storage. */ - if (DECL_FIELD_CONTEXT (decl) != NULL_TREE - && IS_AGGR_TYPE (DECL_FIELD_CONTEXT (decl))) - { - TREE_PUBLIC (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_EXTERNAL (decl) = !initialized; - } - /* At top level, either `static' or no s.c. makes a definition - (perhaps tentative), and absence of `static' makes it public. */ - else if (current_binding_level == global_binding_level) - { - TREE_PUBLIC (decl) = ! (specbits & RIDBIT (RID_STATIC)); - TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); - } - /* Not at top level, only `static' makes a static definition. */ - else - { - TREE_STATIC (decl) = !! (specbits & RIDBIT (RID_STATIC)); - TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); - } - return decl; -} - -/* Given declspecs and a declarator, - determine the name and type of the object declared - and construct a ..._DECL node for it. - (In one case we can return a ..._TYPE node instead. - For invalid input we sometimes return 0.) - - DECLSPECS is a chain of tree_list nodes whose value fields - are the storage classes and type specifiers. - - DECL_CONTEXT says which syntactic context this declaration is in: - NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL. - FUNCDEF for a function definition. Like NORMAL but a few different - error messages in each case. Return value may be zero meaning - this definition is too screwy to try to parse. - MEMFUNCDEF for a function definition. Like FUNCDEF but prepares to - handle member functions (which have FIELD context). - Return value may be zero meaning this definition is too screwy to - try to parse. - PARM for a parameter declaration (either within a function prototype - or before a function body). Make a PARM_DECL, or return void_type_node. - TYPENAME if for a typename (in a cast or sizeof). - Don't make a DECL node; just return the ..._TYPE node. - FIELD for a struct or union field; make a FIELD_DECL. - BITFIELD for a field with specified width. - INITIALIZED is 1 if the decl has an initializer. - - In the TYPENAME case, DECLARATOR is really an absolute declarator. - It may also be so in the PARM case, for a prototype where the - argument type is specified but not the name. - - This function is where the complicated C meanings of `static' - and `extern' are interpreted. - - For C++, if there is any monkey business to do, the function which - calls this one must do it, i.e., prepending instance variables, - renaming overloaded function names, etc. - - Note that for this C++, it is an error to define a method within a class - which does not belong to that class. - - Except in the case where SCOPE_REFs are implicitly known (such as - methods within a class being redundantly qualified), - declarations which involve SCOPE_REFs are returned as SCOPE_REFs - (class_name::decl_name). The caller must also deal with this. - - If a constructor or destructor is seen, and the context is FIELD, - then the type gains the attribute TREE_HAS_x. If such a declaration - is erroneous, NULL_TREE is returned. - - QUALS is used only for FUNCDEF and MEMFUNCDEF cases. For a member - function, these are the qualifiers to give to the `this' pointer. - - May return void_type_node if the declarator turned out to be a friend. - See grokfield for details. */ - -enum return_types { return_normal, return_ctor, return_dtor, return_conversion }; - -tree -grokdeclarator (declarator, declspecs, decl_context, initialized, raises) - tree declspecs; - tree declarator; - enum decl_context decl_context; - int initialized; - tree raises; -{ - extern int current_class_depth; - - RID_BIT_TYPE specbits = 0; - int nclasses = 0; - tree spec; - tree type = NULL_TREE; - int longlong = 0; - int constp; - int volatilep; - int virtualp, friendp, inlinep, staticp; - int explicit_int = 0; - int explicit_char = 0; - tree typedef_decl = NULL_TREE; - char *name; - tree typedef_type = NULL_TREE; - int funcdef_flag = 0; - enum tree_code innermost_code = ERROR_MARK; - int bitfield = 0; - int size_varies = 0; - /* Set this to error_mark_node for FIELD_DECLs we could not handle properly. - All FIELD_DECLs we build here have `init' put into their DECL_INITIAL. */ - tree init = NULL_TREE; - - /* Keep track of what sort of function is being processed - so that we can warn about default return values, or explicit - return values which do not match prescribed defaults. */ - enum return_types return_type = return_normal; - - tree dname = NULL_TREE; - tree ctype = current_class_type; - tree ctor_return_type = NULL_TREE; - enum overload_flags flags = NO_SPECIAL; - int seen_scope_ref = 0; - tree quals = NULL_TREE; - - if (decl_context == FUNCDEF) - funcdef_flag = 1, decl_context = NORMAL; - else if (decl_context == MEMFUNCDEF) - funcdef_flag = -1, decl_context = FIELD; - else if (decl_context == BITFIELD) - bitfield = 1, decl_context = FIELD; - - if (flag_traditional && allocation_temporary_p ()) - end_temporary_allocation (); - - /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ - { - tree type, last = NULL_TREE; - register tree decl = declarator; - name = NULL; - - /* If we see something of the form `aggr_type xyzzy (a, b, c)' - it is either an old-style function declaration or a call to - a constructor. The following conditional makes recognizes this - case as being a call to a constructor. Too bad if it is not. */ - - /* For Doug Lea, also grok `aggr_type xyzzy (a, b, c)[10][10][10]'. */ - while (decl && TREE_CODE (decl) == ARRAY_REF) - { - last = decl; - decl = TREE_OPERAND (decl, 0); - } - - if (decl && declspecs - && TREE_CODE (decl) == CALL_EXPR - && TREE_OPERAND (decl, 0) - && (TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE - || TREE_CODE (TREE_OPERAND (decl, 0)) == SCOPE_REF)) - { - type = TREE_CODE (TREE_VALUE (declspecs)) == IDENTIFIER_NODE - ? lookup_name (TREE_VALUE (declspecs), 1) : - (IS_AGGR_TYPE (TREE_VALUE (declspecs)) - ? TYPE_NAME (TREE_VALUE (declspecs)) : NULL_TREE); - - if (type && TREE_CODE (type) == TYPE_DECL - && IS_AGGR_TYPE (TREE_TYPE (type)) - && parmlist_is_exprlist (TREE_OPERAND (decl, 1))) - { - if (decl_context == FIELD - && TREE_CHAIN (TREE_OPERAND (decl, 1))) - { - /* That was an initializer list. */ - sorry ("initializer lists for field declarations"); - decl = TREE_OPERAND (decl, 0); - if (last) - { - TREE_OPERAND (last, 0) = decl; - decl = declarator; - } - declarator = decl; - init = error_mark_node; - goto bot; - } - else - { - init = TREE_OPERAND (decl, 1); - if (last) - { - TREE_OPERAND (last, 0) = TREE_OPERAND (decl, 0); - if (pedantic && init) - { - error ("arrays cannot take initializers"); - init = error_mark_node; - } - } - else - declarator = TREE_OPERAND (declarator, 0); - decl = start_decl (declarator, declspecs, 1, NULL_TREE); - finish_decl (decl, init, NULL_TREE, 1); - return 0; - } - } - - if (parmlist_is_random (TREE_OPERAND (decl, 1))) - { - decl = TREE_OPERAND (decl, 0); - if (TREE_CODE (decl) == SCOPE_REF) - { - if (TREE_COMPLEXITY (decl)) - my_friendly_abort (15); - decl = TREE_OPERAND (decl, 1); - } - if (TREE_CODE (decl) == IDENTIFIER_NODE) - name = IDENTIFIER_POINTER (decl); - if (name) - error ("bad parameter list specification for function `%s'", - name); - else - error ("bad parameter list specification for function"); - return void_type_node; - } - bot: - ; - } - else - /* It didn't look like we thought it would, leave the ARRAY_REFs on. */ - decl = declarator; - - while (decl) - switch (TREE_CODE (decl)) - { - case COND_EXPR: - ctype = NULL_TREE; - decl = TREE_OPERAND (decl, 0); - break; - - case BIT_NOT_EXPR: /* for C++ destructors! */ - { - tree name = TREE_OPERAND (decl, 0); - tree rename = NULL_TREE; - - my_friendly_assert (flags == NO_SPECIAL, 152); - flags = DTOR_FLAG; - return_type = return_dtor; - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153); - if (ctype == NULL_TREE) - { - if (current_class_type == NULL_TREE) - { - error ("destructors must be member functions"); - flags = NO_SPECIAL; - } - else - { - tree t = constructor_name (current_class_name); - if (t != name) - rename = t; - } - } - else - { - tree t = constructor_name (ctype); - if (t != name) - rename = t; - } - - if (rename) - { - error ("destructor `%s' must match class name `%s'", - IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (rename)); - TREE_OPERAND (decl, 0) = rename; - } - decl = name; - } - break; - - case ADDR_EXPR: /* C++ reference declaration */ - /* fall through */ - case ARRAY_REF: - case INDIRECT_REF: - ctype = NULL_TREE; - innermost_code = TREE_CODE (decl); - decl = TREE_OPERAND (decl, 0); - break; - - case CALL_EXPR: - innermost_code = TREE_CODE (decl); - decl = TREE_OPERAND (decl, 0); - if (decl_context == FIELD && ctype == NULL_TREE) - ctype = current_class_type; - if (ctype != NULL_TREE - && decl != NULL_TREE && flags != DTOR_FLAG - && decl == constructor_name (ctype)) - { - return_type = return_ctor; - ctor_return_type = ctype; - } - ctype = NULL_TREE; - break; - - case IDENTIFIER_NODE: - dname = decl; - name = IDENTIFIER_POINTER (decl); - decl = NULL_TREE; - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - /* Parse error puts this typespec where - a declarator should go. */ - error ("declarator name missing"); - dname = TYPE_NAME (decl); - if (dname && TREE_CODE (dname) == TYPE_DECL) - dname = DECL_NAME (dname); - name = dname ? IDENTIFIER_POINTER (dname) : ""; - declspecs = temp_tree_cons (NULL_TREE, decl, declspecs); - decl = NULL_TREE; - break; - - case TYPE_EXPR: - if (ctype == NULL_TREE) - { - /* ANSI C++ June 5 1992 WP 12.3.2 only describes - conversion functions in terms of being declared - as a member function. */ - error ("operator `%s' must be declared as a member", - IDENTIFIER_POINTER (TREE_VALUE (TREE_TYPE (decl)))); - return NULL_TREE; - } - - ctype = NULL_TREE; - my_friendly_assert (flags == NO_SPECIAL, 154); - flags = TYPENAME_FLAG; - name = "operator "; - /* Go to the absdcl. */ - decl = TREE_OPERAND (decl, 0); - return_type = return_conversion; - break; - - /* C++ extension */ - case SCOPE_REF: - if (seen_scope_ref == 1) - error ("multiple `::' terms in declarator invalid"); - seen_scope_ref += 1; - { - /* Perform error checking, and convert class names to types. - We may call grokdeclarator multiple times for the same - tree structure, so only do the conversion once. In this - case, we have exactly what we want for `ctype'. */ - tree cname = TREE_OPERAND (decl, 0); - if (cname == NULL_TREE) - ctype = NULL_TREE; - /* Can't use IS_AGGR_TYPE because CNAME might not be a type. */ - else if (IS_AGGR_TYPE_CODE (TREE_CODE (cname)) - || TREE_CODE (cname) == UNINSTANTIATED_P_TYPE) - ctype = cname; - else if (! is_aggr_typedef (cname, 1)) - { - TREE_OPERAND (decl, 0) = NULL_TREE; - } - /* Must test TREE_OPERAND (decl, 1), in case user gives - us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */ - else if (TREE_OPERAND (decl, 1) - && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF) - { - TREE_OPERAND (decl, 0) = IDENTIFIER_TYPE_VALUE (cname); - } - else if (ctype == NULL_TREE) - { - ctype = IDENTIFIER_TYPE_VALUE (cname); - TREE_OPERAND (decl, 0) = ctype; - } - else if (TREE_COMPLEXITY (decl) == current_class_depth) - TREE_OPERAND (decl, 0) = ctype; - else - { - if (! UNIQUELY_DERIVED_FROM_P (IDENTIFIER_TYPE_VALUE (cname), ctype)) - { - error ("type `%s' is not derived from type `%s'", - IDENTIFIER_POINTER (cname), - TYPE_NAME_STRING (ctype)); - TREE_OPERAND (decl, 0) = NULL_TREE; - } - else - { - ctype = IDENTIFIER_TYPE_VALUE (cname); - TREE_OPERAND (decl, 0) = ctype; - } - } - - decl = TREE_OPERAND (decl, 1); - if (ctype) - { - if (TREE_CODE (decl) == IDENTIFIER_NODE - && constructor_name (ctype) == decl) - { - return_type = return_ctor; - ctor_return_type = ctype; - } - else if (TREE_CODE (decl) == BIT_NOT_EXPR - && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE - && constructor_name (ctype) == TREE_OPERAND (decl, 0)) - { - return_type = return_dtor; - ctor_return_type = ctype; - flags = DTOR_FLAG; - decl = TREE_OPERAND (decl, 0); - } - } - } - break; - - case ERROR_MARK: - decl = NULL_TREE; - break; - - default: - my_friendly_abort (155); - } - if (name == NULL) - name = "type name"; - } - - /* A function definition's declarator must have the form of - a function declarator. */ - - if (funcdef_flag && innermost_code != CALL_EXPR) - return 0; - - /* Anything declared one level down from the top level - must be one of the parameters of a function - (because the body is at least two levels down). */ - - /* This heuristic cannot be applied to C++ nodes! Fixed, however, - by not allowing C++ class definitions to specify their parameters - with xdecls (must be spec.d in the parmlist). - - Since we now wait to push a class scope until we are sure that - we are in a legitimate method context, we must set oldcname - explicitly (since current_class_name is not yet alive). */ - - if (decl_context == NORMAL - && current_binding_level->level_chain == global_binding_level) - decl_context = PARM; - - /* Look through the decl specs and record which ones appear. - Some typespecs are defined as built-in typenames. - Others, the ones that are modifiers of other types, - are represented by bits in SPECBITS: set the bits for - the modifiers that appear. Storage class keywords are also in SPECBITS. - - If there is a typedef name or a type, store the type in TYPE. - This includes builtin typedefs such as `int'. - - Set EXPLICIT_INT if the type is `int' or `char' and did not - come from a user typedef. - - Set LONGLONG if `long' is mentioned twice. - - For C++, constructors and destructors have their own fast treatment. */ - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - register int i; - register tree id = TREE_VALUE (spec); - - /* Certain parse errors slip through. For example, - `int class;' is not caught by the parser. Try - weakly to recover here. */ - if (TREE_CODE (spec) != TREE_LIST) - return 0; - - if (TREE_CODE (id) == IDENTIFIER_NODE) - { - if (id == ridpointers[(int) RID_INT]) - { - if (type) - error ("extraneous `int' ignored"); - else - { - explicit_int = 1; - type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); - } - goto found; - } - if (id == ridpointers[(int) RID_CHAR]) - { - if (type) - error ("extraneous `char' ignored"); - else - { - explicit_char = 1; - type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); - } - goto found; - } - if (id == ridpointers[(int) RID_WCHAR]) - { - if (type) - error ("extraneous `__wchar_t' ignored"); - else - { - type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); - } - goto found; - } - /* C++ aggregate types. */ - if (IDENTIFIER_HAS_TYPE_VALUE (id)) - { - if (type) - error ("multiple declarations `%s' and `%s'", - IDENTIFIER_POINTER (type), - IDENTIFIER_POINTER (id)); - else - type = IDENTIFIER_TYPE_VALUE (id); - goto found; - } - - for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++) - { - if (ridpointers[i] == id) - { - if (i == (int) RID_LONG && (specbits & RIDBIT (i))) - { - if (pedantic) - pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); - else if (longlong) - error ("`long long long' is too long for GCC"); - else - longlong = 1; - } - else if (specbits & RIDBIT (i)) - warning ("duplicate `%s'", IDENTIFIER_POINTER (id)); - specbits |= RIDBIT (i); - goto found; - } - } - } - if (type) - error ("two or more data types in declaration of `%s'", name); - else if (TREE_CODE (id) == IDENTIFIER_NODE) - { - register tree t = lookup_name (id, 1); - if (!t || TREE_CODE (t) != TYPE_DECL) - error ("`%s' fails to be a typedef or built in type", - IDENTIFIER_POINTER (id)); - else - { - type = TREE_TYPE (t); - typedef_decl = t; - } - } - else if (TREE_CODE (id) != ERROR_MARK) - /* Can't change CLASS nodes into RECORD nodes here! */ - type = id; - - found: {} - } - - typedef_type = type; - - /* No type at all: default to `int', and set EXPLICIT_INT - because it was not a user-defined typedef. */ - - if (type == NULL_TREE) - { - explicit_int = -1; - if (return_type == return_dtor) - type = void_type_node; - else if (return_type == return_ctor) - type = TYPE_POINTER_TO (ctor_return_type); - else - { - if (funcdef_flag && explicit_warn_return_type - && return_type == return_normal - && ! (specbits & (RIDBIT (RID_SIGNED) | RIDBIT (RID_UNSIGNED) - | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT)))) - warn_about_return_type = 1; - /* Save warning until we know what is really going on. */ - type = integer_type_node; - } - } - else if (return_type == return_dtor) - { - error ("return type specification for destructor invalid"); - type = void_type_node; - } - else if (return_type == return_ctor) - { - error ("return type specification for constructor invalid"); - type = TYPE_POINTER_TO (ctor_return_type); - } - else if ((specbits & RIDBIT (RID_FRIEND)) - && IS_AGGR_TYPE (type) - && ! TYPE_BEING_DEFINED (type) - && TYPE_SIZE (type) == NULL_TREE - && ! ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)) - && current_function_decl == NULL_TREE - && decl_context != PARM) - { - /* xref_tag will make friend class declarations look like - nested class declarations. Retroactively change that - if the type has not yet been defined. - - ??? ANSI C++ doesn't say what to do in this case yet. */ - globalize_nested_type (type); - } - - ctype = NULL_TREE; - - /* Now process the modifiers that were specified - and check for invalid combinations. */ - - /* Long double is a special combination. */ - - if ((specbits & RIDBIT (RID_LONG)) - && TYPE_MAIN_VARIANT (type) == double_type_node) - { - specbits &= ~ RIDBIT (RID_LONG); - type = build_type_variant (long_double_type_node, TYPE_READONLY (type), - TYPE_VOLATILE (type)); - } - - /* Check all other uses of type modifiers. */ - - if (specbits & (RIDBIT (RID_UNSIGNED) | RIDBIT (RID_SIGNED) - | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT))) - { - int ok = 0; - - if (TREE_CODE (type) == REAL_TYPE) - error ("short, signed or unsigned invalid for `%s'", name); - else if (TREE_CODE (type) != INTEGER_TYPE || type == wchar_type_node) - error ("long, short, signed or unsigned invalid for `%s'", name); - else if ((specbits & RIDBIT (RID_LONG)) - && (specbits & RIDBIT (RID_SHORT))) - error ("long and short specified together for `%s'", name); - else if (((specbits & RIDBIT (RID_LONG)) - || (specbits & RIDBIT (RID_SHORT))) - && explicit_char) - error ("long or short specified with char for `%s'", name); - else if (((specbits & RIDBIT (RID_LONG)) - || (specbits & RIDBIT (RID_SHORT))) - && TREE_CODE (type) == REAL_TYPE) - error ("long or short specified with floating type for `%s'", name); - else if ((specbits & RIDBIT (RID_SIGNED)) - && (specbits & RIDBIT (RID_UNSIGNED))) - error ("signed and unsigned given together for `%s'", name); - else - { - ok = 1; - if (!explicit_int && !explicit_char && pedantic) - { - pedwarn ("long, short, signed or unsigned used invalidly for `%s'", - name); - if (flag_pedantic_errors) - ok = 0; - } - } - - /* Discard the type modifiers if they are invalid. */ - if (! ok) - { - specbits &= ~ (RIDBIT (RID_UNSIGNED) | RIDBIT (RID_SIGNED) - | RIDBIT (RID_LONG) | RIDBIT (RID_SHORT)); - longlong = 0; - } - } - - /* Decide whether an integer type is signed or not. - Optionally treat bitfields as signed by default. */ - if ((specbits & RIDBIT (RID_UNSIGNED)) - /* Traditionally, all bitfields are unsigned. */ - || (bitfield && flag_traditional) - || (bitfield && ! flag_signed_bitfields - && (explicit_int || explicit_char - /* A typedef for plain `int' without `signed' - can be controlled just like plain `int'. */ - || ! (typedef_decl != NULL_TREE - && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) - && TREE_CODE (type) != ENUMERAL_TYPE - && !(specbits & RIDBIT (RID_SIGNED)))) - { - if (longlong) - type = long_long_unsigned_type_node; - else if (specbits & RIDBIT (RID_LONG)) - type = long_unsigned_type_node; - else if (specbits & RIDBIT (RID_SHORT)) - type = short_unsigned_type_node; - else if (type == char_type_node) - type = unsigned_char_type_node; - else if (typedef_decl) - type = unsigned_type (type); - else - type = unsigned_type_node; - } - else if ((specbits & RIDBIT (RID_SIGNED)) - && type == char_type_node) - type = signed_char_type_node; - else if (longlong) - type = long_long_integer_type_node; - else if (specbits & RIDBIT (RID_LONG)) - type = long_integer_type_node; - else if (specbits & RIDBIT (RID_SHORT)) - type = short_integer_type_node; - - /* Set CONSTP if this declaration is `const', whether by - explicit specification or via a typedef. - Likewise for VOLATILEP. */ - - constp = !! (specbits & RIDBIT (RID_CONST)) + TYPE_READONLY (type); - volatilep = !! (specbits & RIDBIT (RID_VOLATILE)) + TYPE_VOLATILE (type); - staticp = 0; - inlinep = !! (specbits & RIDBIT (RID_INLINE)); - if (constp > 1) - warning ("duplicate `const'"); - if (volatilep > 1) - warning ("duplicate `volatile'"); - virtualp = specbits & RIDBIT (RID_VIRTUAL); - if (specbits & RIDBIT (RID_STATIC)) - staticp = 1 + (decl_context == FIELD); - - if (virtualp && staticp == 2) - { - error ("member `%s' cannot be declared both virtual and static", name); - staticp = 0; - } - friendp = specbits & RIDBIT (RID_FRIEND); - specbits &= ~ (RIDBIT (RID_VIRTUAL) | RIDBIT (RID_FRIEND)); - - /* Warn if two storage classes are given. Default to `auto'. */ - - if (specbits) - { - if (specbits & RIDBIT (RID_STATIC)) nclasses++; - if (specbits & RIDBIT (RID_EXTERN)) nclasses++; - if (decl_context == PARM && nclasses > 0) - error ("storage class specifiers invalid in parameter declarations"); - if (specbits & RIDBIT (RID_TYPEDEF)) - { - if (decl_context == PARM) - error ("typedef declaration invalid in parameter declaration"); - nclasses++; - } - if (specbits & RIDBIT (RID_AUTO)) nclasses++; - if (specbits & RIDBIT (RID_REGISTER)) nclasses++; - } - - /* Give error if `virtual' is used outside of class declaration. */ - if (virtualp && current_class_name == NULL_TREE) - { - error ("virtual outside class declaration"); - virtualp = 0; - } - - /* Warn about storage classes that are invalid for certain - kinds of declarations (parameters, typenames, etc.). */ - - if (nclasses > 1) - error ("multiple storage classes in declaration of `%s'", name); - else if (decl_context != NORMAL && nclasses > 0) - { - if (decl_context == PARM - && ((specbits & RIDBIT (RID_REGISTER)) | RIDBIT (RID_AUTO))) - ; - else if ((decl_context == FIELD - || decl_context == TYPENAME) - && (specbits & RIDBIT (RID_TYPEDEF))) - { - /* A typedef which was made in a class's scope. */ - tree loc_typedecl; - register int i = sizeof (struct lang_decl_flags) / sizeof (int); - register int *pi; - struct binding_level *local_binding_level; - - /* keep `grokdeclarator' from thinking we are in PARM context. */ - pushlevel (0); - /* poplevel_class may be called by grokdeclarator which is called in - start_decl which is called below. In this case, our pushed level - may vanish and poplevel mustn't be called. So remember what we - have pushed and pop only if that is matched by - current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */ - local_binding_level = current_binding_level; - - loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE); - - pi = (int *) permalloc (sizeof (struct lang_decl_flags)); - while (i > 0) - pi[--i] = 0; - DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; - /* This poplevel conflicts with the popclass over in - grokdeclarator. See ``This popclass conflicts'' */ - if (current_binding_level == local_binding_level) - poplevel (0, 0, 0); - -#if 0 - if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) - { - tree ref = lookup_tag (ENUMERAL_TYPE, DECL_NAME (loc_typedecl), current_binding_level, 0); - if (! ref) - pushtag (DECL_NAME (loc_typedecl), TREE_TYPE (loc_typedecl)); - } -#endif - - /* We used to check for a typedef hiding a previous decl in - class scope, but delete_duplicate_fields_1 will now do - that for us in the proper place. */ - - /* We reset loc_typedecl because the IDENTIFIER_CLASS_NAME is - set by pushdecl_class_level. */ - loc_typedecl = pushdecl_class_level (loc_typedecl); - - return loc_typedecl; - } - else if (decl_context == FIELD - /* C++ allows static class elements */ - && (specbits & RIDBIT (RID_STATIC))) - /* C++ also allows inlines and signed and unsigned elements, - but in those cases we don't come in here. */ - ; - else - { - if (decl_context == FIELD) - { - tree tmp = TREE_OPERAND (declarator, 0); - register int op = IDENTIFIER_OPNAME_P (tmp); - error ("storage class specified for %s `%s'", - op ? "member operator" : "structure field", - op ? operator_name_string (tmp) : name); - } - else - error ((decl_context == PARM - ? "storage class specified for parameter `%s'" - : "storage class specified for typename"), name); - specbits &= ~ (RIDBIT (RID_REGISTER) | RIDBIT (RID_AUTO) - | RIDBIT (RID_EXTERN)); - } - } - else if ((specbits & RIDBIT (RID_EXTERN)) && initialized && !funcdef_flag) - { - if (current_binding_level == global_binding_level) - { - /* It's common practice (and completely legal) to have a const - be initialized and declared extern. */ - if (! constp) - warning ("`%s' initialized and declared `extern'", name); - } - else - error ("`%s' has both `extern' and initializer", name); - } - else if ((specbits & RIDBIT (RID_EXTERN)) && funcdef_flag - && current_binding_level != global_binding_level) - error ("nested function `%s' declared `extern'", name); - else if (current_binding_level == global_binding_level) - { - if (specbits & RIDBIT (RID_AUTO)) - error ("top-level declaration of `%s' specifies `auto'", name); -#if 0 - if (specbits & RIDBIT (RID_REGISTER)) - error ("top-level declaration of `%s' specifies `register'", name); -#endif -#if 0 - /* I'm not sure under what circumstances we should turn - on the extern bit, and under what circumstances we should - warn if other bits are turned on. */ - if (decl_context == NORMAL - && ! (specbits & RIDBIT (RID_EXTERN)) - && ! root_lang_context_p ()) - { - specbits |= RIDBIT (RID_EXTERN); - } -#endif - } - - /* Now figure out the structure of the declarator proper. - Descend through it, creating more complex types, until we reach - the declared identifier (or NULL_TREE, in an absolute declarator). */ - - while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE) - { - /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), - an INDIRECT_REF (for *...), - a CALL_EXPR (for ...(...)), - an identifier (for the name being declared) - or a null pointer (for the place in an absolute declarator - where the name was omitted). - For the last two cases, we have just exited the loop. - - For C++ it could also be - a SCOPE_REF (for class :: ...). In this case, we have converted - sensible names to types, and those are the values we use to - qualify the member name. - an ADDR_EXPR (for &...), - a BIT_NOT_EXPR (for destructors) - a TYPE_EXPR (for operator typenames) - - At this point, TYPE is the type of elements of an array, - or for a function to return, or for a pointer to point to. - After this sequence of ifs, TYPE is the type of the - array or function or pointer, and DECLARATOR has had its - outermost layer removed. */ - - if (TREE_CODE (type) == ERROR_MARK) - { - if (TREE_CODE (declarator) == SCOPE_REF) - declarator = TREE_OPERAND (declarator, 1); - else - declarator = TREE_OPERAND (declarator, 0); - continue; - } - if (quals != NULL_TREE - && (declarator == NULL_TREE - || TREE_CODE (declarator) != SCOPE_REF)) - { - if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (type); - if (ctype != NULL_TREE) - { -#if 0 /* not yet, should get fixed properly later */ - tree dummy = make_type_decl (NULL_TREE, type); -#else - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); -#endif - ctype = grok_method_quals (ctype, dummy, quals); - type = TREE_TYPE (dummy); - quals = NULL_TREE; - } - } - switch (TREE_CODE (declarator)) - { - case ARRAY_REF: - maybe_globalize_type (type); - { - register tree itype = NULL_TREE; - register tree size = TREE_OPERAND (declarator, 1); - - declarator = TREE_OPERAND (declarator, 0); - - /* Check for some types that there cannot be arrays of. */ - - if (TYPE_MAIN_VARIANT (type) == void_type_node) - { - error ("declaration of `%s' as array of voids", name); - type = error_mark_node; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("declaration of `%s' as array of functions", name); - type = error_mark_node; - } - - /* ARM $8.4.3: Since you can't have a pointer to a reference, - you can't have arrays of references. If we allowed them, - then we'd be saying x[i] is legal for an array x, but - then you'd have to ask: what does `*(x + i)' mean? */ - if (TREE_CODE (type) == REFERENCE_TYPE) - error ("declaration of `%s' as array of references", name); - - if (size == error_mark_node) - type = error_mark_node; - - if (type == error_mark_node) - continue; - - if (size) - { - /* Must suspend_momentary here because the index - type may need to live until the end of the function. - For example, it is used in the declaration of a - variable which requires destructing at the end of - the function; then build_vec_delete will need this - value. */ - int yes = suspend_momentary (); - /* might be a cast */ - if (TREE_CODE (size) == NOP_EXPR - && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0))) - size = TREE_OPERAND (size, 0); - - /* If this is a template parameter, it'll be constant, but - we don't know what the value is yet. */ - if (TREE_CODE (size) == TEMPLATE_CONST_PARM) - goto dont_grok_size; - - if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE) - { - error ("size of array `%s' has non-integer type", name); - size = integer_one_node; - } - if (TREE_READONLY_DECL_P (size)) - size = decl_constant_value (size); - if (pedantic && integer_zerop (size)) - pedwarn ("ANSI C++ forbids zero-size array `%s'", name); - if (TREE_CONSTANT (size)) - { - if (INT_CST_LT (size, integer_zero_node)) - { - error ("size of array `%s' is negative", name); - size = integer_one_node; - } - itype = build_index_type (size_binop (MINUS_EXPR, size, - integer_one_node)); - } - else - { - if (pedantic) - pedwarn ("ANSI C++ forbids variable-size array `%s'", name); - dont_grok_size: - itype = - build_binary_op (MINUS_EXPR, size, integer_one_node, 1); - /* Make sure the array size remains visibly nonconstant - even if it is (eg) a const variable with known value. */ - size_varies = 1; - itype = variable_size (itype); - itype = build_index_type (itype); - } - resume_momentary (yes); - } - - /* Build the array type itself. - Merge any constancy or volatility into the target type. */ - - if (constp || volatilep) - type = build_type_variant (type, constp, volatilep); - - type = build_cplus_array_type (type, itype); - ctype = NULL_TREE; - } - break; - - case CALL_EXPR: - maybe_globalize_type (type); - { - tree arg_types; - - /* Declaring a function type. - Make sure we have a valid type for the function to return. */ -#if 0 - /* Is this an error? Should they be merged into TYPE here? */ - if (pedantic && (constp || volatilep)) - pedwarn ("function declared to return const or volatile result"); -#else - /* Merge any constancy or volatility into the target type - for the pointer. */ - - if (constp || volatilep) - { - type = build_type_variant (type, constp, volatilep); - if (IS_AGGR_TYPE (type)) - build_pointer_type (type); - constp = 0; - volatilep = 0; - } -#endif - - /* Warn about some types functions can't return. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("`%s' declared as function returning a function", name); - type = integer_type_node; - } - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("`%s' declared as function returning an array", name); - type = integer_type_node; - } - - if (ctype == NULL_TREE - && decl_context == FIELD - && (friendp == 0 || dname == current_class_name)) - ctype = current_class_type; - - if (ctype && flags == TYPENAME_FLAG) - TYPE_HAS_CONVERSION (ctype) = 1; - if (ctype && constructor_name (ctype) == dname) - { - /* We are within a class's scope. If our declarator name - is the same as the class name, and we are defining - a function, then it is a constructor/destructor, and - therefore returns a void type. */ - - if (flags == DTOR_FLAG) - { - /* ANSI C++ June 5 1992 WP 12.4.1. A destructor may - not be declared const or volatile. A destructor - may not be static. */ - if (staticp == 2) - error ("destructor cannot be static member function"); - if (TYPE_READONLY (type)) - { - error ("destructors cannot be declared `const'"); - return void_type_node; - } - if (TYPE_VOLATILE (type)) - { - error ("destructors cannot be declared `volatile'"); - return void_type_node; - } - if (decl_context == FIELD) - { - if (! member_function_or_else (ctype, current_class_type, - "destructor for alien class `%s' cannot be a member")) - return void_type_node; - } - } - else /* it's a constructor. */ - { - /* ANSI C++ June 5 1992 WP 12.1.2. A constructor may - not be declared const or volatile. A constructor may - not be virtual. A constructor may not be static. */ - if (staticp == 2) - error ("constructor cannot be static member function"); - if (virtualp) - { - pedwarn ("constructors cannot be declared virtual"); - virtualp = 0; - } - if (TYPE_READONLY (type)) - { - error ("constructors cannot be declared `const'"); - return void_type_node; - } - if (TYPE_VOLATILE (type)) - { - error ("constructors cannot be declared `volatile'"); - return void_type_node; - } - if (specbits & ~(RIDBIT (RID_INLINE)|RIDBIT (RID_STATIC))) - error ("return value type specifier for constructor ignored"); - type = TYPE_POINTER_TO (ctype); - if (decl_context == FIELD) - { - if (! member_function_or_else (ctype, current_class_type, - "constructor for alien class `%s' cannot be member")) - return void_type_node; - TYPE_HAS_CONSTRUCTOR (ctype) = 1; - if (return_type != return_ctor) - return NULL_TREE; - } - } - if (decl_context == FIELD) - staticp = 0; - } - else if (friendp && virtualp) - { - /* Cannot be both friend and virtual. */ - error ("virtual functions cannot be friends"); - specbits &= ~ RIDBIT (RID_FRIEND); - } - - if (decl_context == NORMAL && friendp) - error ("friend declaration not in class definition"); - - /* Pick up type qualifiers which should be applied to `this'. */ - quals = TREE_OPERAND (declarator, 2); - - /* Traditionally, declaring return type float means double. */ - - if (flag_traditional - && TYPE_MAIN_VARIANT (type) == float_type_node) - { - type = build_type_variant (double_type_node, - TYPE_READONLY (type), - TYPE_VOLATILE (type)); - } - - /* Construct the function type and go to the next - inner layer of declarator. */ - - { - int funcdef_p; - tree inner_parms = TREE_OPERAND (declarator, 1); - tree inner_decl = TREE_OPERAND (declarator, 0); - - declarator = TREE_OPERAND (declarator, 0); - - if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF) - inner_decl = TREE_OPERAND (inner_decl, 1); - - /* Say it's a definition only for the CALL_EXPR - closest to the identifier. */ - funcdef_p = - (inner_decl && - (TREE_CODE (inner_decl) == IDENTIFIER_NODE - || TREE_CODE (inner_decl) == TYPE_EXPR)) ? funcdef_flag : 0; - - arg_types = grokparms (inner_parms, funcdef_p); - } - - if (declarator) - { - /* Get past destructors, etc. - We know we have one because FLAGS will be non-zero. - - Complain about improper parameter lists here. */ - if (TREE_CODE (declarator) == BIT_NOT_EXPR) - { - declarator = TREE_OPERAND (declarator, 0); - - if (strict_prototype == 0 && arg_types == NULL_TREE) - arg_types = void_list_node; - else if (arg_types == NULL_TREE - || arg_types != void_list_node) - { - error ("destructors cannot be specified with parameters"); - arg_types = void_list_node; - } - } - } - /* the top level const or volatile is attached semantically only - to the function not the actual type. */ - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - { - int constp = TYPE_READONLY (type); - int volatilep = TYPE_VOLATILE (type); - type = build_function_type (TYPE_MAIN_VARIANT (type), - flag_traditional - ? 0 - : arg_types); - type = build_type_variant (type, constp, volatilep); - } - else - type = build_function_type (type, - flag_traditional - ? 0 - : arg_types); - } - break; - - case ADDR_EXPR: - case INDIRECT_REF: - maybe_globalize_type (type); - - /* Filter out pointers-to-references and references-to-references. - We can get these if a TYPE_DECL is used. */ - - if (TREE_CODE (type) == REFERENCE_TYPE) - { - error ("cannot declare %s to references", - TREE_CODE (declarator) == ADDR_EXPR - ? "references" : "pointers"); - declarator = TREE_OPERAND (declarator, 0); - continue; - } - - /* Merge any constancy or volatility into the target type - for the pointer. */ - - if (constp || volatilep) - { - type = build_type_variant (type, constp, volatilep); - if (IS_AGGR_TYPE (type)) - build_pointer_type (type); - constp = 0; - volatilep = 0; - } - - if (TREE_CODE (declarator) == ADDR_EXPR) - { - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("cannot declare references to functions; use pointer to function instead"); - type = build_pointer_type (type); - } - else - { - if (TYPE_MAIN_VARIANT (type) == void_type_node) - error ("invalid type: `void &'"); - else - type = build_reference_type (type); - } - } - else - type = build_pointer_type (type); - - /* Process a list of type modifier keywords (such as - const or volatile) that were given inside the `*' or `&'. */ - - if (TREE_TYPE (declarator)) - { - register tree typemodlist; - int erred = 0; - for (typemodlist = TREE_TYPE (declarator); typemodlist; - typemodlist = TREE_CHAIN (typemodlist)) - { - if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST]) - constp++; - else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE]) - volatilep++; - else if (!erred) - { - erred = 1; - error ("invalid type modifier within %s declarator", - TREE_CODE (declarator) == ADDR_EXPR - ? "reference" : "pointer"); - } - } - if (constp > 1) - warning ("duplicate `const'"); - if (volatilep > 1) - warning ("duplicate `volatile'"); - } - declarator = TREE_OPERAND (declarator, 0); - ctype = NULL_TREE; - break; - - case SCOPE_REF: - { - /* We have converted type names to NULL_TREE if the - name was bogus, or to a _TYPE node, if not. - - The variable CTYPE holds the type we will ultimately - resolve to. The code here just needs to build - up appropriate member types. */ - tree sname = TREE_OPERAND (declarator, 1); - /* Destructors can have their visibilities changed as well. */ - if (TREE_CODE (sname) == BIT_NOT_EXPR) - sname = TREE_OPERAND (sname, 0); - - if (TREE_COMPLEXITY (declarator) == 0) - /* This needs to be here, in case we are called - multiple times. */ ; - else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) - /* don't fall out into global scope. Hides real bug? --eichin */ ; - else if (TREE_COMPLEXITY (declarator) == current_class_depth) - { - TREE_COMPLEXITY (declarator) -= 1; - /* This popclass conflicts with the poplevel over in - grokdeclarator. See ``This poplevel conflicts'' */ - popclass (1); - } - else - my_friendly_abort (16); - - if (TREE_OPERAND (declarator, 0) == NULL_TREE) - { - /* We had a reference to a global decl, or - perhaps we were given a non-aggregate typedef, - in which case we cleared this out, and should just - keep going as though it wasn't there. */ - declarator = sname; - continue; - } - ctype = TREE_OPERAND (declarator, 0); - - if (sname == NULL_TREE) - goto done_scoping; - - if (TREE_CODE (sname) == IDENTIFIER_NODE) - { - /* This is the `standard' use of the scoping operator: - basetype :: member . */ - - if (TYPE_MAIN_VARIANT (ctype) == current_class_type || friendp) - { - if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); - else - { - if (TYPE_MAIN_VARIANT (ctype) != current_class_type) - { - error ("cannot declare member `%s::%s' within this class", - TYPE_NAME_STRING (ctype), name); - return void_type_node; - } - else if (extra_warnings) - warning ("extra qualification `%s' on member `%s' ignored", - TYPE_NAME_STRING (ctype), name); - type = build_offset_type (ctype, type); - } - } - else if (TYPE_SIZE (ctype) != NULL_TREE - || (specbits & RIDBIT (RID_TYPEDEF))) - { - tree t; - /* have to move this code elsewhere in this function. - this code is used for i.e., typedef int A::M; M *pm; */ - - if (explicit_int == -1 && decl_context == FIELD - && funcdef_flag == 0) - { - /* The code in here should only be used to build - stuff that will be grokked as visibility decls. */ - t = lookup_field (ctype, sname, 0, 0); - if (t) - { - t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type); - DECL_INITIAL (t) = init; - return t; - } - /* No such field, try member functions. */ - t = lookup_fnfields (TYPE_BINFO (ctype), sname, 0); - if (t) - { - if (flags == DTOR_FLAG) - t = TREE_VALUE (t); - else if (CLASSTYPE_METHOD_VEC (ctype) - && TREE_VALUE (t) == TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), 0)) - { - /* Don't include destructor with constructors. */ - t = DECL_CHAIN (TREE_VALUE (t)); - if (t == NULL_TREE) - error ("class `%s' does not have any constructors", IDENTIFIER_POINTER (sname)); - t = build_tree_list (NULL_TREE, t); - } - t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type); - DECL_INITIAL (t) = init; - return t; - } - - if (flags == TYPENAME_FLAG) - error_with_aggr_type (ctype, "type conversion is not a member of structure `%s'"); - else - error ("field `%s' is not a member of structure `%s'", - IDENTIFIER_POINTER (sname), - TYPE_NAME_STRING (ctype)); - } - if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); - else - { - if (current_class_type) - { - if (TYPE_MAIN_VARIANT (ctype) != current_class_type) - { - error ("cannot declare member `%s::%s' within this class", - TYPE_NAME_STRING (ctype), name); - return void_type_node; - } - else if (extra_warnings) - warning ("extra qualification `%s' on member `%s' ignored", - TYPE_NAME_STRING (ctype), name); - } - type = build_offset_type (ctype, type); - } - } - else if (uses_template_parms (ctype)) - { - enum tree_code c; - if (TREE_CODE (type) == FUNCTION_TYPE) - { - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - c = FUNCTION_DECL; - } - } - else - sorry ("structure `%s' not yet defined", - TYPE_NAME_STRING (ctype)); - declarator = sname; - } - else if (TREE_CODE (sname) == TYPE_EXPR) - { - /* A TYPE_EXPR will change types out from under us. - So do the TYPE_EXPR now, and make this SCOPE_REF - inner to the TYPE_EXPR's CALL_EXPR. - - This does not work if we don't get a CALL_EXPR back. - I did not think about error recovery, hence the - my_friendly_abort. */ - - /* Get the CALL_EXPR. */ - sname = grokoptypename (sname, 0); - my_friendly_assert (TREE_CODE (sname) == CALL_EXPR, 157); - type = TREE_TYPE (TREE_OPERAND (sname, 0)); - /* Scope the CALL_EXPR's name. */ - TREE_OPERAND (declarator, 1) = TREE_OPERAND (sname, 0); - /* Put the SCOPE_EXPR in the CALL_EXPR's innermost position. */ - TREE_OPERAND (sname, 0) = declarator; - /* Now work from the CALL_EXPR. */ - declarator = sname; - continue; - } - else if (TREE_CODE (sname) == SCOPE_REF) - my_friendly_abort (17); - else - { - done_scoping: - declarator = TREE_OPERAND (declarator, 1); - if (declarator && TREE_CODE (declarator) == CALL_EXPR) - /* In this case, we will deal with it later. */ - ; - else - { - if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), TREE_TYPE (type), TYPE_ARG_TYPES (type)); - else - type = build_offset_type (ctype, type); - } - } - } - break; - - case BIT_NOT_EXPR: - declarator = TREE_OPERAND (declarator, 0); - break; - - case TYPE_EXPR: - declarator = grokoptypename (declarator, 0); - if (explicit_int != -1) - if (comp_target_types (type, - TREE_TYPE (TREE_OPERAND (declarator, 0)), - 1) == 0) - error ("type conversion function declared to return incongruent type"); - else - pedwarn ("return type specified for type conversion function"); - type = TREE_TYPE (TREE_OPERAND (declarator, 0)); - maybe_globalize_type (type); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - declarator = NULL_TREE; - break; - - case ERROR_MARK: - declarator = NULL_TREE; - break; - - default: - my_friendly_abort (158); - } - } - - /* Now TYPE has the actual type. */ - - /* If this is declaring a typedef name, return a TYPE_DECL. */ - - if (specbits & RIDBIT (RID_TYPEDEF)) - { - tree decl; - - /* Note that the grammar rejects storage classes - in typenames, fields or parameters. */ - if (constp || volatilep) - type = build_type_variant (type, constp, volatilep); - - /* If the user declares "struct {...} foo" then `foo' will have - an anonymous name. Fill that name in now. Nothing can - refer to it, so nothing needs know about the name change. - The TYPE_NAME field was filled in by build_struct_xref. */ - if (TYPE_NAME (type) - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - { - /* replace the anonymous name with the real name everywhere. */ - lookup_tag_reverse (type, declarator); - TYPE_IDENTIFIER (type) = declarator; - } - -#if 0 /* not yet, should get fixed properly later */ - decl = make_type_decl (declarator, type); -#else - decl = build_decl (TYPE_DECL, declarator, type); -#endif - if (quals) - { - if (ctype == NULL_TREE) - { - if (TREE_CODE (type) != METHOD_TYPE) - error_with_decl (decl, "invalid type qualifier for non-method type"); - else - ctype = TYPE_METHOD_BASETYPE (type); - } - if (ctype != NULL_TREE) - grok_method_quals (ctype, decl, quals); - } - - if ((specbits & RIDBIT (RID_SIGNED)) - || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) - C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - - return decl; - } - - /* Detect the case of an array type of unspecified size - which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ - - if (type == typedef_type && TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == NULL_TREE) - { - type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type)); - } - - /* If this is a type name (such as, in a cast or sizeof), - compute the type and return it now. */ - - if (decl_context == TYPENAME) - { - /* Note that the grammar rejects storage classes - in typenames, fields or parameters. */ - if (constp || volatilep) - type = build_type_variant (type, constp, volatilep); - - /* Special case: "friend class foo" looks like a TYPENAME context. */ - if (friendp) - { - /* A friendly class? */ - if (current_class_type) - make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type)); - else - error("trying to make class `%s' a friend of global scope", - TYPE_NAME_STRING (type)); - type = void_type_node; - } - else if (quals) - { -#if 0 /* not yet, should get fixed properly later */ - tree dummy = make_type_decl (declarator, type); -#else - tree dummy = build_decl (TYPE_DECL, declarator, type); -#endif - if (ctype == NULL_TREE) - { - my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159); - ctype = TYPE_METHOD_BASETYPE (type); - } - grok_method_quals (ctype, dummy, quals); - type = TREE_TYPE (dummy); - } - - return type; - } - - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM) - { - if (declarator != NULL_TREE - && TREE_CODE (declarator) == IDENTIFIER_NODE) - { - if (IDENTIFIER_OPNAME_P (declarator)) - error ("operator `%s' declared void", - operator_name_string (declarator)); - else - error ("variable or field `%s' declared void", name); - } - else - error ("variable or field declared void"); - type = integer_type_node; - } - - /* Now create the decl, which may be a VAR_DECL, a PARM_DECL - or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ - - { - register tree decl; - - if (decl_context == PARM) - { - tree parmtype = type; - - if (ctype) - error ("cannot use `::' in parameter declaration"); - bad_specifiers ("parameter", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. - One declared as a member is really a pointer to member. - - Don't be misled by references. */ - - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - if (TREE_CODE (type) == ARRAY_TYPE) - { - if (parmtype == type) - { - /* Transfer const-ness of array into that of type - pointed to. */ - type = build_pointer_type - (build_type_variant (TREE_TYPE (type), constp, volatilep)); - volatilep = constp = 0; - } - else - type = build_pointer_type (TREE_TYPE (type)); - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == OFFSET_TYPE) - type = build_pointer_type (type); - - if (TREE_CODE (parmtype) == REFERENCE_TYPE) - { - /* Transfer const-ness of reference into that of type pointed to. */ - type = build_type_variant (build_reference_type (type), constp, volatilep); - constp = volatilep = 0; - } - - decl = build_decl (PARM_DECL, declarator, type); - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - DECL_ARG_TYPE (decl) = type; - if (TYPE_MAIN_VARIANT (type) == float_type_node) - DECL_ARG_TYPE (decl) = build_type_variant (double_type_node, - TYPE_READONLY (type), - TYPE_VOLATILE (type)); - else if (C_PROMOTING_INTEGER_TYPE_P (type)) - { - tree argtype; - - /* Retain unsignedness if traditional or if not really - getting wider. */ - if (TREE_UNSIGNED (type) - && (flag_traditional - || TYPE_PRECISION (type) - == TYPE_PRECISION (integer_type_node))) - argtype = unsigned_type_node; - else - argtype = integer_type_node; - DECL_ARG_TYPE (decl) = build_type_variant (argtype, - TYPE_READONLY (type), - TYPE_VOLATILE (type)); - } - } - else if (decl_context == FIELD) - { - if (type == error_mark_node) - { - /* Happens when declaring arrays of sizes which - are error_mark_node, for example. */ - decl = NULL_TREE; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - int publicp = 0; - - if (friendp == 0) - { - if (ctype == NULL_TREE) - ctype = current_class_type; - - if (ctype == NULL_TREE) - { - register int op = IDENTIFIER_OPNAME_P (declarator); - error ("can't make %s `%s' into a method -- not in a class", - op ? "operator" : "function", - op ? operator_name_string (declarator) : IDENTIFIER_POINTER (declarator)); - return void_type_node; - } - - /* ``A union may [ ... ] not [ have ] virtual functions.'' - ARM 9.5 */ - if (virtualp && TREE_CODE (ctype) == UNION_TYPE) - { - error ("function `%s' declared virtual inside a union", - IDENTIFIER_POINTER (declarator)); - return void_type_node; - } - - /* Don't convert type of operators new and delete to - METHOD_TYPE; they remain FUNCTION_TYPEs. */ - if (staticp < 2 - && declarator != ansi_opname[(int) NEW_EXPR] - && declarator != ansi_opname[(int) DELETE_EXPR]) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); - } - - /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ - publicp = ((specbits & RIDBIT (RID_EXTERN)) - || (ctype != NULL_TREE && funcdef_flag >= 0) -#if 0 - /* These are replicated in each object, so we shouldn't - set TREE_PUBLIC. */ - || (friendp - && !(specbits & RIDBIT (RID_STATIC)) - && !(specbits & RIDBIT (RID_INLINE))) -#endif - ); - decl = grokfndecl (ctype, type, declarator, - virtualp, flags, quals, - raises, friendp ? -1 : 0, publicp); - DECL_INLINE (decl) = inlinep; - } - else if (TREE_CODE (type) == METHOD_TYPE) - { - /* All method decls are public, so tell grokfndecl to set - TREE_PUBLIC, also. */ - decl = grokfndecl (ctype, type, declarator, - virtualp, flags, quals, - raises, friendp ? -1 : 0, 1); - DECL_INLINE (decl) = inlinep; - } - else if (TREE_CODE (type) == RECORD_TYPE - && CLASSTYPE_DECLARED_EXCEPTION (type)) - { - /* Handle a class-local exception declaration. */ - decl = build_lang_field_decl (VAR_DECL, declarator, type); - if (ctype == NULL_TREE) - ctype = current_class_type; - finish_exception_decl (TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL - ? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype), decl); - return void_type_node; - } - else if (TYPE_SIZE (type) == NULL_TREE && !staticp - && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0)) - { - if (declarator) - error ("field `%s' has incomplete type", - IDENTIFIER_POINTER (declarator)); - else - error ("field has incomplete type"); - - /* If we're instantiating a template, tell them which - instantiation made the field's type be incomplete. */ - if (current_class_type - && IDENTIFIER_TEMPLATE (current_class_type) - && declspecs && TREE_VALUE (declspecs) - && TREE_TYPE (TREE_VALUE (declspecs)) == type) - error (" in instantiation of template `%s'", - TYPE_NAME_STRING (current_class_type)); - - type = error_mark_node; - decl = NULL_TREE; - } - else - { - if (friendp) - { - if (declarator) - error ("`%s' is neither function nor method; cannot be declared friend", - IDENTIFIER_POINTER (declarator)); - else - { - error ("invalid friend declaration"); - return void_type_node; - } - friendp = 0; - } - decl = NULL_TREE; - } - - if (friendp) - { - tree t; - - /* Friends are treated specially. */ - if (ctype == current_class_type) - warning ("member functions are implicitly friends of their class"); - else if (decl && (t = DECL_NAME (decl))) - { - /* ARM $13.4.3 */ - if (t == ansi_opname[(int) MODIFY_EXPR]) - pedwarn ("operator `=' must be a member function"); - else - return do_friend (ctype, declarator, decl, - last_function_parms, flags, quals); - } - else return void_type_node; - } - - /* Structure field. It may not be a function, except for C++ */ - - if (decl == NULL_TREE) - { - bad_specifiers ("field", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); - - /* ANSI C++ June 5 1992 WP 9.2.2 and 9.4.2. A member-declarator - cannot have an initializer, and a static member declaration must - be defined elsewhere. */ - if (initialized) - { - if (staticp) - error ("static member `%s' must be defined separately from its declaration", - IDENTIFIER_POINTER (declarator)); - /* Note that initialization of const members is not - mentioned in the ARM or draft ANSI standard explicitly, - and it appears to be in common practice. However, - reading the draft section 9.2.2, it does say that a - member declarator can't have an initializer--it does - not except constant members, which also qualify as - member-declarators. */ - else if (!pedantic && (!constp || flag_ansi)) - warning ("ANSI C++ forbids initialization of %s `%s'", - constp ? "const member" : "member", - IDENTIFIER_POINTER (declarator)); - } - - if (staticp || (constp && initialized)) - { - /* C++ allows static class members. - All other work for this is done by grokfield. - This VAR_DECL is built by build_lang_field_decl. - All other VAR_DECLs are built by build_decl. */ - decl = build_lang_field_decl (VAR_DECL, declarator, type); - if (staticp || TREE_CODE (type) == ARRAY_TYPE) - TREE_STATIC (decl) = 1; - /* In class context, static means public visibility. */ - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = !initialized; - } - else - decl = build_lang_field_decl (FIELD_DECL, declarator, type); - } - } - else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) - { - int was_overloaded = 0; - tree original_name = declarator; - int publicp = 0; - - if (! declarator) return NULL_TREE; - - if (specbits & (RIDBIT (RID_AUTO) | RIDBIT (RID_REGISTER))) - error ("invalid storage class for function `%s'", name); - /* Function declaration not at top level. - Storage classes other than `extern' are not allowed - and `extern' makes no difference. */ - if (current_binding_level != global_binding_level - && (specbits & (RIDBIT (RID_STATIC) | RIDBIT (RID_INLINE))) - && pedantic) - pedwarn ("invalid storage class for function `%s'", name); - - if (ctype == NULL_TREE) - { - if (virtualp) - { - error ("virtual non-class function `%s'", name); - virtualp = 0; - } - - /* ARM $13.4.3 */ - /* XXX: It's likely others should also be forbidden. (bpk) */ - if (declarator == ansi_opname[(int) MODIFY_EXPR]) - warning ("operator `=' must be a member function"); - - if (current_lang_name == lang_name_cplusplus - && ! (IDENTIFIER_LENGTH (original_name) == 4 - && IDENTIFIER_POINTER (original_name)[0] == 'm' - && strcmp (IDENTIFIER_POINTER (original_name), "main") == 0) - && ! (IDENTIFIER_LENGTH (original_name) > 10 - && IDENTIFIER_POINTER (original_name)[0] == '_' - && IDENTIFIER_POINTER (original_name)[1] == '_' - && strncmp (IDENTIFIER_POINTER (original_name)+2, "builtin_", 8) == 0)) - { - /* Plain overloading: will not be grok'd by grokclassfn. */ - declarator = build_decl_overload (dname, TYPE_ARG_TYPES (type), 0); - was_overloaded = 1; - } - } - else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); - - /* Record presence of `static'. In C++, `inline' is like `static'. - Methods of classes should be public, unless we're dropping them - into some other file, so we don't clear TREE_PUBLIC for them. */ - publicp - = ((ctype - && ! CLASSTYPE_INTERFACE_UNKNOWN (ctype) - && ! CLASSTYPE_INTERFACE_ONLY (ctype)) - || !(specbits & (RIDBIT (RID_STATIC) - | RIDBIT (RID_INLINE)))); - - decl = grokfndecl (ctype, type, original_name, - virtualp, flags, quals, - raises, - processing_template_decl ? 0 : friendp ? 2 : 1, - publicp); - - if (ctype == NULL_TREE) - DECL_ASSEMBLER_NAME (decl) = declarator; - - if (staticp == 1) - { - int illegal_static = 0; - - /* Don't allow a static member function in a class, and forbid - declaring main to be static. */ - if (TREE_CODE (type) == METHOD_TYPE) - { - error_with_decl (decl, - "cannot declare member function `%s' to have static linkage"); - illegal_static = 1; - } - else if (! was_overloaded - && ! ctype - && IDENTIFIER_LENGTH (original_name) == 4 - && IDENTIFIER_POINTER (original_name)[0] == 'm' - && ! strcmp (IDENTIFIER_POINTER (original_name), "main")) - { - error ("cannot declare function `main' to have static linkage"); - illegal_static = 1; - } - - if (illegal_static) - { - staticp = 0; - specbits &= ~ RIDBIT (RID_STATIC); - } - } - - /* Record presence of `inline', if it is reasonable. */ - if (inlinep) - { - tree last = tree_last (TYPE_ARG_TYPES (type)); - - if (! was_overloaded - && ! ctype - && ! strcmp (IDENTIFIER_POINTER (original_name), "main")) - warning ("cannot inline function `main'"); - else if (last && last != void_list_node) - warning ("inline declaration ignored for function with `...'"); - else - /* Assume that otherwise the function can be inlined. */ - DECL_INLINE (decl) = 1; - - if (specbits & RIDBIT (RID_EXTERN)) - { - current_extern_inline = 1; - if (pedantic) - error ("ANSI C++ does not permit `extern inline'"); - else if (flag_ansi) - warning ("ANSI C++ does not permit `extern inline'"); - } - } - if (was_overloaded) - DECL_OVERLOADED (decl) = 1; - } - else - { - /* It's a variable. */ - - bad_specifiers ("variable", virtualp, quals != NULL_TREE, - friendp, raises != NULL_TREE); - if (inlinep) - warning ("variable declared `inline'"); - - /* An uninitialized decl with `extern' is a reference. */ - decl = grokvardecl (type, declarator, specbits, initialized); - if (ctype) - { - if (staticp == 1) - { - error ("cannot declare member `%s' to have static linkage", - lang_printable_name (decl)); - staticp = 0; - specbits &= ~ RIDBIT (RID_STATIC); - } - if (specbits & RIDBIT (RID_EXTERN)) - { - error ("cannot explicitly declare member `%s' to have extern linkage", - lang_printable_name (decl)); - specbits &= ~ RIDBIT (RID_EXTERN); - } - } - } - - /* Record `register' declaration for warnings on & - and in case doing stupid register allocation. */ - - if (specbits & RIDBIT (RID_REGISTER)) - DECL_REGISTER (decl) = 1; - - /* Record constancy and volatility. */ - - if (constp) - TREE_READONLY (decl) = TREE_CODE (type) != REFERENCE_TYPE; - if (volatilep) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } - - return decl; - } -} - -/* Tell if a parmlist/exprlist looks like an exprlist or a parmlist. - An empty exprlist is a parmlist. An exprlist which - contains only identifiers at the global level - is a parmlist. Otherwise, it is an exprlist. */ -int -parmlist_is_exprlist (exprs) - tree exprs; -{ - if (exprs == NULL_TREE || TREE_PARMLIST (exprs)) - return 0; - - if (current_binding_level == global_binding_level) - { - /* At the global level, if these are all identifiers, - then it is a parmlist. */ - while (exprs) - { - if (TREE_CODE (TREE_VALUE (exprs)) != IDENTIFIER_NODE) - return 1; - exprs = TREE_CHAIN (exprs); - } - return 0; - } - return 1; -} - -/* Make sure that the this list of PARMS has a chance of being - grokked by `grokparms'. - - @@ This is really weak, but the grammar does not allow us - @@ to easily reject things that this has to catch as syntax errors. */ -static int -parmlist_is_random (parms) - tree parms; -{ - if (parms == NULL_TREE) - return 0; - - if (TREE_CODE (parms) != TREE_LIST) - return 1; - - while (parms) - { - if (parms == void_list_node) - return 0; - - if (TREE_CODE (TREE_VALUE (parms)) != TREE_LIST) - return 1; - /* Don't get faked out by overloaded functions, which - masquerade as TREE_LISTs! */ - if (TREE_TYPE (TREE_VALUE (parms)) == unknown_type_node) - return 1; - parms = TREE_CHAIN (parms); - } - return 0; -} - -/* Subroutine of `grokparms'. In a fcn definition, arg types must - be complete. - - C++: also subroutine of `start_function'. */ -static void -require_complete_types_for_parms (parms) - tree parms; -{ - while (parms) - { - tree type = TREE_TYPE (parms); - if (TYPE_SIZE (type) == NULL_TREE) - { - if (DECL_NAME (parms)) - error ("parameter `%s' has incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parms))); - else - error ("parameter has incomplete type"); - TREE_TYPE (parms) = error_mark_node; - } -#if 0 - /* If the arg types are incomplete in a declaration, - they must include undefined tags. - These tags can never be defined in the scope of the declaration, - so the types can never be completed, - and no call can be compiled successfully. */ - /* This is not the right behavior for C++, but not having - it is also probably wrong. */ - else - { - /* Now warn if is a pointer to an incomplete type. */ - while (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - type = TYPE_MAIN_VARIANT (type); - if (TYPE_SIZE (type) == NULL_TREE) - { - if (DECL_NAME (parm) != NULL_TREE) - warning ("parameter `%s' points to incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parm))); - else - warning ("parameter points to incomplete type"); - } - } -#endif - parms = TREE_CHAIN (parms); - } -} - -/* Decode the list of parameter types for a function type. - Given the list of things declared inside the parens, - return a list of types. - - The list we receive can have three kinds of elements: - an IDENTIFIER_NODE for names given without types, - a TREE_LIST node for arguments given as typespecs or names with typespecs, - or void_type_node, to mark the end of an argument list - when additional arguments are not permitted (... was not used). - - FUNCDEF_FLAG is nonzero for a function definition, 0 for - a mere declaration. A nonempty identifier-list gets an error message - when FUNCDEF_FLAG is zero. - If FUNCDEF_FLAG is 1, then parameter types must be complete. - If FUNCDEF_FLAG is -1, then parameter types may be incomplete. - - If all elements of the input list contain types, - we return a list of the types. - If all elements contain no type (except perhaps a void_type_node - at the end), we return a null list. - If some have types and some do not, it is an error, and we - return a null list. - - Also set last_function_parms to either - a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs. - A list of names is converted to a chain of PARM_DECLs - by store_parm_decls so that ultimately it is always a chain of decls. - - Note that in C++, parameters can take default values. These default - values are in the TREE_PURPOSE field of the TREE_LIST. It is - an error to specify default values which are followed by parameters - that have no default values, or an ELLIPSES. For simplicities sake, - only parameters which are specified with their types can take on - default values. */ - -static tree -grokparms (first_parm, funcdef_flag) - tree first_parm; - int funcdef_flag; -{ - tree result = NULL_TREE; - tree decls = NULL_TREE; - - if (first_parm != NULL_TREE - && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE) - { - if (! funcdef_flag) - warning ("parameter names (without types) in function declaration"); - last_function_parms = first_parm; - return NULL_TREE; - } - else - { - /* Types were specified. This is a list of declarators - each represented as a TREE_LIST node. */ - register tree parm, chain; - int any_init = 0, any_error = 0, saw_void = 0; - - if (first_parm != NULL_TREE) - { - tree last_result = NULL_TREE; - tree last_decl = NULL_TREE; - - for (parm = first_parm; parm != NULL_TREE; parm = chain) - { - tree type, list_node = parm; - register tree decl = TREE_VALUE (parm); - tree init = TREE_PURPOSE (parm); - - chain = TREE_CHAIN (parm); - /* @@ weak defense against parse errors. */ - if (decl != void_type_node && TREE_CODE (decl) != TREE_LIST) - { - /* Give various messages as the need arises. */ - if (TREE_CODE (decl) == STRING_CST) - error ("invalid string constant `%s'", - TREE_STRING_POINTER (decl)); - else if (TREE_CODE (decl) == INTEGER_CST) - error ("invalid integer constant in parameter list, did you forget to give parameter name?"); - continue; - } - - if (decl != void_type_node) - { - /* @@ May need to fetch out a `raises' here. */ - decl = grokdeclarator (TREE_VALUE (decl), - TREE_PURPOSE (decl), - PARM, init != NULL_TREE, NULL_TREE); - if (! decl) - continue; - type = TREE_TYPE (decl); - if (TYPE_MAIN_VARIANT (type) == void_type_node) - decl = void_type_node; - else if (TREE_CODE (type) == METHOD_TYPE) - { - if (DECL_NAME (decl)) - /* Cannot use `error_with_decl' here because - we don't have DECL_CONTEXT set up yet. */ - error ("parameter `%s' invalidly declared method type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - else - error ("parameter invalidly declared method type"); - type = build_pointer_type (type); - TREE_TYPE (decl) = type; - } - else if (TREE_CODE (type) == OFFSET_TYPE) - { - if (DECL_NAME (decl)) - error ("parameter `%s' invalidly declared offset type", - IDENTIFIER_POINTER (DECL_NAME (decl))); - else - error ("parameter invalidly declared offset type"); - type = build_pointer_type (type); - TREE_TYPE (decl) = type; - } - else if (TREE_CODE (type) == RECORD_TYPE - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - { - abstract_virtuals_error (decl, type); - any_error = 1; /* seems like a good idea */ - } - } - - if (decl == void_type_node) - { - if (result == NULL_TREE) - { - result = void_list_node; - last_result = result; - } - else - { - TREE_CHAIN (last_result) = void_list_node; - last_result = void_list_node; - } - saw_void = 1; - if (chain - && (chain != void_list_node || TREE_CHAIN (chain))) - error ("`void' in parameter list must be entire list"); - break; - } - - /* Since there is a prototype, args are passed in their own types. */ - DECL_ARG_TYPE (decl) = TREE_TYPE (decl); -#ifdef PROMOTE_PROTOTYPES - if (C_PROMOTING_INTEGER_TYPE_P (type)) - DECL_ARG_TYPE (decl) = integer_type_node; -#endif - if (!any_error) - { - if (init) - { - any_init++; - if (TREE_CODE (init) == SAVE_EXPR) - PARM_DECL_EXPR (init) = 1; - else if (TREE_CODE (init) == VAR_DECL) - { - if (IDENTIFIER_LOCAL_VALUE (DECL_NAME (init))) - { - /* ``Local variables may not be used in default - argument expressions.'' dpANSI C++ 8.2.6 */ - /* If extern int i; within a function is not - considered a local variable, then this code is - wrong. */ - error_with_decl (init, "local variable `%s' may not be used as a default argument"); - any_error = 1; - } - else if (TREE_READONLY_DECL_P (init)) - init = decl_constant_value (init); - } - else - init = require_instantiated_type (type, init, integer_zero_node); - } - else if (any_init) - { - error ("all trailing parameters must have default arguments"); - any_error = 1; - } - } - else - init = NULL_TREE; - - if (decls == NULL_TREE) - { - decls = decl; - last_decl = decls; - } - else - { - TREE_CHAIN (last_decl) = decl; - last_decl = decl; - } - if (TREE_PERMANENT (list_node)) - { - TREE_PURPOSE (list_node) = init; - TREE_VALUE (list_node) = type; - TREE_CHAIN (list_node) = NULL_TREE; - } - else - list_node = saveable_tree_cons (init, type, NULL_TREE); - if (result == NULL_TREE) - { - result = list_node; - last_result = result; - } - else - { - TREE_CHAIN (last_result) = list_node; - last_result = list_node; - } - } - if (last_result) - TREE_CHAIN (last_result) = NULL_TREE; - /* If there are no parameters, and the function does not end - with `...', then last_decl will be NULL_TREE. */ - if (last_decl != NULL_TREE) - TREE_CHAIN (last_decl) = NULL_TREE; - } - } - - last_function_parms = decls; - - /* In a fcn definition, arg types must be complete. */ - if (funcdef_flag > 0) - require_complete_types_for_parms (last_function_parms); - - return result; -} - -/* These memoizing functions keep track of special properties which - a class may have. `grok_ctor_properties' notices whether a class - has a constructor of the for X(X&), and also complains - if the class has a constructor of the form X(X). - `grok_op_properties' takes notice of the various forms of - operator= which are defined, as well as what sorts of type conversion - may apply. Both functions take a FUNCTION_DECL as an argument. */ -void -grok_ctor_properties (ctype, decl) - tree ctype, decl; -{ - tree parmtypes = FUNCTION_ARG_CHAIN (decl); - tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; - - if (parmtypes && TREE_CHAIN (parmtypes) - && TREE_CODE (TREE_VALUE (TREE_CHAIN (parmtypes))) == REFERENCE_TYPE - && TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (TREE_VALUE (TREE_CHAIN (parmtypes))))) - { - parmtypes = TREE_CHAIN (parmtypes); - parmtype = TREE_VALUE (parmtypes); - } - - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype) - { - if (TREE_CHAIN (parmtypes) == NULL_TREE - || TREE_CHAIN (parmtypes) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (parmtypes))) - { - TYPE_HAS_INIT_REF (ctype) = 1; - TYPE_GETS_INIT_REF (ctype) = 1; - if (TYPE_READONLY (TREE_TYPE (parmtype))) - TYPE_GETS_CONST_INIT_REF (ctype) = 1; - } - else - TYPE_GETS_INIT_AGGR (ctype) = 1; - } - else if (TYPE_MAIN_VARIANT (parmtype) == ctype) - { - if (TREE_CHAIN (parmtypes) != NULL_TREE - && TREE_CHAIN (parmtypes) == void_list_node) - error ("invalid constructor; you probably meant `%s (%s&)'", - TYPE_NAME_STRING (ctype), - TYPE_NAME_STRING (ctype)); - SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype); - TYPE_GETS_INIT_AGGR (ctype) = 1; - } - else if (TREE_CODE (parmtype) == VOID_TYPE - || TREE_PURPOSE (parmtypes) != NULL_TREE) - TYPE_HAS_DEFAULT_CONSTRUCTOR (ctype) = 1; -} - -/* Do a little sanity-checking on how they declared their operator. */ -static void -grok_op_properties (decl, virtualp) - tree decl; - int virtualp; -{ - tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - - if (DECL_STATIC_FUNCTION_P (decl)) - { - if (DECL_NAME (decl) == ansi_opname[(int) NEW_EXPR]) - { - if (virtualp) - error ("`operator new' cannot be declared virtual"); - - /* Take care of function decl if we had syntax errors. */ - if (argtypes == NULL_TREE) - TREE_TYPE (decl) = - build_function_type (ptr_type_node, - hash_tree_chain (integer_type_node, - void_list_node)); - else - decl = coerce_new_type (TREE_TYPE (decl)); - } - else if (DECL_NAME (decl) == ansi_opname[(int) DELETE_EXPR]) - { - if (virtualp) - error ("`operator delete' cannot be declared virtual"); - - if (argtypes == NULL_TREE) - TREE_TYPE (decl) = - build_function_type (void_type_node, - hash_tree_chain (ptr_type_node, - void_list_node)); - else - decl = coerce_delete_type (TREE_TYPE (decl)); - } - else - error_with_decl (decl, "`%s' cannot be a static member function"); - } - else if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtypes; - tree parmtype; - - if (argtypes == NULL_TREE) - { - error_with_decl (decl, "too few arguments to `%s'"); - return; - } - parmtypes = TREE_CHAIN (argtypes); - parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; - - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TREE_TYPE (parmtype) == current_class_type) - { - TYPE_HAS_ASSIGN_REF (current_class_type) = 1; - TYPE_GETS_ASSIGN_REF (current_class_type) = 1; - if (TYPE_READONLY (TREE_TYPE (parmtype))) - TYPE_GETS_CONST_INIT_REF (current_class_type) = 1; - } - } -} - -/* Get the struct, enum or union (CODE says which) with tag NAME. - Define the tag as a forward-reference if it is not defined. - - C++: If a class derivation is given, process it here, and report - an error if multiple derivation declarations are not identical. - - If this is a definition, come in through xref_tag and only look in - the current frame for the name (since C++ allows new names in any - scope.) */ - -/* avoid rewriting all callers of xref_tag */ -static int xref_next_defn = 0; - -tree -xref_defn_tag (code_type_node, name, binfo) - tree code_type_node; - tree name, binfo; -{ - tree rv, ncp; - xref_next_defn = 1; - - if (class_binding_level) - { - tree n1; - char *buf; - /* we need to build a new IDENTIFIER_NODE for name which nukes - * the pieces... */ - n1 = IDENTIFIER_LOCAL_VALUE (current_class_name); - if (n1) - n1 = DECL_NAME (n1); - else - n1 = current_class_name; - - buf = (char *) alloca (4 + IDENTIFIER_LENGTH (n1) - + IDENTIFIER_LENGTH (name)); - - sprintf (buf, "%s::%s", IDENTIFIER_POINTER (n1), - IDENTIFIER_POINTER (name)); - ncp = get_identifier (buf); -#ifdef SPEW_DEBUG - if (spew_debug) - printf("*** %s ***\n", IDENTIFIER_POINTER (ncp)); -#endif -#if 0 - IDENTIFIER_LOCAL_VALUE (name) = - build_lang_decl (TYPE_DECL, ncp, NULL_TREE); -#endif - rv = xref_tag (code_type_node, name, binfo); - pushdecl_top_level (build_lang_decl (TYPE_DECL, ncp, rv)); - } - else - { - rv = xref_tag (code_type_node, name, binfo); - } - xref_next_defn = 0; - return rv; -} - -tree -xref_tag (code_type_node, name, binfo) - tree code_type_node; - tree name, binfo; -{ - enum tag_types tag_code; - enum tree_code code; - int temp = 0; - int i, len; - register tree ref; - struct binding_level *b - = (class_binding_level ? class_binding_level : current_binding_level); - - tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); - switch (tag_code) - { - case record_type: - case class_type: - case exception_type: - code = RECORD_TYPE; - len = list_length (binfo); - break; - case union_type: - code = UNION_TYPE; - if (binfo) - { - error ("derived union `%s' invalid", IDENTIFIER_POINTER (name)); - binfo = NULL_TREE; - } - len = 0; - break; - case enum_type: - code = ENUMERAL_TYPE; - break; - default: - my_friendly_abort (18); - } - - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - if (xref_next_defn) - { - /* If we know we are defining this tag, only look it up in this scope - * and don't try to find it as a type. */ - xref_next_defn = 0; - ref = lookup_tag (code, name, b, 1); - } - else - { - ref = lookup_tag (code, name, b, 0); - - if (! ref) - { - /* Try finding it as a type declaration. If that wins, use it. */ - ref = lookup_name (name, 1); - if (ref && TREE_CODE (ref) == TYPE_DECL - && TREE_CODE (TREE_TYPE (ref)) == code) - ref = TREE_TYPE (ref); - else - ref = NULL_TREE; - } - } - - push_obstacks_nochange (); - - if (! ref) - { - /* If no such tag is yet defined, create a forward-reference node - and record it as the "definition". - When a real declaration of this type is found, - the forward-reference will be altered into a real type. */ - - /* In C++, since these migrate into the global scope, we must - build them on the permanent obstack. */ - - temp = allocation_temporary_p (); - if (temp) - end_temporary_allocation (); - - if (code == ENUMERAL_TYPE) - { - ref = make_node (ENUMERAL_TYPE); - - /* Give the type a default layout like unsigned int - to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); - TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); - TREE_UNSIGNED (ref) = 1; - TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); - TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); - TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); - - /* Enable us to recognize when a type is created in class context. - To do nested classes correctly, this should probably be cleared - out when we leave this classes scope. Currently this in only - done in `start_enum'. */ - - pushtag (name, ref); - if (flag_cadillac) - cadillac_start_enum (ref); - } - else if (tag_code == exception_type) - { - ref = make_lang_type (code); - /* Enable us to recognize when an exception type is created in - class context. To do nested classes correctly, this should - probably be cleared out when we leave this class's scope. */ - CLASSTYPE_DECLARED_EXCEPTION (ref) = 1; - pushtag (name, ref); - if (flag_cadillac) - cadillac_start_struct (ref); - } - else - { - extern tree pending_vtables; - struct binding_level *old_b = class_binding_level; - int needs_writing; - - ref = make_lang_type (code); - - /* Record how to set the visibility of this class's - virtual functions. If write_virtuals == 2 or 3, then - inline virtuals are ``extern inline''. */ - switch (write_virtuals) - { - case 0: - case 1: - needs_writing = 1; - break; - case 2: - needs_writing = !! value_member (name, pending_vtables); - break; - case 3: - needs_writing - = ! (CLASSTYPE_INTERFACE_ONLY (ref) || CLASSTYPE_INTERFACE_UNKNOWN (ref)); - break; - default: - needs_writing = 0; - } - - CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = needs_writing; - -#ifdef NONNESTED_CLASSES - /* Class types don't nest the way enums do. */ - class_binding_level = (struct binding_level *)0; -#endif - pushtag (name, ref); - class_binding_level = old_b; - - if (flag_cadillac) - cadillac_start_struct (ref); - } - } - else - { - if (IS_AGGR_TYPE_CODE (code)) - { - if (IS_AGGR_TYPE (ref) - && ((tag_code == exception_type) - != (CLASSTYPE_DECLARED_EXCEPTION (ref) == 1))) - { - error ("type `%s' is both exception and aggregate type", - IDENTIFIER_POINTER (name)); - CLASSTYPE_DECLARED_EXCEPTION (ref) = (tag_code == exception_type); - } - } - - /* If it no longer looks like a nested type, make sure it's - in global scope. */ - if (b == global_binding_level && !class_binding_level - && IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE) - IDENTIFIER_GLOBAL_VALUE (name) = TYPE_NAME (ref); - - if (binfo) - { - tree tt1 = binfo; - tree tt2 = TYPE_BINFO_BASETYPES (ref); - - if (TYPE_BINFO_BASETYPES (ref)) - for (i = 0; tt1; i++, tt1 = TREE_CHAIN (tt1)) - if (TREE_VALUE (tt1) != TYPE_IDENTIFIER (BINFO_TYPE (TREE_VEC_ELT (tt2, i)))) - { - error ("redeclaration of derivation chain of type `%s'", - IDENTIFIER_POINTER (name)); - break; - } - - if (tt1 == NULL_TREE) - /* The user told us something we already knew. */ - goto just_return; - - /* In C++, since these migrate into the global scope, we must - build them on the permanent obstack. */ - end_temporary_allocation (); - } - } - - if (binfo) - { - /* In the declaration `A : X, Y, ... Z' we mark all the types - (A, X, Y, ..., Z) so we can check for duplicates. */ - tree binfos; - - SET_CLASSTYPE_MARKED (ref); - BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len); - - for (i = 0; binfo; binfo = TREE_CHAIN (binfo)) - { - /* The base of a derived struct is public. */ - int via_public = (tag_code != class_type - || TREE_PURPOSE (binfo) == (tree)visibility_public - || TREE_PURPOSE (binfo) == (tree)visibility_public_virtual); - int via_protected = TREE_PURPOSE (binfo) == (tree)visibility_protected; - int via_virtual = (TREE_PURPOSE (binfo) == (tree)visibility_private_virtual - || TREE_PURPOSE (binfo) == (tree)visibility_public_virtual - || TREE_PURPOSE (binfo) == (tree)visibility_default_virtual); - tree basetype = TREE_TYPE (TREE_VALUE (binfo)); - tree base_binfo; - - GNU_xref_hier (IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (TREE_VALUE (binfo)), - via_public, via_virtual, 0); - - if (basetype && TREE_CODE (basetype) == TYPE_DECL) - basetype = TREE_TYPE (basetype); - if (!basetype || TREE_CODE (basetype) != RECORD_TYPE) - { - error ("base type `%s' fails to be a struct or class type", - IDENTIFIER_POINTER (TREE_VALUE (binfo))); - continue; - } -#if 1 - /* This code replaces similar code in layout_basetypes. */ - else if (TYPE_SIZE (basetype) == NULL_TREE) - { - error_with_aggr_type (basetype, "base class `%s' has incomplete type"); - continue; - } -#endif - else - { - if (CLASSTYPE_MARKED (basetype)) - { - if (basetype == ref) - error_with_aggr_type (basetype, "recursive type `%s' undefined"); - else - error_with_aggr_type (basetype, "duplicate base type `%s' invalid"); - continue; - } - - /* Note that the BINFO records which describe individual - inheritances are *not* shared in the lattice! They - cannot be shared because a given baseclass may be - inherited with different `accessibility' by different - derived classes. (Each BINFO record describing an - individual inheritance contains flags which say what - the `accessibility' of that particular inheritance is.) */ - - base_binfo = make_binfo (integer_zero_node, basetype, - TYPE_BINFO_VTABLE (basetype), - TYPE_BINFO_VIRTUALS (basetype), 0); - - TREE_VEC_ELT (binfos, i) = base_binfo; - TREE_VIA_PUBLIC (base_binfo) = via_public; - TREE_VIA_PROTECTED (base_binfo) = via_protected; - TREE_VIA_VIRTUAL (base_binfo) = via_virtual; - - SET_CLASSTYPE_MARKED (basetype); -#if 0 -/* XYZZY TEST VIRTUAL BASECLASSES */ -if (CLASSTYPE_N_BASECLASSES (basetype) == NULL_TREE - && TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype) - && via_virtual == 0) - { - warning ("making type `%s' a virtual baseclass", - TYPE_NAME_STRING (basetype)); - via_virtual = 1; - } -#endif - /* We are free to modify these bits because they are meaningless - at top level, and BASETYPE is a top-level type. */ - if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1; - TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; - } - - TYPE_GETS_ASSIGNMENT (ref) |= TYPE_GETS_ASSIGNMENT (basetype); - TYPE_OVERLOADS_METHOD_CALL_EXPR (ref) |= TYPE_OVERLOADS_METHOD_CALL_EXPR (basetype); - TREE_GETS_NEW (ref) |= TREE_GETS_NEW (basetype); - TREE_GETS_DELETE (ref) |= TREE_GETS_DELETE (basetype); - CLASSTYPE_LOCAL_TYPEDECLS (ref) |= CLASSTYPE_LOCAL_TYPEDECLS (basetype); - i += 1; - } - } - if (i) - TREE_VEC_LENGTH (binfos) = i; - else - BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE; - - if (i > 1) - TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; - else if (i == 1) - TYPE_USES_MULTIPLE_INHERITANCE (ref) - = TYPE_USES_MULTIPLE_INHERITANCE (BINFO_TYPE (TREE_VEC_ELT (binfos, 0))); - if (TYPE_USES_MULTIPLE_INHERITANCE (ref)) - TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; - - /* Unmark all the types. */ - while (--i >= 0) - CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i))); - CLEAR_CLASSTYPE_MARKED (ref); - } - - just_return: - - /* Until the type is defined, tentatively accept whatever - structure tag the user hands us. */ - if (TYPE_SIZE (ref) == NULL_TREE - && ref != current_class_type - /* Have to check this, in case we have contradictory tag info. */ - && IS_AGGR_TYPE_CODE (TREE_CODE (ref))) - { - if (tag_code == class_type) - CLASSTYPE_DECLARED_CLASS (ref) = 1; - else if (tag_code == record_type) - CLASSTYPE_DECLARED_CLASS (ref) = 0; - } - - pop_obstacks (); - - return ref; -} - -static tree current_local_enum = NULL_TREE; - -/* Begin compiling the definition of an enumeration type. - NAME is its name (or null if anonymous). - Returns the type object, as yet incomplete. - Also records info about it so that build_enumerator - may be used to declare the individual values as they are read. */ - -tree -start_enum (name) - tree name; -{ - register tree enumtype = NULL_TREE; - struct binding_level *b - = (class_binding_level ? class_binding_level : current_binding_level); - - /* If this is the real definition for a previous forward reference, - fill in the contents in the same object that used to be the - forward reference. */ - - if (name != NULL_TREE) - enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1); - - if (enumtype == NULL_TREE || TREE_CODE (enumtype) != ENUMERAL_TYPE) - { - enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype); - } - - if (current_class_type) - TREE_ADDRESSABLE (b->tags) = 1; - current_local_enum = NULL_TREE; - - if (TYPE_VALUES (enumtype) != NULL_TREE) - { - /* This enum is a named one that has been declared already. */ - error ("redeclaration of `enum %s'", IDENTIFIER_POINTER (name)); - - /* Completely replace its old definition. - The old enumerators remain defined, however. */ - TYPE_VALUES (enumtype) = NULL_TREE; - } - - /* Initially, set up this enum as like `int' - so that we can create the enumerators' declarations and values. - Later on, the precision of the type may be changed and - it may be laid out again. */ - - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - TYPE_SIZE (enumtype) = NULL_TREE; - fixup_unsigned_type (enumtype); - - /* We copy this value because enumerated type constants - are really of the type of the enumerator, not integer_type_node. */ - enum_next_value = copy_node (integer_zero_node); - - GNU_xref_decl (current_function_decl, enumtype); - return enumtype; -} - -/* After processing and defining all the values of an enumeration type, - install their decls in the enumeration type and finish it off. - ENUMTYPE is the type object and VALUES a list of name-value pairs. - Returns ENUMTYPE. */ - -tree -finish_enum (enumtype, values) - register tree enumtype, values; -{ - register tree pair; - register HOST_WIDE_INT maxvalue = 0; - register HOST_WIDE_INT minvalue = 0; - register HOST_WIDE_INT i; - - TYPE_VALUES (enumtype) = values; - - /* Calculate the maximum value of any enumerator in this type. */ - - if (values) - { - /* Speed up the main loop by performing some precalculations */ - - HOST_WIDE_INT value = TREE_INT_CST_LOW (TREE_VALUE (values)); - TREE_TYPE (TREE_VALUE (values)) = enumtype; - minvalue = maxvalue = value; - - for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair)) - { - value = TREE_INT_CST_LOW (TREE_VALUE (pair)); - if (value > maxvalue) - maxvalue = value; - else if (value < minvalue) - minvalue = value; - TREE_TYPE (TREE_VALUE (pair)) = enumtype; - } - } - - if (flag_short_enums) - { - /* Determine the precision this type needs, lay it out, and define it. */ - - for (i = maxvalue; i; i >>= 1) - TYPE_PRECISION (enumtype)++; - - if (!TYPE_PRECISION (enumtype)) - TYPE_PRECISION (enumtype) = 1; - - /* Cancel the laying out previously done for the enum type, - so that fixup_unsigned_type will do it over. */ - TYPE_SIZE (enumtype) = NULL_TREE; - - fixup_unsigned_type (enumtype); - } - - TREE_INT_CST_LOW (TYPE_MAX_VALUE (enumtype)) = maxvalue; - - /* An enum can have some negative values; then it is signed. */ - if (minvalue < 0) - { - TREE_INT_CST_LOW (TYPE_MIN_VALUE (enumtype)) = minvalue; - TREE_INT_CST_HIGH (TYPE_MIN_VALUE (enumtype)) = -1; - TREE_UNSIGNED (enumtype) = 0; - } - if (flag_cadillac) - cadillac_finish_enum (enumtype); - - /* Finish debugging output for this type. */ -#if 0 - /* @@ Do we ever generate generate ENUMERAL_TYPE nodes for which debugging - information should *not* be generated? I think not. */ - if (! DECL_IGNORED_P (TYPE_NAME (enumtype))) -#endif - rest_of_type_compilation (enumtype, global_bindings_p ()); - - return enumtype; -} - -/* Build and install a CONST_DECL for one value of the - current enumeration type (one that was begun with start_enum). - Return a tree-list containing the name and its value. - Assignment of sequential values by default is handled here. */ - -tree -build_enumerator (name, value) - tree name, value; -{ - tree decl, result; - /* Change this to zero if we find VALUE is not shareable. */ - int shareable = 1; - - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); - - /* Validate and default VALUE. */ - if (value != NULL_TREE) - { - if (TREE_READONLY_DECL_P (value)) - { - value = decl_constant_value (value); - shareable = 0; - } - - if (TREE_CODE (value) != INTEGER_CST) - { - error ("enumerator value for `%s' not integer constant", - IDENTIFIER_POINTER (name)); - value = NULL_TREE; - } - } - /* The order of things is reversed here so that we - can check for possible sharing of enum values, - to keep that from happening. */ - /* Default based on previous value. */ - if (value == NULL_TREE) - value = enum_next_value; - - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); - - /* Make up for hacks in cp-lex.c. */ - if (value == integer_zero_node) - value = build_int_2 (0, 0); - else if (value == integer_one_node) - value = build_int_2 (1, 0); - else if (TREE_CODE (value) == INTEGER_CST - && (shareable == 0 - || TREE_CODE (TREE_TYPE (value)) == ENUMERAL_TYPE)) - { - value = copy_node (value); - TREE_TYPE (value) = integer_type_node; - } - - result = saveable_tree_cons (name, value, NULL_TREE); - - /* C++ associates enums with global, function, or class declarations. */ - if (current_class_type == NULL_TREE || current_function_decl != NULL_TREE) - { - /* Create a declaration for the enum value name. */ - - decl = build_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - - pushdecl (decl); - GNU_xref_decl (current_function_decl, decl); - } - - if (current_class_type) - { - /* class-local enum declaration */ - decl = build_lang_field_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - TREE_READONLY (decl) = 1; - pushdecl_class_level (decl); - TREE_CHAIN (decl) = current_local_enum; - current_local_enum = decl; - } - - /* Set basis for default for next value. */ - enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value, - integer_one_node, PLUS_EXPR); - if (enum_next_value == integer_one_node) - enum_next_value = copy_node (enum_next_value); - - return result; -} - -tree -grok_enum_decls (type, decl) - tree type, decl; -{ - tree d = current_local_enum; - - if (d == NULL_TREE) - return decl; - - while (1) - { - TREE_TYPE (d) = type; - if (TREE_CHAIN (d) == NULL_TREE) - { - TREE_CHAIN (d) = decl; - break; - } - d = TREE_CHAIN (d); - } - - decl = current_local_enum; - current_local_enum = NULL_TREE; - - return decl; -} - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. - - For C++, we must first check whether that datum makes any sense. - For example, "class A local_a(1,2);" means that variable local_a - is an aggregate of type A, which should have a constructor - applied to it with the argument list [1, 2]. - - @@ There is currently no way to retrieve the storage - @@ allocated to FUNCTION (or all of its parms) if we return - @@ something we had previously. */ - -int -start_function (declspecs, declarator, raises, pre_parsed_p) - tree declarator, declspecs, raises; - int pre_parsed_p; -{ - extern tree EHS_decl; - tree decl1, olddecl; - tree ctype = NULL_TREE; - tree fntype; - tree restype; - extern int have_extern_spec; - extern int used_extern_spec; - int doing_friend = 0; - - if (flag_handle_exceptions && EHS_decl == NULL_TREE) - init_exception_processing_1 (); - - /* Sanity check. */ - my_friendly_assert (TREE_VALUE (void_list_node) == void_type_node, 160); - my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); - - /* Assume, until we see it does. */ - current_function_returns_value = 0; - current_function_returns_null = 0; - warn_about_return_type = 0; - current_extern_inline = 0; - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - current_function_parms_stored = 0; - original_result_rtx = NULL_RTX; - current_function_obstack_index = 0; - current_function_obstack_usage = 0; - - clear_temp_name (); - - /* This should only be done once on the top most decl. */ - if (have_extern_spec && !used_extern_spec) - { - declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); - used_extern_spec = 1; - } - - if (pre_parsed_p) - { - decl1 = declarator; - last_function_parms = DECL_ARGUMENTS (decl1); - last_function_parm_tags = NULL_TREE; - fntype = TREE_TYPE (decl1); - if (TREE_CODE (fntype) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (fntype); - - /* ANSI C++ June 5 1992 WP 11.4.5. A friend function defined in a - class is in the (lexical) scope of the class in which it is - defined. */ - if (!ctype && DECL_FRIEND_P (decl1)) - { - ctype = TREE_TYPE (TREE_CHAIN (decl1)); - - /* CTYPE could be null here if we're dealing with a template; - for example, `inline friend float foo()' inside a template - will have no CTYPE set. */ - if (ctype && TREE_CODE (ctype) != RECORD_TYPE) - ctype = NULL_TREE; - else - doing_friend = 1; - } - - if ( !(DECL_VINDEX (decl1) - && write_virtuals >= 2 - && CLASSTYPE_VTABLE_NEEDS_WRITING (ctype))) - current_extern_inline = TREE_PUBLIC (decl1) && DECL_INLINE (decl1); - - raises = TYPE_RAISES_EXCEPTIONS (fntype); - - /* In a fcn definition, arg types must be complete. */ - require_complete_types_for_parms (last_function_parms); - } - else - { - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, raises); - /* If the declarator is not suitable for a function definition, - cause a syntax error. */ - if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0; - - fntype = TREE_TYPE (decl1); - - restype = TREE_TYPE (fntype); - if (IS_AGGR_TYPE (restype) - && ! CLASSTYPE_GOT_SEMICOLON (restype)) - { - error_with_aggr_type (restype, "semicolon missing after declaration of `%s'"); - shadow_tag (build_tree_list (NULL_TREE, restype)); - CLASSTYPE_GOT_SEMICOLON (restype) = 1; - if (TREE_CODE (fntype) == FUNCTION_TYPE) - fntype = build_function_type (integer_type_node, - TYPE_ARG_TYPES (fntype)); - else - fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)), - integer_type_node, - TYPE_ARG_TYPES (fntype)); - TREE_TYPE (decl1) = fntype; - } - - if (TREE_CODE (fntype) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (fntype); - else if (IDENTIFIER_LENGTH (DECL_NAME (decl1)) == 4 - && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (decl1)), "main") - && DECL_CONTEXT (decl1) == NULL_TREE) - { - /* If this doesn't return integer_type, complain. */ - if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node) - { - warning ("return type for `main' changed to integer type"); - TREE_TYPE (decl1) = fntype = default_function_type; - } - warn_about_return_type = 0; - } - } - - /* Warn if function was previously implicitly declared - (but not if we warned then). */ - if (! warn_implicit - && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) - warning_with_decl (IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)), - "`%s' implicitly declared before its definition"); - - current_function_decl = decl1; - - if (flag_cadillac) - cadillac_start_function (decl1); - else - announce_function (decl1); - - if (TYPE_SIZE (TREE_TYPE (fntype)) == NULL_TREE) - { - if (IS_AGGR_TYPE (TREE_TYPE (fntype))) - error_with_aggr_type (TREE_TYPE (fntype), - "return-type `%s' is an incomplete type"); - else - error ("return-type is an incomplete type"); - - /* Make it return void instead, but don't change the - type of the DECL_RESULT, in case we have a named return value. */ - if (ctype) - TREE_TYPE (decl1) - = build_cplus_method_type (build_type_variant (ctype, - TREE_READONLY (decl1), - TREE_SIDE_EFFECTS (decl1)), - void_type_node, - FUNCTION_ARG_CHAIN (decl1)); - else - TREE_TYPE (decl1) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl1))); - DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, TREE_TYPE (fntype)); - } - - if (warn_about_return_type) - warning ("return-type defaults to `int'"); - - /* Make the init_value nonzero so pushdecl knows this is not tentative. - error_mark_node is replaced below (in poplevel) with the BLOCK. */ - DECL_INITIAL (decl1) = error_mark_node; - - /* Didn't get anything from C. */ - olddecl = NULL_TREE; - - /* This function exists in static storage. - (This does not mean `static' in the C sense!) */ - TREE_STATIC (decl1) = 1; - - /* If this function belongs to an interface, it is public. - If it belongs to someone else's interface, it is also external. - It doesn't matter whether it's inline or not. */ - if (interface_unknown == 0) - { - TREE_PUBLIC (decl1) = 1; - DECL_EXTERNAL (decl1) = (interface_only - || (DECL_INLINE (decl1) - && ! flag_implement_inlines)); - } - else - /* This is a definition, not a reference. - So normally clear DECL_EXTERNAL. - However, `extern inline' acts like a declaration except for - defining how to inline. So set DECL_EXTERNAL in that case. */ - DECL_EXTERNAL (decl1) = current_extern_inline; - - /* Now see if this is the implementation of a function - declared with "C" linkage. */ - if (ctype == NULL_TREE && current_lang_name == lang_name_cplusplus - && !DECL_CONTEXT (decl1)) - { - olddecl = lookup_name_current_level (DECL_NAME (decl1)); - if (olddecl && TREE_CODE (olddecl) != FUNCTION_DECL) - olddecl = NULL_TREE; - if (olddecl && DECL_NAME (decl1) != DECL_NAME (olddecl)) - { - /* Collision between user and internal naming scheme. */ - olddecl = lookup_name_current_level (DECL_ASSEMBLER_NAME (decl1)); - if (olddecl == NULL_TREE) - olddecl = decl1; - } - if (olddecl && olddecl != decl1 - && DECL_NAME (decl1) == DECL_NAME (olddecl)) - { - if (TREE_CODE (olddecl) == FUNCTION_DECL - && decls_match (decl1, olddecl)) - { - olddecl = DECL_MAIN_VARIANT (olddecl); - /* The following copy is needed to handle forcing a function's - linkage to obey the linkage of the original decl. */ - DECL_ASSEMBLER_NAME (decl1) = DECL_ASSEMBLER_NAME (olddecl); - DECL_OVERLOADED (decl1) = DECL_OVERLOADED (olddecl); - if (DECL_INITIAL (olddecl)) - redeclaration_error_message (decl1, olddecl); - if (! duplicate_decls (decl1, olddecl)) - my_friendly_abort (19); - decl1 = olddecl; - } - else - olddecl = NULL_TREE; - } - } - - /* Record the decl so that the function name is defined. - If we already have a decl for this name, and it is a FUNCTION_DECL, - use the old decl. */ - - if (olddecl) - current_function_decl = olddecl; - else if (pre_parsed_p == 0) - { - current_function_decl = pushdecl (decl1); - if (TREE_CODE (current_function_decl) == TREE_LIST) - { - /* @@ revert to modified original declaration. */ - decl1 = DECL_MAIN_VARIANT (decl1); - current_function_decl = decl1; - } - else - { - decl1 = current_function_decl; - DECL_MAIN_VARIANT (decl1) = decl1; - } - fntype = TREE_TYPE (decl1); - } - else - current_function_decl = decl1; - - if (DECL_OVERLOADED (decl1)) - decl1 = push_overloaded_decl (decl1, 1); - - if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)) - { - if (TREE_CODE (fntype) == METHOD_TYPE) - TREE_TYPE (decl1) = fntype - = build_function_type (TREE_TYPE (fntype), - TREE_CHAIN (TYPE_ARG_TYPES (fntype))); - last_function_parms = TREE_CHAIN (last_function_parms); - DECL_ARGUMENTS (decl1) = last_function_parms; - ctype = NULL_TREE; - } - restype = TREE_TYPE (fntype); - - pushlevel (0); - current_binding_level->parm_flag = 1; - - /* Save the parm names or decls from this function's declarator - where store_parm_decls will find them. */ - current_function_parms = last_function_parms; - current_function_parm_tags = last_function_parm_tags; - - GNU_xref_function (decl1, current_function_parms); - - make_function_rtl (decl1); - - if (ctype) - { - pushclass (ctype, 1); - - /* If we're compiling a friend function, neither of the variables - current_class_decl nor current_class_type will have values. */ - if (! doing_friend) - { - /* We know that this was set up by `grokclassfn'. - We do not wait until `store_parm_decls', since evil - parse errors may never get us to that point. Here - we keep the consistency between `current_class_type' - and `current_class_decl'. */ - current_class_decl = last_function_parms; - my_friendly_assert (current_class_decl != NULL_TREE - && TREE_CODE (current_class_decl) == PARM_DECL, 162); - if (TREE_CODE (TREE_TYPE (current_class_decl)) == POINTER_TYPE) - { - tree variant = TREE_TYPE (TREE_TYPE (current_class_decl)); - if (CLASSTYPE_INST_VAR (ctype) == NULL_TREE) - { - /* Can't call build_indirect_ref here, because it has special - logic to return C_C_D given this argument. */ - C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl); - CLASSTYPE_INST_VAR (ctype) = C_C_D; - } - else - { - C_C_D = CLASSTYPE_INST_VAR (ctype); - /* `current_class_decl' is different for every - function we compile. */ - TREE_OPERAND (C_C_D, 0) = current_class_decl; - } - TREE_READONLY (C_C_D) = TYPE_READONLY (variant); - TREE_SIDE_EFFECTS (C_C_D) = TYPE_VOLATILE (variant); - TREE_THIS_VOLATILE (C_C_D) = TYPE_VOLATILE (variant); - } - else - C_C_D = current_class_decl; - } - } - else - { - if (DECL_STATIC_FUNCTION_P (decl1)) - pushclass (DECL_CONTEXT (decl1), 2); - else - push_memoized_context (0, 1); - } - - /* Allocate further tree nodes temporarily during compilation - of this function only. Tiemann moved up here from bottom of fn. */ - temporary_allocation (); - - /* Promote the value to int before returning it. */ - if (C_PROMOTING_INTEGER_TYPE_P (restype)) - { - /* It retains unsignedness if traditional or if it isn't - really getting wider. */ - if (TREE_UNSIGNED (restype) - && (flag_traditional - || TYPE_PRECISION (restype) - == TYPE_PRECISION (integer_type_node))) - restype = unsigned_type_node; - else - restype = integer_type_node; - } - if (DECL_RESULT (decl1) == NULL_TREE) - DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, restype); - - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1))) - { - dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - ctor_label = NULL_TREE; - } - else - { - dtor_label = NULL_TREE; - if (DECL_CONSTRUCTOR_P (decl1)) - ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - } - - /* If this fcn was already referenced via a block-scope `extern' decl - (or an implicit decl), propagate certain information about the usage. */ - if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl1))) - TREE_ADDRESSABLE (decl1) = 1; - - return 1; -} - -/* Store the parameter declarations into the current function declaration. - This is called after parsing the parameter declarations, before - digesting the body of the function. - - Also install to binding contour return value identifier, if any. */ - -void -store_parm_decls () -{ - register tree fndecl = current_function_decl; - register tree parm; - int parms_have_cleanups = 0; - tree eh_decl; - - /* This is either a chain of PARM_DECLs (when a prototype is used). */ - tree specparms = current_function_parms; - - /* This is a list of types declared among parms in a prototype. */ - tree parmtags = current_function_parm_tags; - - /* This is a chain of any other decls that came in among the parm - declarations. If a parm is declared with enum {foo, bar} x; - then CONST_DECLs for foo and bar are put here. */ - tree nonparms = NULL_TREE; - - if (current_binding_level == global_binding_level) - fatal ("parse errors have confused me too much"); - - /* Initialize RTL machinery. */ - init_function_start (fndecl, input_filename, lineno); - - /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ - declare_function_name (); - - /* Create a binding level for the parms. */ - expand_start_bindings (0); - - /* Prepare to catch raises, if appropriate. */ - if (flag_handle_exceptions) - { - /* Get this cleanup to be run last, since it - is a call to `longjmp'. */ - setup_exception_throw_decl (); - eh_decl = current_binding_level->names; - current_binding_level->names = TREE_CHAIN (current_binding_level->names); - } - if (flag_handle_exceptions) - expand_start_try (integer_one_node, 0, 1); - - if (specparms != NULL_TREE) - { - /* This case is when the function was defined with an ANSI prototype. - The parms already have decls, so we need not do anything here - except record them as in effect - and complain if any redundant old-style parm decls were written. */ - - register tree next; - - /* Must clear this because it might contain TYPE_DECLs declared - at class level. */ - storedecls (NULL_TREE); - for (parm = nreverse (specparms); parm; parm = next) - { - next = TREE_CHAIN (parm); - if (TREE_CODE (parm) == PARM_DECL) - { - tree cleanup = maybe_build_cleanup (parm); - if (DECL_NAME (parm) == NULL_TREE) - { -#if 0 - error_with_decl (parm, "parameter name omitted"); -#else - /* for C++, this is not an error. */ - pushdecl (parm); -#endif - } - else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) - error_with_decl (parm, "parameter `%s' declared void"); - else - { - /* Now fill in DECL_REFERENCE_SLOT for any of the parm decls. - A parameter is assumed not to have any side effects. - If this should change for any reason, then this - will have to wrap the bashed reference type in a save_expr. - - Also, if the parameter type is declared to be an X - and there is an X(X&) constructor, we cannot lay it - into the stack (any more), so we make this parameter - look like it is really of reference type. Functions - which pass parameters to this function will know to - create a temporary in their frame, and pass a reference - to that. */ - - if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE - && TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm)))) - SET_DECL_REFERENCE_SLOT (parm, convert_from_reference (parm)); - - pushdecl (parm); - } - if (cleanup) - { - expand_decl (parm); - expand_decl_cleanup (parm, cleanup); - parms_have_cleanups = 1; - } - } - else - { - /* If we find an enum constant or a type tag, - put it aside for the moment. */ - TREE_CHAIN (parm) = NULL_TREE; - nonparms = chainon (nonparms, parm); - } - } - - /* Get the decls in their original chain order - and record in the function. This is all and only the - PARM_DECLs that were pushed into scope by the loop above. */ - DECL_ARGUMENTS (fndecl) = getdecls (); - - storetags (chainon (parmtags, gettags ())); - } - else - DECL_ARGUMENTS (fndecl) = NULL_TREE; - - /* Now store the final chain of decls for the arguments - as the decl-chain of the current lexical scope. - Put the enumerators in as well, at the front so that - DECL_ARGUMENTS is not modified. */ - - storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); - - /* Initialize the RTL code for the function. */ - DECL_SAVED_INSNS (fndecl) = NULL_RTX; - expand_function_start (fndecl, parms_have_cleanups); - - if (flag_handle_exceptions) - { - /* Make the throw decl visible at this level, just - not in the way of the parameters. */ - pushdecl (eh_decl); - expand_decl_init (eh_decl); - } - - /* Create a binding contour which can be used to catch - cleanup-generated temporaries. Also, if the return value needs or - has initialization, deal with that now. */ - if (parms_have_cleanups) - { - pushlevel (0); - expand_start_bindings (0); - } - - current_function_parms_stored = 1; - - if (flag_gc) - { - maybe_gc_cleanup = build_tree_list (NULL_TREE, error_mark_node); - expand_decl_cleanup (NULL_TREE, maybe_gc_cleanup); - } - - /* If this function is `main', emit a call to `__main' - to run global initializers, etc. */ - if (DECL_NAME (fndecl) - && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4 - && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0 - && DECL_CONTEXT (fndecl) == NULL_TREE) - { - expand_main_function (); - - if (flag_gc) - expand_expr (build_function_call (lookup_name (get_identifier ("__gc_main"), 0), NULL_TREE), - 0, VOIDmode, 0); - - if (flag_dossier) - output_builtin_tdesc_entries (); - } -} - -/* Bind a name and initialization to the return value of - the current function. */ -void -store_return_init (return_id, init) - tree return_id, init; -{ - tree decl = DECL_RESULT (current_function_decl); - - if (pedantic) - /* Give this error as many times as there are occurrences, - so that users can use Emacs compilation buffers to find - and fix all such places. */ - error ("ANSI C++ does not permit named return values"); - - if (return_id != NULL_TREE) - { - if (DECL_NAME (decl) == NULL_TREE) - { - DECL_NAME (decl) = return_id; - DECL_ASSEMBLER_NAME (decl) = return_id; - } - else - error ("return identifier `%s' already in place", - IDENTIFIER_POINTER (DECL_NAME (decl))); - } - - /* Can't let this happen for constructors. */ - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - error ("can't redefine default return value for constructors"); - return; - } - - /* If we have a named return value, put that in our scope as well. */ - if (DECL_NAME (decl) != NULL_TREE) - { - /* If this named return value comes in a register, - put it in a pseudo-register. */ - if (DECL_REGISTER (decl)) - { - original_result_rtx = DECL_RTL (decl); - DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); - } - - /* Let `finish_decl' know that this initializer is ok. */ - DECL_INITIAL (decl) = init; - pushdecl (decl); - finish_decl (decl, init, 0, 0); - } -} - -/* Generate code for default X(X&) constructor. */ -static void -build_default_constructor (fndecl) - tree fndecl; -{ - int i = CLASSTYPE_N_BASECLASSES (current_class_type); - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); - tree fields = TYPE_FIELDS (current_class_type); - tree binfos = TYPE_BINFO_BASETYPES (current_class_type); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - parm = TREE_CHAIN (parm); - parm = DECL_REFERENCE_SLOT (parm); - - while (--i >= 0) - { - tree basetype = TREE_VEC_ELT (binfos, i); - if (TYPE_GETS_INIT_REF (basetype)) - { - tree name = TYPE_NAME (basetype); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - current_base_init_list = tree_cons (name, parm, current_base_init_list); - } - } - for (; fields; fields = TREE_CHAIN (fields)) - { - tree name, init; - if (TREE_STATIC (fields)) - continue; - if (TREE_CODE (fields) != FIELD_DECL) - continue; - if (DECL_NAME (fields)) - { - if (VFIELD_NAME_P (DECL_NAME (fields))) - continue; - if (VBASE_NAME_P (DECL_NAME (fields))) - continue; - - /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) - continue; - } - - init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); - - if (TREE_ANON_UNION_ELEM (fields)) - name = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); - else - { - name = DECL_NAME (fields); - init = build_tree_list (NULL_TREE, init); - } - - current_member_init_list - = tree_cons (name, init, current_member_init_list); - } -} - - -/* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage - for the function definition. - - This is called after parsing the body of the function definition. - LINENO is the current line number. - - C++: CALL_POPLEVEL is non-zero if an extra call to poplevel - (and expand_end_bindings) must be made to take care of the binding - contour for the base initializers. This is only relevant for - constructors. */ - -void -finish_function (lineno, call_poplevel) - int lineno; - int call_poplevel; -{ - register tree fndecl = current_function_decl; - tree fntype, ctype = NULL_TREE; - rtx head, last_parm_insn, mark; - extern int sets_exception_throw_decl; - /* Label to use if this function is supposed to return a value. */ - tree no_return_label = NULL_TREE; - - /* When we get some parse errors, we can end up without a - current_function_decl, so cope. */ - if (fndecl == NULL_TREE) - return; - - fntype = TREE_TYPE (fndecl); - -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ - - /* This happens on strange parse errors. */ - if (! current_function_parms_stored) - { - call_poplevel = 0; - store_parm_decls (); - } - - if (write_symbols != NO_DEBUG && TREE_CODE (fntype) != METHOD_TYPE) - { - tree ttype = target_type (fntype); - tree parmdecl; - - if (IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - - for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl)) - { - ttype = target_type (TREE_TYPE (parmdecl)); - if (IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - } - } - - /* Clean house because we will need to reorder insns here. */ - do_pending_stack_adjust (); - - if (dtor_label) - { - tree binfo = TYPE_BINFO (current_class_type); - tree cond = integer_one_node; - tree exprstmt, vfields; - tree in_charge_node = lookup_name (in_charge_identifier, 0); - tree virtual_size; - int ok_to_optimize_dtor = 0; - - if (current_function_assigns_this) - cond = build (NE_EXPR, integer_type_node, - current_class_decl, integer_zero_node); - else - { - int n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); - - /* If this destructor is empty, then we don't need to check - whether `this' is NULL in some cases. */ - mark = get_last_insn (); - last_parm_insn = get_first_nonparm_insn (); - - if ((flag_this_is_variable & 1) == 0) - ok_to_optimize_dtor = 1; - else if (mark == last_parm_insn) - ok_to_optimize_dtor - = (n_baseclasses == 0 - || (n_baseclasses == 1 - && TYPE_HAS_DESTRUCTOR (TYPE_BINFO_BASETYPE (current_class_type, 0)))); - } - - /* These initializations might go inline. Protect - the binding level of the parms. */ - pushlevel (0); - - if (current_function_assigns_this) - { - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } - - /* Generate the code to call destructor on base class. - If this destructor belongs to a class with virtual - functions, then set the virtual function table - pointer to represent the type of our base class. */ - - /* This side-effect makes call to `build_delete' generate the - code we have to have at the end of this destructor. */ - TYPE_HAS_DESTRUCTOR (current_class_type) = 0; - - /* These are two cases where we cannot delegate deletion. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type) - || TREE_GETS_DELETE (current_class_type)) - exprstmt = build_delete (current_class_type, C_C_D, integer_zero_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); - else - exprstmt = build_delete (current_class_type, C_C_D, in_charge_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); - - /* If we did not assign to this, then `this' is non-zero at - the end of a destructor. As a special optimization, don't - emit test if this is an empty destructor. If it does nothing, - it does nothing. If it calls a base destructor, the base - destructor will perform the test. */ - - if (exprstmt != error_mark_node - && (TREE_CODE (exprstmt) != NOP_EXPR - || TREE_OPERAND (exprstmt, 0) != integer_zero_node - || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))) - { - expand_label (dtor_label); - if (cond != integer_one_node) - expand_start_cond (cond, 0); - if (exprstmt != void_zero_node) - /* Don't call `expand_expr_stmt' if we're not going to do - anything, since -Wall will give a diagnostic. */ - expand_expr_stmt (exprstmt); - - /* Run destructor on all virtual baseclasses. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - { - tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); - expand_start_cond (build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_two_node), 0); - while (vbases) - { - if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases))) - { - tree ptr = convert_pointer_to_vbase (vbases, current_class_decl); - expand_expr_stmt (build_delete (TYPE_POINTER_TO (BINFO_TYPE (vbases)), - ptr, integer_zero_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_HAS_IN_CHARGE, 0, 0)); - } - vbases = TREE_CHAIN (vbases); - } - expand_end_cond (); - } - - do_pending_stack_adjust (); - if (cond != integer_one_node) - expand_end_cond (); - } - - TYPE_HAS_DESTRUCTOR (current_class_type) = 1; - - virtual_size = c_sizeof (current_class_type); - - /* At the end, call delete if that's what's requested. */ - if (TREE_GETS_DELETE (current_class_type)) - /* This NOP_EXPR means we are in a static call context. */ - exprstmt = - build_method_call - (build1 (NOP_EXPR, - TYPE_POINTER_TO (current_class_type), error_mark_node), - ansi_opname[(int) DELETE_EXPR], - tree_cons (NULL_TREE, current_class_decl, - build_tree_list (NULL_TREE, virtual_size)), - NULL_TREE, LOOKUP_NORMAL); - else if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - exprstmt = build_x_delete (ptr_type_node, current_class_decl, 0, - virtual_size); - else - exprstmt = NULL_TREE; - - if (exprstmt) - { - cond = build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_one_node); - expand_start_cond (cond, 0); - expand_expr_stmt (exprstmt); - expand_end_cond (); - } - - /* End of destructor. */ - poplevel (2, 0, 0); - - /* Back to the top of destructor. */ - /* Dont execute destructor code if `this' is NULL. */ - mark = get_last_insn (); - last_parm_insn = get_first_nonparm_insn (); - if (last_parm_insn == NULL_RTX) - last_parm_insn = mark; - else - last_parm_insn = previous_insn (last_parm_insn); - - /* Make all virtual function table pointers point to CURRENT_CLASS_TYPE's - virtual function tables. */ - if (CLASSTYPE_VFIELDS (current_class_type)) - { - for (vfields = CLASSTYPE_VFIELDS (current_class_type); - TREE_CHAIN (vfields); - vfields = TREE_CHAIN (vfields)) - { - tree vf_decl = current_class_decl; - /* ??? This may need to be a loop if there are multiple - levels of replication. */ - if (VF_BINFO_VALUE (vfields)) - vf_decl = convert_pointer_to (VF_BINFO_VALUE (vfields), vf_decl); - if (vf_decl != error_mark_node) - { - /* It is one of these two, or a combination... */ - /* basically speaking, I want to get down to the right - VF_BASETYPE_VALUE (vfields) */ -#if 0 - if (VF_NORMAL_VALUE (vfields) != VF_DERIVED_VALUE (vfields)) - warning ("hum, wonder if I am doing the right thing"); -#endif - expand_expr_stmt (build_virtual_init (binfo, - get_binfo (VF_BASETYPE_VALUE (vfields), - get_binfo (VF_DERIVED_VALUE (vfields), binfo, 0), 0), - vf_decl)); - } - } - expand_expr_stmt (build_virtual_init (binfo, binfo, - current_class_decl)); - } - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - expand_expr_stmt (build_vbase_vtables_init (binfo, binfo, - C_C_D, current_class_decl, 0)); - if (! ok_to_optimize_dtor) - { - cond = build_binary_op (NE_EXPR, - current_class_decl, integer_zero_node, 1); - expand_start_cond (cond, 0); - } - if (mark != get_last_insn ()) - reorder_insns (next_insn (mark), get_last_insn (), last_parm_insn); - if (! ok_to_optimize_dtor) - expand_end_cond (); - } - else if (current_function_assigns_this) - { - /* Does not need to call emit_base_init, because - that is done (if needed) just after assignment to this - is seen. */ - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - expand_label (ctor_label); - ctor_label = NULL_TREE; - - if (call_poplevel) - { - tree decls = getdecls (); - if (flag_handle_exceptions == 2) - deactivate_exception_cleanups (); - expand_end_bindings (decls, decls != NULL_TREE, 0); - poplevel (decls != NULL_TREE, 0, 0); - } - c_expand_return (current_class_decl); - } - else if (TYPE_MAIN_VARIANT (TREE_TYPE ( - DECL_RESULT (current_function_decl))) != void_type_node - && return_label != NULL_RTX) - no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - base_init_insns = NULL_RTX; - } - else if (DECL_CONSTRUCTOR_P (fndecl)) - { - tree allocated_this; - tree cond, thenclause; - /* Allow constructor for a type to get a new instance of the object - using `build_new'. */ - tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; - - DECL_RETURNS_FIRST_ARG (fndecl) = 1; - - if (flag_this_is_variable > 0) - { - cond = build_binary_op (EQ_EXPR, - current_class_decl, integer_zero_node, 1); - thenclause = build_modify_expr (current_class_decl, NOP_EXPR, - build_new (NULL_TREE, current_class_type, void_type_node, 0)); - if (flag_handle_exceptions == 2) - { - tree cleanup, cleanup_deallocate; - tree virtual_size; - - /* This is the size of the virtual object pointed to by - allocated_this. In this case, it is simple. */ - virtual_size = c_sizeof (current_class_type); - - allocated_this = build_decl (VAR_DECL, NULL_TREE, ptr_type_node); - DECL_REGISTER (allocated_this) = 1; - DECL_INITIAL (allocated_this) = error_mark_node; - expand_decl (allocated_this); - expand_decl_init (allocated_this); - /* How we cleanup `this' if an exception was raised before - we are ready to bail out. */ - cleanup = TREE_GETS_DELETE (current_class_type) - ? build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, allocated_this, virtual_size, NULL_TREE) - /* The size of allocated_this is wrong, and hence the - second argument to operator delete will be wrong. */ - : build_delete (TREE_TYPE (allocated_this), allocated_this, - integer_three_node, - LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, 1, 0); - cleanup_deallocate - = build_modify_expr (current_class_decl, NOP_EXPR, integer_zero_node); - cleanup = tree_cons (NULL_TREE, cleanup, - build_tree_list (NULL_TREE, cleanup_deallocate)); - - expand_decl_cleanup (allocated_this, - build (COND_EXPR, integer_type_node, - build (NE_EXPR, integer_type_node, - allocated_this, integer_zero_node), - build_compound_expr (cleanup), - integer_zero_node)); - } - } - else if (TREE_GETS_NEW (current_class_type)) - /* Just check visibility here. */ - build_method_call (build1 (NOP_EXPR, TYPE_POINTER_TO (current_class_type), error_mark_node), - ansi_opname[(int) NEW_EXPR], - build_tree_list (NULL_TREE, integer_zero_node), - NULL_TREE, LOOKUP_NORMAL); - - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = abstract_virtuals; - - /* must keep the first insn safe. */ - head = get_insns (); - - /* this note will come up to the top with us. */ - mark = get_last_insn (); - - if (flag_this_is_variable > 0) - { - expand_start_cond (cond, 0); - expand_expr_stmt (thenclause); - if (flag_handle_exceptions == 2) - expand_assignment (allocated_this, current_class_decl, 0, 0); - expand_end_cond (); - } - - if (DECL_NAME (fndecl) == NULL_TREE - && TREE_CHAIN (DECL_ARGUMENTS (fndecl)) != NULL_TREE) - build_default_constructor (fndecl); - - /* Emit insns from `emit_base_init' which sets up virtual - function table pointer(s). */ - emit_insns (base_init_insns); - base_init_insns = NULL_RTX; - - /* This is where the body of the constructor begins. - If there were no insns in this function body, then the - last_parm_insn is also the last insn. - - If optimization is enabled, last_parm_insn may move, so - we don't hold on to it (across emit_base_init). */ - last_parm_insn = get_first_nonparm_insn (); - if (last_parm_insn == NULL_RTX) last_parm_insn = mark; - else last_parm_insn = previous_insn (last_parm_insn); - - if (mark != get_last_insn ()) - reorder_insns (next_insn (mark), get_last_insn (), last_parm_insn); - - /* This is where the body of the constructor ends. */ - expand_label (ctor_label); - ctor_label = NULL_TREE; - if (flag_handle_exceptions == 2) - { - expand_assignment (allocated_this, integer_zero_node, 0, 0); - if (call_poplevel) - deactivate_exception_cleanups (); - } - - pop_implicit_try_blocks (NULL_TREE); - - if (call_poplevel) - { - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 1, 0); - } - - c_expand_return (current_class_decl); - - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } - else if (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4 - && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") - && DECL_CONTEXT (fndecl) == NULL_TREE) - { - /* Make it so that `main' always returns 0 by default. */ -#ifdef VMS - c_expand_return (integer_one_node); -#else - c_expand_return (integer_zero_node); -#endif - } - else if (return_label != NULL_RTX - && current_function_return_value == NULL_TREE - && ! DECL_NAME (DECL_RESULT (current_function_decl))) - no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - if (flag_gc) - expand_gc_prologue_and_epilogue (); - - /* That's the end of the vtable decl's life. Need to mark it such - if doing stupid register allocation. - - Note that current_vtable_decl is really an INDIRECT_REF - on top of a VAR_DECL here. */ - if (obey_regdecls && current_vtable_decl) - use_variable (DECL_RTL (TREE_OPERAND (current_vtable_decl, 0))); - - /* If this function is supposed to return a value, ensure that - we do not fall into the cleanups by mistake. The end of our - function will look like this: - - user code (may have return stmt somewhere) - goto no_return_label - cleanup_label: - cleanups - goto return_label - no_return_label: - NOTE_INSN_FUNCTION_END - return_label: - things for return - - If the user omits a return stmt in the USER CODE section, we - will have a control path which reaches NOTE_INSN_FUNCTION_END. - Otherwise, we won't. */ - if (no_return_label) - { - DECL_CONTEXT (no_return_label) = fndecl; - DECL_INITIAL (no_return_label) = error_mark_node; - DECL_SOURCE_FILE (no_return_label) = input_filename; - DECL_SOURCE_LINE (no_return_label) = lineno; - expand_goto (no_return_label); - } - - if (cleanup_label) - { - /* remove the binding contour which is used - to catch cleanup-generated temporaries. */ - expand_end_bindings (0, 0, 0); - poplevel (0, 0, 0); - } - - if (cleanup_label) - /* Emit label at beginning of cleanup code for parameters. */ - emit_label (cleanup_label); - -#if 1 - /* Cheap hack to get better code from GNU C++. Remove when cse is fixed. */ - if (exception_throw_decl && sets_exception_throw_decl == 0) - expand_assignment (exception_throw_decl, integer_zero_node, 0, 0); -#endif - - if (flag_handle_exceptions) - { - expand_end_try (); - expand_start_except (0, 0); - expand_end_except (); - } - expand_end_bindings (0, 0, 0); - - /* Get return value into register if that's where it's supposed to be. */ - if (original_result_rtx) - fixup_result_decl (DECL_RESULT (fndecl), original_result_rtx); - - /* Finish building code that will trigger warnings if users forget - to make their functions return values. */ - if (no_return_label || cleanup_label) - emit_jump (return_label); - if (no_return_label) - { - /* We don't need to call `expand_*_return' here because we - don't need any cleanups here--this path of code is only - for error checking purposes. */ - expand_label (no_return_label); - } - - /* reset scope for C++: if we were in the scope of a class, - then when we finish this function, we are not longer so. - This cannot be done until we know for sure that no more - class members will ever be referenced in this function - (i.e., calls to destructors). */ - if (current_class_name) - { - ctype = current_class_type; - popclass (1); - } - else - pop_memoized_context (1); - - /* Forget about all overloaded functions defined in - this scope which go away. */ - while (overloads_to_forget) - { - IDENTIFIER_GLOBAL_VALUE (TREE_PURPOSE (overloads_to_forget)) - = TREE_VALUE (overloads_to_forget); - overloads_to_forget = TREE_CHAIN (overloads_to_forget); - } - - /* Generate rtl for function exit. */ - expand_function_end (input_filename, lineno); - - /* This must come after expand_function_end because cleanups might - have declarations (from inline functions) that need to go into - this function's blocks. */ - if (current_binding_level->parm_flag != 1) - my_friendly_abort (122); - poplevel (1, 0, 1); - - /* Must mark the RESULT_DECL as being in this function. */ - DECL_CONTEXT (DECL_RESULT (fndecl)) = DECL_INITIAL (fndecl); - - /* Obey `register' declarations if `setjmp' is called in this fn. */ - if (flag_traditional && current_function_calls_setjmp) - setjmp_protect (DECL_INITIAL (fndecl)); - - /* Set the BLOCK_SUPERCONTEXT of the outermost function scope to point - to the FUNCTION_DECL node itself. */ - BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - - /* ??? Compensate for Sun brain damage in dealing with data segments - of PIC code. */ - if (flag_pic - && (DECL_CONSTRUCTOR_P (fndecl) - || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) - && CLASSTYPE_NEEDS_VIRTUAL_REINIT (TYPE_METHOD_BASETYPE (fntype))) - DECL_INLINE (fndecl) = 0; - - if (DECL_EXTERNAL (fndecl) - /* This function is just along for the ride. If we can make - it inline, that's great. Otherwise, just punt it. */ - && (DECL_INLINE (fndecl) == 0 - || flag_no_inline - || function_cannot_inline_p (fndecl))) - { - extern int rtl_dump_and_exit; - int old_rtl_dump_and_exit = rtl_dump_and_exit; - int inline_spec = DECL_INLINE (fndecl); - - /* This throws away the code for FNDECL. */ - rtl_dump_and_exit = 1; - /* This throws away the memory of the code for FNDECL. */ - if (flag_no_inline) - DECL_INLINE (fndecl) = 0; - rest_of_compilation (fndecl); - rtl_dump_and_exit = old_rtl_dump_and_exit; - DECL_INLINE (fndecl) = inline_spec; - } - else - { - /* Run the optimizers and output the assembler code for this function. */ - rest_of_compilation (fndecl); - } - - if (ctype && TREE_ASM_WRITTEN (fndecl)) - note_debug_info_needed (ctype); - - current_function_returns_null |= can_reach_end; - - /* Since we don't normally go through c_expand_return for constructors, - this normally gets the wrong value. - Also, named return values have their return codes emitted after - NOTE_INSN_FUNCTION_END, confusing jump.c. */ - if (DECL_CONSTRUCTOR_P (fndecl) - || DECL_NAME (DECL_RESULT (fndecl)) != NULL_TREE) - current_function_returns_null = 0; - - if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) - warning ("`volatile' function does return"); - else if (warn_return_type && current_function_returns_null - && TYPE_MAIN_VARIANT (TREE_TYPE (fntype)) != void_type_node) - { - /* If this function returns non-void and control can drop through, - complain. */ - pedwarn ("control reaches end of non-void function"); - } - /* With just -W, complain only if function returns both with - and without a value. */ - else if (extra_warnings - && current_function_returns_value && current_function_returns_null) - warning ("this function may return with or without a value"); - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently - until we start another function. */ - permanent_allocation (); - - if (flag_cadillac) - cadillac_finish_function (fndecl); - - if (DECL_SAVED_INSNS (fndecl) == NULL_RTX) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - DECL_INITIAL (fndecl) = error_mark_node; - if (! DECL_CONSTRUCTOR_P (fndecl) - || !TYPE_USES_VIRTUAL_BASECLASSES (TYPE_METHOD_BASETYPE (fntype))) - DECL_ARGUMENTS (fndecl) = NULL_TREE; - } - - /* Let the error reporting routines know that we're outside a function. */ - current_function_decl = NULL_TREE; - named_label_uses = NULL_TREE; - clear_anon_parm_name (); -} - -/* Create the FUNCTION_DECL for a function definition. - LINE1 is the line number that the definition absolutely begins on. - LINE2 is the line number that the name of the function appears on. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns a FUNCTION_DECL on success. - - If the DECLARATOR is not suitable for a function (it defines a datum - instead), we return 0, which tells yyparse to report a parse error. - - May return void_type_node indicating that this method is actually - a friend. See grokfield for more details. - - Came here with a `.pushlevel' . - - DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING - CHANGES TO CODE IN `grokfield'. */ -tree -start_method (declspecs, declarator, raises) - tree declarator, declspecs, raises; -{ - tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, raises); - - /* Something too ugly to handle. */ - if (fndecl == NULL_TREE) - return NULL_TREE; - - /* Pass friends other than inline friend functions back. */ - if (TYPE_MAIN_VARIANT (fndecl) == void_type_node) - return fndecl; - - if (TREE_CODE (fndecl) != FUNCTION_DECL) - /* Not a function, tell parser to report parse error. */ - return NULL_TREE; - - if (DECL_IN_AGGR_P (fndecl)) - { - if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type) - { - if (DECL_CONTEXT (fndecl)) - error_with_decl (fndecl, "`%s' is already defined in class %s", - TYPE_NAME_STRING (DECL_CONTEXT (fndecl))); - } - return void_type_node; - } - - /* If we're expanding a template, a function must be explicitly declared - inline if we're to compile it now. If it isn't, we have to wait to see - whether it's needed, and whether an override exists. */ - if (flag_default_inline && !processing_template_defn) - DECL_INLINE (fndecl) = 1; - - /* We read in the parameters on the maybepermanent_obstack, - but we won't be getting back to them until after we - may have clobbered them. So the call to preserve_data - will keep them safe. */ - preserve_data (); - - if (! DECL_FRIEND_P (fndecl)) - { - if (DECL_CHAIN (fndecl) != NULL_TREE) - { - /* Need a fresh node here so that we don't get circularity - when we link these together. If FNDECL was a friend, then - `pushdecl' does the right thing, which is nothing wrt its - current value of DECL_CHAIN. */ - fndecl = copy_node (fndecl); - } - if (TREE_CHAIN (fndecl)) - { - fndecl = copy_node (fndecl); - TREE_CHAIN (fndecl) = NULL_TREE; - } - - if (DECL_CONSTRUCTOR_P (fndecl)) - grok_ctor_properties (current_class_type, fndecl); - else if (IDENTIFIER_OPNAME_P (DECL_NAME (fndecl))) - grok_op_properties (fndecl, DECL_VIRTUAL_P (fndecl)); - } - - finish_decl (fndecl, NULL_TREE, NULL_TREE, 0); - - /* Make a place for the parms */ - pushlevel (0); - current_binding_level->parm_flag = 1; - - DECL_IN_AGGR_P (fndecl) = 1; - return fndecl; -} - -/* Go through the motions of finishing a function definition. - We don't compile this method until after the whole class has - been processed. - - FINISH_METHOD must return something that looks as though it - came from GROKFIELD (since we are defining a method, after all). - - This is called after parsing the body of the function definition. - STMTS is the chain of statements that makes up the function body. - - DECL is the ..._DECL that `start_method' provided. */ - -tree -finish_method (decl) - tree decl; -{ - register tree fndecl = decl; - tree old_initial; - tree context = DECL_CONTEXT (fndecl); - - register tree link; - - if (TYPE_MAIN_VARIANT (decl) == void_type_node) - return decl; - -#ifdef DEBUG_CP_BINDING_LEVELS - indent_to (stderr, debug_bindings_indentation); - fprintf (stderr, "finish_method"); - debug_bindings_indentation += 4; -#endif - - old_initial = DECL_INITIAL (fndecl); - - /* Undo the level for the parms (from start_method). - This is like poplevel, but it causes nothing to be - saved. Saving information here confuses symbol-table - output routines. Besides, this information will - be correctly output when this method is actually - compiled. */ - - /* Clear out the meanings of the local variables of this level; - also record in each decl which block it belongs to. */ - - for (link = current_binding_level->names; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != NULL_TREE) - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0; - my_friendly_assert (TREE_CODE (link) != FUNCTION_DECL, 163); - DECL_CONTEXT (link) = NULL_TREE; - } - - /* Restore all name-meanings of the outer levels - that were shadowed by this level. */ - - for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->class_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->type_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - - GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, - (HOST_WIDE_INT) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep, - current_binding_level->tag_transparent); - - pop_binding_level (); - - DECL_INITIAL (fndecl) = old_initial; -#if 0 - /* tiemann would like this, but is causes String.cc to not compile. */ - if (DECL_FRIEND_P (fndecl) || DECL_CONTEXT (fndecl) != current_class_type) -#else - if (DECL_FRIEND_P (fndecl)) -#endif - { - CLASSTYPE_INLINE_FRIENDS (current_class_type) - = tree_cons (NULL_TREE, fndecl, CLASSTYPE_INLINE_FRIENDS (current_class_type)); - decl = void_type_node; - } -#if 0 - /* Work in progress, 9/17/92. */ - else if (context != current_class_type - && TREE_CHAIN (context) != NULL_TREE - && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) - { - /* Don't allow them to declare a function like this: - class A { - public: - class B { - public: - int f(); - }; - int B::f() {} - }; - - Note we can get in here if it's a friend (in which case we'll - avoid lots of nasty cruft), or it's a destructor. Compensate. - */ - tree tmp = DECL_ARGUMENTS (TREE_CHAIN (context)); - if (tmp - && TREE_CODE (tmp) == IDENTIFIER_NODE - && TREE_CHAIN (IDENTIFIER_GLOBAL_VALUE (tmp)) - && TREE_CODE (TREE_CHAIN (IDENTIFIER_GLOBAL_VALUE (tmp))) == TYPE_DECL) - { - error_with_decl (decl, - "qualified name used in declaration of `%s'"); - /* Make this node virtually unusable in the end. */ - TREE_CHAIN (decl) = NULL_TREE; - } - } -#endif - -#ifdef DEBUG_CP_BINDING_LEVELS - debug_bindings_indentation -= 4; -#endif - - return decl; -} - -/* Called when a new struct TYPE is defined. - If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ - -void -hack_incomplete_structures (type) - tree type; -{ - tree decl; - - if (current_binding_level->n_incomplete == 0) - return; - - if (!type) /* Don't do this for class templates. */ - return; - - for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl)) - if (TREE_TYPE (decl) == type - || (TREE_TYPE (decl) - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type)) - { - if (TREE_CODE (decl) == TYPE_DECL) - layout_type (TREE_TYPE (decl)); - else - { - int toplevel = global_binding_level == current_binding_level; - if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type) - layout_type (TREE_TYPE (decl)); - layout_decl (decl, 0); - rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); - if (! toplevel) - { - expand_decl (decl); - expand_decl_cleanup (decl, maybe_build_cleanup (decl)); - expand_decl_init (decl); - } - } - my_friendly_assert (current_binding_level->n_incomplete > 0, 164); - --current_binding_level->n_incomplete; - } -} - -/* Nonzero if presently building a cleanup. Needed because - SAVE_EXPRs are not the right things to use inside of cleanups. - They are only ever evaluated once, where the cleanup - might be evaluated several times. In this case, a later evaluation - of the cleanup might fill in the SAVE_EXPR_RTL, and it will - not be valid for an earlier cleanup. */ - -int building_cleanup; - -/* If DECL is of a type which needs a cleanup, build that cleanup here. - We don't build cleanups if just going for syntax checking, since - fixup_cleanups does not know how to not handle them. - - Don't build these on the momentary obstack; they must live - the life of the binding contour. */ -tree -maybe_build_cleanup (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; - tree rval; - int old_building_cleanup = building_cleanup; - building_cleanup = 1; - - if (TREE_CODE (decl) != PARM_DECL) - temp = suspend_momentary (); - - if (TREE_CODE (type) == ARRAY_TYPE) - rval = decl; - else - { - mark_addressable (decl); - rval = build_unary_op (ADDR_EXPR, decl, 0); - } - - /* Optimize for space over speed here. */ - if (! TYPE_USES_VIRTUAL_BASECLASSES (type) - || flag_expensive_optimizations) - flags |= LOOKUP_NONVIRTUAL; - - /* Use TYPE_MAIN_VARIANT so we don't get a warning about - calling delete on a `const' variable. */ - if (TYPE_READONLY (TREE_TYPE (TREE_TYPE (rval)))) - rval = build1 (NOP_EXPR, TYPE_POINTER_TO (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (rval)))), rval); - - rval = build_delete (TREE_TYPE (rval), rval, integer_two_node, flags, 0, 0); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type) - && ! TYPE_HAS_DESTRUCTOR (type)) - rval = build_compound_expr (tree_cons (NULL_TREE, rval, - build_tree_list (NULL_TREE, build_vbase_delete (type, decl)))); - - current_binding_level->have_cleanups = 1; - current_binding_level->more_exceptions_ok = 0; - - if (TREE_CODE (decl) != PARM_DECL) - resume_momentary (temp); - - building_cleanup = old_building_cleanup; - - return rval; - } - return 0; -} - -/* Expand a C++ expression at the statement level. - This is needed to ferret out nodes which have UNKNOWN_TYPE. - The C++ type checker should get all of these out when - expressions are combined with other, type-providing, expressions, - leaving only orphan expressions, such as: - - &class::bar; / / takes its address, but does nothing with it. - - */ -void -cplus_expand_expr_stmt (exp) - tree exp; -{ - if (TREE_TYPE (exp) == unknown_type_node) - { - if (TREE_CODE (exp) == ADDR_EXPR || TREE_CODE (exp) == TREE_LIST) - error ("address of overloaded function with no contextual type information"); - else if (TREE_CODE (exp) == COMPONENT_REF) - warning ("useless reference to a member function name, did you forget the ()?"); - } - else - { - int remove_implicit_immediately = 0; - - if (TREE_CODE (exp) == FUNCTION_DECL) - { - warning_with_decl (exp, "reference, not call, to function `%s'"); - warning ("at this point in file"); - } - if (TREE_RAISES (exp)) - { - my_friendly_assert (flag_handle_exceptions, 165); - if (flag_handle_exceptions == 2) - { - if (! current_binding_level->more_exceptions_ok) - { - extern struct nesting *nesting_stack, *block_stack; - - remove_implicit_immediately - = (nesting_stack != block_stack); - cplus_expand_start_try (1); - } - current_binding_level->have_exceptions = 1; - } - } - - expand_expr_stmt (break_out_cleanups (exp)); - - if (remove_implicit_immediately) - pop_implicit_try_blocks (NULL_TREE); - } - - /* Clean up any pending cleanups. This happens when a function call - returns a cleanup-needing value that nobody uses. */ - expand_cleanups_to (NULL_TREE); -} - -/* When a stmt has been parsed, this function is called. - - Currently, this function only does something within a - constructor's scope: if a stmt has just assigned to this, - and we are in a derived class, we call `emit_base_init'. */ - -void -finish_stmt () -{ - extern struct nesting *cond_stack, *loop_stack, *case_stack; - - - if (current_function_assigns_this - || ! current_function_just_assigned_this) - return; - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Constructors must wait until we are out of control - zones before calling base constructors. */ - if (cond_stack || loop_stack || case_stack) - return; - emit_insns (base_init_insns); - check_base_init (current_class_type); - } - current_function_assigns_this = 1; - - if (flag_cadillac) - cadillac_finish_stmt (); -} - -void -pop_implicit_try_blocks (decl) - tree decl; -{ - if (decl) - { - my_friendly_assert (current_binding_level->parm_flag == 3, 166); - current_binding_level->names = TREE_CHAIN (decl); - } - - while (current_binding_level->parm_flag == 3) - { - tree name = get_identifier ("(compiler error)"); - tree orig_ex_type = current_exception_type; - tree orig_ex_decl = current_exception_decl; - tree orig_ex_obj = current_exception_object; - tree decl = cplus_expand_end_try (2); - - /* @@ It would be nice to make all these point - to exactly the same handler. */ - /* Start hidden EXCEPT. */ - cplus_expand_start_except (name, decl); - /* reraise ALL. */ - cplus_expand_reraise (NULL_TREE); - current_exception_type = orig_ex_type; - current_exception_decl = orig_ex_decl; - current_exception_object = orig_ex_obj; - /* This will reraise for us. */ - cplus_expand_end_except (error_mark_node); - } - - if (decl) - { - TREE_CHAIN (decl) = current_binding_level->names; - current_binding_level->names = decl; - } -} - -/* Push a cleanup onto the current binding contour that will cause - ADDR to be cleaned up, in the case that an exception propagates - through its binding contour. */ - -void -push_exception_cleanup (addr) - tree addr; -{ - tree decl = build_decl (VAR_DECL, get_identifier (EXCEPTION_CLEANUP_NAME), ptr_type_node); - tree cleanup; - - decl = pushdecl (decl); - DECL_REGISTER (decl) = 1; - store_init_value (decl, addr); - expand_decl (decl); - expand_decl_init (decl); - - cleanup = build (COND_EXPR, integer_type_node, - build (NE_EXPR, integer_type_node, - decl, integer_zero_node), - build_delete (TREE_TYPE (addr), decl, - lookup_name (in_charge_identifier, 0), - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0), - integer_zero_node); - expand_decl_cleanup (decl, cleanup); -} - -/* For each binding contour, emit code that deactivates the - exception cleanups. All other cleanups are left as they were. */ - -static void -deactivate_exception_cleanups () -{ - struct binding_level *b = current_binding_level; - tree xyzzy = get_identifier (EXCEPTION_CLEANUP_NAME); - while (b != class_binding_level) - { - if (b->parm_flag == 3) - { - tree decls = b->names; - while (decls) - { - if (DECL_NAME (decls) == xyzzy) - expand_assignment (decls, integer_zero_node, 0, 0); - decls = TREE_CHAIN (decls); - } - } - b = b->level_chain; - } -} - -/* Change a static member function definition into a FUNCTION_TYPE, instead - of the METHOD_TYPE that we create when it's originally parsed. */ -void -revert_static_member_fn (fn, decl, argtypes) - tree *fn, *decl, *argtypes; -{ - tree tmp, function = *fn; - - *argtypes = TREE_CHAIN (*argtypes); - tmp = build_function_type (TREE_TYPE (function), *argtypes); - tmp = build_type_variant (tmp, TYPE_READONLY (function), - TYPE_VOLATILE (function)); - tmp = build_exception_variant (TYPE_METHOD_BASETYPE (function), tmp, - TYPE_RAISES_EXCEPTIONS (function)); - TREE_TYPE (*decl) = tmp; - *fn = tmp; - DECL_STATIC_FUNCTION_P (*decl) = 1; -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-decl.h b/gnu/usr.bin/gcc2/cc1plus/cp-decl.h deleted file mode 100644 index ad16f5cc7ff..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-decl.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Variables and structures for declaration processing. - Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: cp-decl.h,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $ -*/ - -/* In grokdeclarator, distinguish syntactic contexts of declarators. */ -enum decl_context -{ NORMAL, /* Ordinary declaration */ - FUNCDEF, /* Function definition */ - PARM, /* Declaration of parm before function body */ - FIELD, /* Declaration inside struct or union */ - BITFIELD, /* Likewise but with specified width */ - TYPENAME, /* Typename (inside cast or sizeof) */ - MEMFUNCDEF /* Member function definition */ -}; - -/* C++: Keep these around to reduce calls to `get_identifier'. - Identifiers for `this' in member functions and the auto-delete - parameter for destructors. */ -extern tree this_identifier, in_charge_identifier; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ -extern tree last_function_parms; - -/* A list of static class variables. This is needed, because a - static class variable can be declared inside the class without - an initializer, and then initialized, staticly, outside the class. */ -extern tree pending_statics; - -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -extern tree static_aggregates; - -/* A list of functions which were declared inline, but later had their - address taken. Used only for non-virtual member functions, since we can - find other functions easily enough. */ -extern tree pending_addressable_inlines; - -#ifdef DEBUG_CP_BINDING_LEVELS -/* Purely for debugging purposes. */ -extern int debug_bindings_indentation; -#endif diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-decl2.c b/gnu/usr.bin/gcc2/cc1plus/cp-decl2.c deleted file mode 100644 index 474c93d83f4..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-decl2.c +++ /dev/null @@ -1,2454 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-decl2.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include "config.h" -#include -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "cp-tree.h" -#include "cp-decl.h" -#include "cp-lex.h" - -extern tree grokdeclarator (); -static void grok_function_init (); - -/* A list of virtual function tables we must make sure to write out. */ -tree pending_vtables; - -/* A list of static class variables. This is needed, because a - static class variable can be declared inside the class without - an initializer, and then initialized, staticly, outside the class. */ -tree pending_statics; - -extern tree pending_addressable_inlines; - -/* Used to help generate temporary names which are unique within - a function. Reset to 0 by start_function. */ - -static int temp_name_counter; - -/* Same, but not reset. Local temp variables and global temp variables - can have the same name. */ -static int global_temp_name_counter; - -/* The (assembler) name of the first globally-visible object output. */ -extern char * first_global_object_name; - -/* Flag used when debugging cp-spew.c */ - -extern int spew_debug; - -/* C (and C++) language-specific option variables. */ - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -int flag_cond_mismatch; - -/* Nonzero means give `double' the same size as `float'. */ - -int flag_short_double; - -/* Nonzero means don't recognize the keyword `asm'. */ - -int flag_no_asm; - -/* Nonzero means don't recognize the non-ANSI builtin functions. */ - -int flag_no_builtin; - -/* Nonzero means do some things the same way PCC does. */ - -int flag_traditional; - -/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ - -int flag_signed_bitfields = 1; - -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident = 0; - -/* Nonzero means handle things in ANSI, instead of GNU fashion. This - flag should be tested for language behavior that's different between - ANSI and GNU, but not so horrible as to merit a PEDANTIC label. */ - -int flag_ansi = 0; - -/* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - -int flag_implement_inlines = 1; - -/* Nonzero means warn about implicit declarations. */ - -int warn_implicit = 1; - -/* Like `warn_return_type', but this is set by users, whereas - `warn_return_type' is set by the compiler. */ - -int explicit_warn_return_type; - -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ - -int warn_write_strings; - -/* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - -int warn_cast_qual; - -/* Nonzero means warn that dbx info for template class methods isn't fully - supported yet. */ - -int warn_template_debugging; - -/* Warn about traditional constructs whose meanings changed in ANSI C. */ - -int warn_traditional; - -/* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - -int warn_pointer_arith; - -/* Nonzero means warn for non-prototype function decls - or non-prototyped defs without previous prototype. */ - -int warn_strict_prototypes; - -/* Nonzero means warn for any function def without prototype decl. */ - -int warn_missing_prototypes; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -int warn_redundant_decls; - -/* Warn about *printf or *scanf format/argument anomalies. */ - -int warn_format; - -/* Warn about a subscript that has type char. */ - -int warn_char_subscripts = 0; - -/* Warn if a type conversion is done that might have confusing results. */ - -int warn_conversion; - -/* Warn if adding () is suggested. */ - -int warn_parentheses = 1; - -/* Non-zero means warn in function declared in derived class has the - same name as a virtual in the base class, but fails to match the - type signature of any virtual function in the base class. */ -int warn_overloaded_virtual; - -/* Non-zero means warn when converting between different enumeral types. */ -int warn_enum_clash; - -/* Non-zero means warn when declaring a class that has a non virtual - destructor, when it really ought to have a virtual one. */ -int warn_nonvdtor = 1; - -/* Nonzero means `$' can be in an identifier. - See cccp.c for reasons why this breaks some obscure ANSI C programs. */ - -#ifndef DOLLARS_IN_IDENTIFIERS -#define DOLLARS_IN_IDENTIFIERS 1 -#endif -int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; - -/* Nonzero for -no-strict-prototype switch: do not consider empty - argument prototype to mean function takes no arguments. */ - -int strict_prototype = 1; -int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus = 1; - -/* Nonzero means that labels can be used as first-class objects */ - -int flag_labels_ok; - -/* Non-zero means to collect statistics which might be expensive - and to print them when we are done. */ -int flag_detailed_statistics; - -/* C++ specific flags. */ -/* Nonzero for -fall-virtual: make every member function (except - constructors) lay down in the virtual function table. Calls - can then either go through the virtual function table or not, - depending. */ - -int flag_all_virtual; - -/* Zero means that `this' is a *const. This gives nice behavior in the - 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. - -2 means we're constructing an object and it has fixed type. */ - -int flag_this_is_variable; - -/* Nonzero means memoize our member lookups. */ - -int flag_memoize_lookups; int flag_save_memoized_contexts; - -/* 3 means write out only virtuals function tables `defined' - in this implementation file. - 2 means write out only specific virtual function tables - and give them (C) public visibility. - 1 means write out virtual function tables and give them - (C) public visibility. - 0 means write out virtual function tables and give them - (C) static visibility (default). - -1 means declare virtual function tables extern. */ - -int write_virtuals; - -/* Nonzero means we should attempt to elide constructors when possible. */ - -int flag_elide_constructors; - -/* Same, but for inline functions: nonzero means write out debug info - for inlines. Zero means do not. */ - -int flag_inline_debug; - -/* Nonzero means recognize and handle exception handling constructs. - 2 means handle exceptions the way Spring wants them handled. */ - -int flag_handle_exceptions; - -/* Nonzero means recognize and handle exception handling constructs. - Use ansi syntax and semantics. WORK IN PROGRESS! - 2 means handle exceptions the way Spring wants them handled. */ - -int flag_ansi_exceptions; - -/* Nonzero means that member functions defined in class scope are - inline by default. */ - -int flag_default_inline = 1; - -/* Controls whether enums and ints freely convert. - 1 means with complete freedom. - 0 means enums can convert to ints, but not vice-versa. */ -int flag_int_enum_equivalence; - -/* Controls whether compiler is operating under LUCID's Cadillac - system. 1 means yes, 0 means no. */ -int flag_cadillac; - -/* Controls whether compiler generates code to build objects - that can be collected when they become garbage. */ -int flag_gc; - -/* Controls whether compiler generates 'dossiers' that give - run-time type information. */ -int flag_dossier; - -/* Nonzero if we wish to output cross-referencing information - for the GNU class browser. */ -extern int flag_gnu_xref; - -/* Nonzero if compiler can make `reasonable' assumptions about - references and objects. For example, the compiler must be - conservative about the following and not assume that `a' is nonnull: - - obj &a = g (); - a.f (2); - - In general, it is `reasonable' to assume that for many programs, - and better code can be generated in that case. */ - -int flag_assume_nonnull_objects; - -/* Table of language-dependent -f options. - STRING is the option name. VARIABLE is the address of the variable. - ON_VALUE is the value to store in VARIABLE - if `-fSTRING' is seen as an option. - (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ - -static struct { char *string; int *variable; int on_value;} lang_f_options[] = -{ - {"signed-char", &flag_signed_char, 1}, - {"unsigned-char", &flag_signed_char, 0}, - {"signed-bitfields", &flag_signed_bitfields, 1}, - {"unsigned-bitfields", &flag_signed_bitfields, 0}, - {"short-enums", &flag_short_enums, 1}, - {"short-double", &flag_short_double, 1}, - {"cond-mismatch", &flag_cond_mismatch, 1}, - {"asm", &flag_no_asm, 0}, - {"builtin", &flag_no_builtin, 0}, - {"ident", &flag_no_ident, 0}, - {"labels-ok", &flag_labels_ok, 1}, - {"stats", &flag_detailed_statistics, 1}, - {"this-is-variable", &flag_this_is_variable, 1}, - {"strict-prototype", &strict_prototypes_lang_cplusplus, 1}, - {"all-virtual", &flag_all_virtual, 1}, - {"memoize-lookups", &flag_memoize_lookups, 1}, - {"elide-constructors", &flag_elide_constructors, 1}, - {"inline-debug", &flag_inline_debug, 0}, - {"handle-exceptions", &flag_handle_exceptions, 1}, - {"ansi-exceptions", &flag_ansi_exceptions, 1}, - {"spring-exceptions", &flag_handle_exceptions, 2}, - {"default-inline", &flag_default_inline, 1}, - {"dollars-in-identifiers", &dollars_in_ident, 1}, - {"enum-int-equiv", &flag_int_enum_equivalence, 1}, - {"gc", &flag_gc, 1}, - {"dossier", &flag_dossier, 1}, - {"xref", &flag_gnu_xref, 1}, - {"nonnull-objects", &flag_assume_nonnull_objects, 1}, - {"implement-inlines", &flag_implement_inlines, 1}, -}; - -/* Decode the string P as a language-specific option. - Return 1 if it is recognized (and handle it); - return 0 if not recognized. */ - -int -lang_decode_option (p) - char *p; -{ - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - flag_traditional = 1, dollars_in_ident = 1, flag_writable_strings = 1, - flag_this_is_variable = 1; - /* The +e options are for cfront compatibility. They come in as - `-+eN', to kludge around gcc.c's argument handling. */ - else if (p[0] == '-' && p[1] == '+' && p[2] == 'e') - { - int old_write_virtuals = write_virtuals; - if (p[3] == '1') - write_virtuals = 1; - else if (p[3] == '0') - write_virtuals = -1; - else if (p[3] == '2') - write_virtuals = 2; - else error ("invalid +e option"); - if (old_write_virtuals != 0 - && write_virtuals != old_write_virtuals) - error ("conflicting +e options given"); - } - else if (p[0] == '-' && p[1] == 'f') - { - /* Some kind of -f option. - P's value is the option sans `-f'. - Search for it in the table of options. */ - int found = 0, j; - - p += 2; - /* Try special -f options. */ - - if (!strcmp (p, "save-memoized")) - { - flag_memoize_lookups = 1; - flag_save_memoized_contexts = 1; - found = 1; - } - if (!strcmp (p, "no-save-memoized")) - { - flag_memoize_lookups = 0; - flag_save_memoized_contexts = 0; - found = 1; - } - else if (! strncmp (p, "cadillac", 8)) - { - flag_cadillac = atoi (p+9); - found = 1; - } - else if (! strncmp (p, "no-cadillac", 11)) - { - flag_cadillac = 0; - found = 1; - } - else if (! strcmp (p, "gc")) - { - flag_gc = 1; - /* This must come along for the ride. */ - flag_dossier = 1; - found = 1; - } - else if (! strcmp (p, "no-gc")) - { - flag_gc = 0; - /* This must come along for the ride. */ - flag_dossier = 0; - found = 1; - } - else for (j = 0; - !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); - j++) - { - if (!strcmp (p, lang_f_options[j].string)) - { - *lang_f_options[j].variable = lang_f_options[j].on_value; - /* A goto here would be cleaner, - but breaks the vax pcc. */ - found = 1; - } - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' - && ! strcmp (p+3, lang_f_options[j].string)) - { - *lang_f_options[j].variable = ! lang_f_options[j].on_value; - found = 1; - } - } - return found; - } - else if (p[0] == '-' && p[1] == 'W') - { - int setting = 1; - - /* The -W options control the warning behavior of the compiler. */ - p += 2; - - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') - setting = 0, p += 3; - - if (!strcmp (p, "implicit")) - warn_implicit = setting; - else if (!strcmp (p, "return-type")) - explicit_warn_return_type = setting; - else if (!strcmp (p, "write-strings")) - warn_write_strings = setting; - else if (!strcmp (p, "cast-qual")) - warn_cast_qual = setting; - else if (!strcmp (p, "traditional")) - warn_traditional = setting; - else if (!strcmp (p, "char-subscripts")) - warn_char_subscripts = setting; - else if (!strcmp (p, "pointer-arith")) - warn_pointer_arith = setting; - else if (!strcmp (p, "strict-prototypes")) - warn_strict_prototypes = setting; - else if (!strcmp (p, "missing-prototypes")) - warn_missing_prototypes = setting; - else if (!strcmp (p, "redundant-decls")) - warn_redundant_decls = setting; - else if (!strcmp (p, "format")) - warn_format = setting; - else if (!strcmp (p, "conversion")) - warn_conversion = setting; - else if (!strcmp (p, "parentheses")) - warn_parentheses = setting; - else if (!strcmp (p, "comment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "comments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "import")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "all")) - { - extra_warnings = setting; - explicit_warn_return_type = setting; - warn_unused = setting; - warn_implicit = setting; - warn_switch = setting; - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = (setting ? 2 : 0); - warn_template_debugging = setting; -#if 0 - warn_enum_clash = setting; -#endif - } - - else if (!strcmp (p, "overloaded-virtual")) - warn_overloaded_virtual = setting; - else if (!strcmp (p, "enum-clash")) - warn_enum_clash = setting; - else return 0; - } - else if (!strcmp (p, "-ansi")) - flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1; -#ifdef SPEW_DEBUG - /* Undocumented, only ever used when you're invoking cc1plus by hand, since - it's probably safe to assume no sane person would ever want to use this - under normal circumstances. */ - else if (!strcmp (p, "-spew-debug")) - spew_debug = 1; -#endif - else - return 0; - - return 1; -} - -/* Incorporate `const' and `volatile' qualifiers for member functions. - FUNCTION is a TYPE_DECL or a FUNCTION_DECL. - QUALS is a list of qualifiers. */ -tree -grok_method_quals (ctype, function, quals) - tree ctype, function, quals; -{ - tree fntype = TREE_TYPE (function); - tree raises = TYPE_RAISES_EXCEPTIONS (fntype); - - do - { - extern tree ridpointers[]; - - if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST]) - { - if (TYPE_READONLY (ctype)) - error ("duplicate `%s' %s", - IDENTIFIER_POINTER (TREE_VALUE (quals)), - (TREE_CODE (function) == FUNCTION_DECL - ? "for member function" : "in type declaration")); - ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype)); - build_pointer_type (ctype); - } - else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE]) - { - if (TYPE_VOLATILE (ctype)) - error ("duplicate `%s' %s", - IDENTIFIER_POINTER (TREE_VALUE (quals)), - (TREE_CODE (function) == FUNCTION_DECL - ? "for member function" : "in type declaration")); - ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1); - build_pointer_type (ctype); - } - else - my_friendly_abort (20); - quals = TREE_CHAIN (quals); - } - while (quals); - fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype), - (TREE_CODE (fntype) == METHOD_TYPE - ? TREE_CHAIN (TYPE_ARG_TYPES (fntype)) - : TYPE_ARG_TYPES (fntype))); - if (raises) - fntype = build_exception_variant (ctype, fntype, raises); - - TREE_TYPE (function) = fntype; - return ctype; -} - -/* This routine replaces cryptic DECL_NAMEs with readable DECL_NAMEs. - It leaves DECL_ASSEMBLER_NAMEs with the correct value. */ -/* This does not yet work with user defined conversion operators - It should. */ -static void -substitute_nice_name (decl) - tree decl; -{ - if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE) - { - char *n = decl_as_string (DECL_NAME (decl)); - if (n[strlen (n) - 1] == ' ') - n[strlen (n) - 1] = 0; - DECL_NAME (decl) = get_identifier (n); - } -} - -/* Classes overload their constituent function names automatically. - When a function name is declared in a record structure, - its name is changed to it overloaded name. Since names for - constructors and destructors can conflict, we place a leading - '$' for destructors. - - CNAME is the name of the class we are grokking for. - - FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'. - - FLAGS contains bits saying what's special about today's - arguments. 1 == DESTRUCTOR. 2 == OPERATOR. - - If FUNCTION is a destructor, then we must add the `auto-delete' field - as a second parameter. There is some hair associated with the fact - that we must "declare" this variable in the manner consistent with the - way the rest of the arguments were declared. - - QUALS are the qualifiers for the this pointer. */ - -void -grokclassfn (ctype, cname, function, flags, quals) - tree ctype, cname, function; - enum overload_flags flags; - tree quals; -{ - tree fn_name = DECL_NAME (function); - tree arg_types; - tree parm; - - if (fn_name == NULL_TREE) - { - error ("name missing for member function"); - fn_name = get_identifier (""); - DECL_NAME (function) = fn_name; - } - - if (quals) - ctype = grok_method_quals (ctype, function, quals); - - arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); - if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) - { - /* Must add the class instance variable up front. */ - /* Right now we just make this a pointer. But later - we may wish to make it special. */ - tree type = TREE_VALUE (arg_types); - - if (flags == DTOR_FLAG) - type = TYPE_MAIN_VARIANT (type); - else if (DECL_CONSTRUCTOR_P (function)) - { - if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) - { - DECL_CONSTRUCTOR_FOR_VBASE_P (function) = 1; - /* In this case we need "in-charge" flag saying whether - this constructor is responsible for initialization - of virtual baseclasses or not. */ - parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); - DECL_ARG_TYPE (parm) = integer_type_node; - DECL_REGISTER (parm) = 1; - TREE_CHAIN (parm) = last_function_parms; - last_function_parms = parm; - } - } - - parm = build_decl (PARM_DECL, this_identifier, type); - /* Mark the artificial `this' parameter as "artificial". */ - DECL_SOURCE_LINE (parm) = 0; - DECL_ARG_TYPE (parm) = type; - /* We can make this a register, so long as we don't - accidentally complain if someone tries to take its address. */ - DECL_REGISTER (parm) = 1; -#if 0 - /* it is wrong to flag the object as readonly, when - flag_this_is_variable is 0. */ - if (flags != DTOR_FLAG - && (flag_this_is_variable <= 0 || TYPE_READONLY (type))) -#else - if (flags != DTOR_FLAG && TYPE_READONLY (type)) -#endif - TREE_READONLY (parm) = 1; - TREE_CHAIN (parm) = last_function_parms; - last_function_parms = parm; - } - - if (flags == DTOR_FLAG) - { - char *buf, *dbuf; - tree const_integer_type = build_type_variant (integer_type_node, 1, 0); - int len = sizeof (DESTRUCTOR_DECL_PREFIX)-1; - - arg_types = hash_tree_chain (const_integer_type, void_list_node); - /* Build the overload name. It will look like e.g. 7Example. */ - if (IDENTIFIER_TYPE_VALUE (cname)) - dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); - else if (IDENTIFIER_LOCAL_VALUE (cname)) - dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1); - else -#if 0 - my_friendly_abort (346); -#else - /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when - it's defined out of the class definition, since poplevel_class wipes - it out. */ - dbuf = build_overload_name (ctype, 1, 1); -#endif - buf = (char *)alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX)); - bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); - buf[len] = '\0'; - strcat (buf, dbuf); - DECL_ASSEMBLER_NAME (function) = get_identifier (buf); - parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type); - TREE_USED (parm) = 1; - TREE_READONLY (parm) = 1; - DECL_ARG_TYPE (parm) = const_integer_type; - /* This is the same chain as DECL_ARGUMENTS (...). */ - TREE_CHAIN (last_function_parms) = parm; - - TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, arg_types); - TYPE_HAS_DESTRUCTOR (ctype) = 1; - } - else - { - tree these_arg_types; - - if (DECL_CONSTRUCTOR_FOR_VBASE_P (function)) - { - arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); - TREE_TYPE (function) - = build_cplus_method_type (ctype, TREE_TYPE (TREE_TYPE (function)), arg_types); - arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); - } - - these_arg_types = arg_types; - - if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) - /* Only true for static member functions. */ - these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types); - - DECL_ASSEMBLER_NAME (function) - = build_decl_overload (fn_name, these_arg_types, - 1 + DECL_CONSTRUCTOR_P (function)); - -#if 0 - /* This code is going into the compiler, but currently, it makes - libg++/src/Interger.cc not compile. The problem is that the nice name - winds up going into the symbol table, and conversion operations look - for the manged name. */ - substitute_nice_name (function); -#endif - -#if 0 - if (flags == TYPENAME_FLAG) - /* Not exactly an IDENTIFIER_TYPE_VALUE. */ - TREE_TYPE (DECL_ASSEMBLER_NAME (function)) = TREE_TYPE (fn_name); -#endif - } - - DECL_ARGUMENTS (function) = last_function_parms; - /* First approximations. */ - DECL_CONTEXT (function) = ctype; - DECL_CLASS_CONTEXT (function) = ctype; -} - -/* Generate errors possibly applicable for a given set of specifiers. */ -void -bad_specifiers (object, virtualp, quals, friendp, raises) - char *object; - int virtualp, quals, friendp, raises; -{ - if (virtualp) - error ("%s declared `virtual'", object); - if (quals) - error ("`const' and `volatile' function specifiers invalid in %s declaration"); - if (friendp) - error ("invalid friend declaration"); - if (raises) - error ("invalid raises declaration"); -} - -/* Sanity check: report error if this function FUNCTION is not - really a member of the class (CTYPE) it is supposed to belong to. - CNAME and FLAGS are the same here as they are for grokclassfn above. */ - -void -check_classfn (ctype, cname, function) - tree ctype, cname, function; -{ - tree fn_name = DECL_NAME (function); - tree fndecl; - int need_quotes = 0; - char *err_name; - tree method_vec = CLASSTYPE_METHOD_VEC (ctype); - tree *methods = 0; - tree *end = 0; - - if (method_vec != 0) - { - methods = &TREE_VEC_ELT (method_vec, 0); - end = TREE_VEC_END (method_vec); - - /* First suss out ctors and dtors. */ - if (*methods && fn_name == cname) - goto got_it; - - while (++methods != end) - { - if (fn_name == DECL_NAME (*methods)) - { - got_it: - fndecl = *methods; - while (fndecl) - { - if (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl)) - return; - fndecl = DECL_CHAIN (fndecl); - } - break; /* loser */ - } - } - } - - if (fn_name == ansi_opname[(int) TYPE_EXPR]) - { - if (TYPE_HAS_CONVERSION (ctype)) - err_name = "such type conversion operator"; - } - else if (IDENTIFIER_OPNAME_P (fn_name)) - { - err_name = (char *)alloca (1024); - sprintf (err_name, "`operator %s'", operator_name_string (fn_name)); - } - else - { - err_name = IDENTIFIER_POINTER (fn_name); - need_quotes = 1; - } - - if (methods != end) - if (need_quotes) - error ("argument list for `%s' does not match any in class `%s'", - err_name, IDENTIFIER_POINTER (cname)); - else - error ("argument list for %s does not match any in class `%s'", - err_name, IDENTIFIER_POINTER (cname)); - else - { - methods = 0; - if (need_quotes) - error ("no `%s' member function declared in class `%s'", - err_name, IDENTIFIER_POINTER (cname)); - else - error ("no %s declared in class `%s'", - err_name, IDENTIFIER_POINTER (cname)); - } - - /* If we did not find the method in the class, add it to - avoid spurious errors. */ - add_method (ctype, methods, function); -} - -/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) - of a structure component, returning a FIELD_DECL node. - QUALS is a list of type qualifiers for this decl (such as for declaring - const member functions). - - This is done during the parsing of the struct declaration. - The FIELD_DECL nodes are chained together and the lot of them - are ultimately passed to `build_struct' to make the RECORD_TYPE node. - - C++: - - If class A defines that certain functions in class B are friends, then - the way I have set things up, it is B who is interested in permission - granted by A. However, it is in A's context that these declarations - are parsed. By returning a void_type_node, class A does not attempt - to incorporate the declarations of the friends within its structure. - - DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING - CHANGES TO CODE IN `start_method'. */ - -tree -grokfield (declarator, declspecs, raises, init, asmspec_tree) - tree declarator, declspecs, raises, init, asmspec_tree; -{ - register tree value; - char *asmspec = 0; - - /* Convert () initializers to = initializers. */ - if (init == NULL_TREE && declarator != NULL_TREE - && TREE_CODE (declarator) == CALL_EXPR - && TREE_OPERAND (declarator, 0) - && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE - || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF) - && parmlist_is_exprlist (TREE_OPERAND (declarator, 1))) - { - init = TREE_OPERAND (declarator, 1); - declarator = TREE_OPERAND (declarator, 0); - } - - if (init - && TREE_CODE (init) == TREE_LIST - && TREE_VALUE (init) == error_mark_node - && TREE_CHAIN (init) == NULL_TREE) - init = NULL_TREE; - - value = grokdeclarator (declarator, declspecs, FIELD, init != 0, raises); - if (! value) - return NULL_TREE; /* friends went bad. */ - - /* Pass friendly classes back. */ - if (TREE_CODE (value) == VOID_TYPE) - return void_type_node; - - if (DECL_NAME (value) != NULL_TREE - && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' - && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) - error_with_decl (value, "member `%s' conflicts with virtual function table field name"); - - /* Stash away type declarations. */ - if (TREE_CODE (value) == TYPE_DECL) - { - DECL_NONLOCAL (value) = 1; - CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; - set_identifier_type_value (DECL_NAME (value), TREE_TYPE (value)); - pushdecl_class_level (value); - return value; - } - - if (DECL_IN_AGGR_P (value)) - { - error_with_decl (value, "`%s' is already defined in the class %s", - TYPE_NAME_STRING (DECL_CONTEXT (value))); - return void_type_node; - } - - if (flag_cadillac) - cadillac_start_decl (value); - - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - if (init != 0) - { - if (TREE_CODE (value) == FUNCTION_DECL) - { - grok_function_init (value, init); - init = NULL_TREE; - } - else if (pedantic) - { - error ("fields cannot have initializers"); - init = NULL_TREE; - } - else - { - /* We allow initializers to become parameters to base initializers. */ - if (TREE_CODE (init) == TREE_LIST) - { - if (TREE_CHAIN (init) == NULL_TREE) - init = TREE_VALUE (init); - else - init = digest_init (TREE_TYPE (value), init, (tree *)0); - } - - if (TREE_CODE (init) == CONST_DECL) - init = DECL_INITIAL (init); - else if (TREE_READONLY_DECL_P (init)) - init = decl_constant_value (init); - else if (TREE_CODE (init) == CONSTRUCTOR) - init = digest_init (TREE_TYPE (value), init, (tree *)0); - my_friendly_assert (TREE_PERMANENT (init), 192); - if (init == error_mark_node) - /* We must make this look different than `error_mark_node' - because `decl_const_value' would mis-interpret it - as only meaning that this VAR_DECL is defined. */ - init = build1 (NOP_EXPR, TREE_TYPE (value), init); - else if (! TREE_CONSTANT (init)) - { - /* We can allow references to things that are effectively - static, since references are initialized with the address. */ - if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE - || (TREE_STATIC (init) == 0 - && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd' - || DECL_EXTERNAL (init) == 0))) - { - error ("field initializer is not constant"); - init = error_mark_node; - } - } - } - } - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - if (TREE_CODE (value) == VAR_DECL) - { - /* We cannot call pushdecl here, because that would - fill in the value of our TREE_CHAIN. Instead, we - modify finish_decl to do the right thing, namely, to - put this decl out straight away. */ - if (TREE_STATIC (value)) - { - /* current_class_type can be NULL_TREE in case of error. */ - if (asmspec == 0 && current_class_type) - { - tree name; - char *buf, *buf2; - - buf2 = build_overload_name (current_class_type, 1, 1); - buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (value)) - + sizeof (STATIC_NAME_FORMAT) - + strlen (buf2)); - sprintf (buf, STATIC_NAME_FORMAT, buf2, - IDENTIFIER_POINTER (DECL_NAME (value))); - name = get_identifier (buf); - TREE_PUBLIC (value) = 1; - DECL_INITIAL (value) = error_mark_node; - DECL_ASSEMBLER_NAME (value) = name; - } - pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics); - - /* Static consts need not be initialized in the class definition. */ - if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value))) - { - static int explanation = 0; - - error ("initializer invalid for static member with constructor"); - if (explanation++ == 0) - error ("(you really want to initialize it separately)"); - init = 0; - } - /* Force the compiler to know when an uninitialized static - const member is being used. */ - if (TYPE_READONLY (value) && init == 0) - TREE_USED (value) = 1; - } - DECL_INITIAL (value) = init; - DECL_IN_AGGR_P (value) = 1; - - finish_decl (value, init, asmspec_tree, 1); - pushdecl_class_level (value); - return value; - } - if (TREE_CODE (value) == FIELD_DECL) - { - if (asmspec) - DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); - if (DECL_INITIAL (value) == error_mark_node) - init = error_mark_node; - finish_decl (value, init, asmspec_tree, 1); - DECL_INITIAL (value) = init; - DECL_IN_AGGR_P (value) = 1; - return value; - } - if (TREE_CODE (value) == FUNCTION_DECL) - { - /* grokdeclarator defers setting this. */ - TREE_PUBLIC (value) = 1; - if (DECL_CHAIN (value) != NULL_TREE) - { - /* Need a fresh node here so that we don't get circularity - when we link these together. */ - value = copy_node (value); - /* When does this happen? */ - my_friendly_assert (init == NULL_TREE, 193); - } - finish_decl (value, init, asmspec_tree, 1); - - /* Pass friends back this way. */ - if (DECL_FRIEND_P (value)) - return void_type_node; - - DECL_IN_AGGR_P (value) = 1; - return value; - } - my_friendly_abort (21); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Like `grokfield', but for bitfields. - WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */ - -tree -grokbitfield (declarator, declspecs, width) - tree declarator, declspecs, width; -{ - register tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL_TREE); - - if (! value) return NULL_TREE; /* friends went bad. */ - - /* Pass friendly classes back. */ - if (TREE_CODE (value) == VOID_TYPE) - return void_type_node; - - if (TREE_CODE (value) == TYPE_DECL) - { - error_with_decl (value, "cannot declare `%s' to be a bitfield type"); - return NULL_TREE; - } - - if (DECL_IN_AGGR_P (value)) - { - error_with_decl (value, "`%s' is already defined in the class %s", - TYPE_NAME_STRING (DECL_CONTEXT (value))); - return void_type_node; - } - - GNU_xref_member (current_class_name, value); - - if (TREE_STATIC (value)) - { - error_with_decl (value, "static member `%s' cannot be a bitfield"); - return NULL_TREE; - } - finish_decl (value, NULL_TREE, NULL_TREE, 0); - - if (width != error_mark_node) - { - /* detect invalid field size. */ - if (TREE_CODE (width) == CONST_DECL) - width = DECL_INITIAL (width); - else if (TREE_READONLY_DECL_P (width)) - width = decl_constant_value (width); - if (TREE_CODE (width) != INTEGER_CST) - { - error_with_decl (value, "structure field `%s' width not an integer constant"); - DECL_INITIAL (value) = NULL_TREE; - } - else - { - DECL_INITIAL (value) = width; - DECL_BIT_FIELD (value) = 1; - } - } - - DECL_IN_AGGR_P (value) = 1; - return value; -} - -/* Like GROKFIELD, except that the declarator has been - buried in DECLSPECS. Find the declarator, and - return something that looks like it came from - GROKFIELD. */ -tree -groktypefield (declspecs, parmlist) - tree declspecs; - tree parmlist; -{ - tree spec = declspecs; - tree prev = NULL_TREE; - - tree type_id = NULL_TREE; - tree quals = NULL_TREE; - tree lengths = NULL_TREE; - tree decl = NULL_TREE; - - while (spec) - { - register tree id = TREE_VALUE (spec); - - if (TREE_CODE (spec) != TREE_LIST) - /* Certain parse errors slip through. For example, - `int class ();' is not caught by the parser. Try - weakly to recover here. */ - return NULL_TREE; - - if (TREE_CODE (id) == TYPE_DECL - || (TREE_CODE (id) == IDENTIFIER_NODE && TREE_TYPE (id))) - { - /* We have a constructor/destructor or - conversion operator. Use it. */ - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (spec); - else - declspecs = TREE_CHAIN (spec); - - type_id = id; - goto found; - } - prev = spec; - spec = TREE_CHAIN (spec); - } - - /* Nope, we have a conversion operator to a scalar type or something - else, that includes things like constructor declarations for - templates. */ - spec = declspecs; - while (spec) - { - tree id = TREE_VALUE (spec); - - if (TREE_CODE (id) == IDENTIFIER_NODE) - { - if (id == ridpointers[(int)RID_INT] - || id == ridpointers[(int)RID_DOUBLE] - || id == ridpointers[(int)RID_FLOAT] - || id == ridpointers[(int)RID_WCHAR]) - { - if (type_id) - error ("extra `%s' ignored", - IDENTIFIER_POINTER (id)); - else - type_id = id; - } - else if (id == ridpointers[(int)RID_LONG] - || id == ridpointers[(int)RID_SHORT] - || id == ridpointers[(int)RID_CHAR]) - { - lengths = tree_cons (NULL_TREE, id, lengths); - } - else if (id == ridpointers[(int)RID_VOID]) - { - if (type_id) - error ("spurious `void' type ignored"); - else - error ("conversion to `void' type invalid"); - } - else if (id == ridpointers[(int)RID_AUTO] - || id == ridpointers[(int)RID_REGISTER] - || id == ridpointers[(int)RID_TYPEDEF] - || id == ridpointers[(int)RID_CONST] - || id == ridpointers[(int)RID_VOLATILE]) - { - error ("type specifier `%s' used invalidly", - IDENTIFIER_POINTER (id)); - } - else if (id == ridpointers[(int)RID_FRIEND] - || id == ridpointers[(int)RID_VIRTUAL] - || id == ridpointers[(int)RID_INLINE] - || id == ridpointers[(int)RID_UNSIGNED] - || id == ridpointers[(int)RID_SIGNED] - || id == ridpointers[(int)RID_STATIC] - || id == ridpointers[(int)RID_EXTERN]) - { - quals = tree_cons (NULL_TREE, id, quals); - } - else - { - /* Happens when we have a global typedef - and a class-local member function with - the same name. */ - type_id = id; - goto found; - } - } - else if (TREE_CODE (id) == RECORD_TYPE) - { - type_id = TYPE_NAME (id); - if (TREE_CODE (type_id) == TYPE_DECL) - type_id = DECL_NAME (type_id); - if (type_id == NULL_TREE) - error ("identifier for aggregate type conversion omitted"); - } - else if (TREE_CODE_CLASS (TREE_CODE (id)) == 't') - error ("`operator' missing on conversion operator or tag missing from type"); - else - my_friendly_abort (194); - spec = TREE_CHAIN (spec); - } - - if (type_id) - declspecs = chainon (lengths, quals); - else if (lengths) - { - if (TREE_CHAIN (lengths)) - error ("multiple length specifiers"); - type_id = ridpointers[(int)RID_INT]; - declspecs = chainon (lengths, quals); - } - else if (quals) - { - error ("no type given, defaulting to `operator int ...'"); - type_id = ridpointers[(int)RID_INT]; - declspecs = quals; - } - else - return NULL_TREE; - - found: - decl = grokdeclarator (build_parse_node (CALL_EXPR, type_id, parmlist, NULL_TREE), - declspecs, FIELD, 0, NULL_TREE); - if (decl == NULL_TREE) - return NULL_TREE; - - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CHAIN (decl) != NULL_TREE) - { - /* Need a fresh node here so that we don't get circularity - when we link these together. */ - decl = copy_node (decl); - } - - if (decl == void_type_node - || (TREE_CODE (decl) == FUNCTION_DECL - && TREE_CODE (TREE_TYPE (decl)) != METHOD_TYPE)) - /* bunch of friends. */ - return decl; - - if (DECL_IN_AGGR_P (decl)) - { - error_with_decl (decl, "`%s' already defined in the class "); - return void_type_node; - } - - finish_decl (decl, NULL_TREE, NULL_TREE, 0); - - /* If this declaration is common to another declaration - complain about such redundancy, and return NULL_TREE - so that we don't build a circular list. */ - if (DECL_CHAIN (decl)) - { - error_with_decl (decl, "function `%s' declared twice in class %s", - TYPE_NAME_STRING (DECL_CONTEXT (decl))); - return NULL_TREE; - } - DECL_IN_AGGR_P (decl) = 1; - return decl; -} - -/* The precedence rules of this grammar (or any other deterministic LALR - grammar, for that matter), place the CALL_EXPR somewhere where we - may not want it. The solution is to grab the first CALL_EXPR we see, - pretend that that is the one that belongs to the parameter list of - the type conversion function, and leave everything else alone. - We pull it out in place. - - CALL_REQUIRED is non-zero if we should complain if a CALL_EXPR - does not appear in DECL. */ -tree -grokoptypename (decl, call_required) - tree decl; - int call_required; -{ - tree tmp, last; - - my_friendly_assert (TREE_CODE (decl) == TYPE_EXPR, 195); - - tmp = TREE_OPERAND (decl, 0); - last = NULL_TREE; - - while (tmp) - { - switch (TREE_CODE (tmp)) - { - case CALL_EXPR: - { - tree parms = TREE_OPERAND (tmp, 1); - - if (last) - TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0); - else - TREE_OPERAND (decl, 0) = TREE_OPERAND (tmp, 0); - if (parms - && TREE_CODE (TREE_VALUE (parms)) == TREE_LIST) - TREE_VALUE (parms) - = grokdeclarator (TREE_VALUE (TREE_VALUE (parms)), - TREE_PURPOSE (TREE_VALUE (parms)), - TYPENAME, 0, NULL_TREE); - if (parms) - { - if (TREE_VALUE (parms) != void_type_node) - error ("operator requires empty parameter list"); - else - /* Canonicalize parameter lists. */ - TREE_OPERAND (tmp, 1) = void_list_node; - } - - last = grokdeclarator (TREE_OPERAND (decl, 0), - TREE_TYPE (decl), - TYPENAME, 0, NULL_TREE); - TREE_OPERAND (tmp, 0) = build_typename_overload (last); - TREE_TYPE (TREE_OPERAND (tmp, 0)) = last; - return tmp; - } - - case INDIRECT_REF: - case ADDR_EXPR: - case ARRAY_REF: - break; - - case SCOPE_REF: - /* This is legal when declaring a conversion to - something of type pointer-to-member. */ - if (TREE_CODE (TREE_OPERAND (tmp, 1)) == INDIRECT_REF) - { - tmp = TREE_OPERAND (tmp, 1); - } - else - { -#if 0 - /* We may need to do this if grokdeclarator cannot handle this. */ - error ("type `member of class %s' invalid return type", - TYPE_NAME_STRING (TREE_OPERAND (tmp, 0))); - TREE_OPERAND (tmp, 1) = build_parse_node (INDIRECT_REF, TREE_OPERAND (tmp, 1)); -#endif - tmp = TREE_OPERAND (tmp, 1); - } - break; - - default: - my_friendly_abort (196); - } - last = tmp; - tmp = TREE_OPERAND (tmp, 0); - } - - if (call_required) - error ("operator construct requires parameter list"); - - last = grokdeclarator (TREE_OPERAND (decl, 0), - TREE_TYPE (decl), - TYPENAME, 0, NULL_TREE); - tmp = build_parse_node (CALL_EXPR, build_typename_overload (last), - void_list_node, NULL_TREE); - TREE_TYPE (TREE_OPERAND (tmp, 0)) = last; - return tmp; -} - -/* When a function is declared with an initializer, - do the right thing. Currently, there are two possibilities: - - class B - { - public: - // initialization possibility #1. - virtual void f () = 0; - int g (); - }; - - class D1 : B - { - public: - int d1; - // error, no f (); - }; - - class D2 : B - { - public: - int d2; - void f (); - }; - - class D3 : B - { - public: - int d3; - // initialization possibility #2 - void f () = B::f; - }; - -*/ - -static void -grok_function_init (decl, init) - tree decl; - tree init; -{ - /* An initializer for a function tells how this function should - be inherited. */ - tree type = TREE_TYPE (decl); - extern tree abort_fndecl; - - if (TREE_CODE (type) == FUNCTION_TYPE) - error_with_decl (decl, "initializer specified for non-member function `%s'"); - else if (DECL_VINDEX (decl) == NULL_TREE) - error_with_decl (decl, "initializer specified for non-virtual method `%s'"); - else if (integer_zerop (init)) - { - /* Mark this function as being "defined". */ - DECL_INITIAL (decl) = error_mark_node; - /* pure virtual destructors must be defined. */ - if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) - { - /* Give this node rtl from `abort'. */ - DECL_RTL (decl) = DECL_RTL (abort_fndecl); - } - DECL_ABSTRACT_VIRTUAL_P (decl) = 1; - } - else if (TREE_CODE (init) == OFFSET_REF - && TREE_OPERAND (init, 0) == NULL_TREE - && TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE) - { - tree basetype = DECL_CLASS_CONTEXT (init); - tree basefn = TREE_OPERAND (init, 1); - if (TREE_CODE (basefn) != FUNCTION_DECL) - error_with_decl (decl, "non-method initializer invalid for method `%s'"); - else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn)))) - sorry ("base member function from other than first base class"); - else - { - tree binfo = get_binfo (basetype, TYPE_METHOD_BASETYPE (type), 1); - if (binfo == error_mark_node) - ; - else if (binfo == 0) - error_not_base_type (TYPE_METHOD_BASETYPE (TREE_TYPE (init)), - TYPE_METHOD_BASETYPE (type)); - else - { - /* Mark this function as being defined, - and give it new rtl. */ - DECL_INITIAL (decl) = error_mark_node; - DECL_RTL (decl) = DECL_RTL (basefn); - } - } - } - else - error_with_decl (decl, "invalid initializer for virtual method `%s'"); -} - -/* When we get a declaration of the form - - type cname::fname ... - - the node for `cname::fname' gets built here in a special way. - Namely, we push into `cname's scope. When this declaration is - processed, we pop back out. */ -tree -build_push_scope (cname, name) - tree cname; - tree name; -{ - extern int current_class_depth; - tree ctype, rval; - - if (cname == error_mark_node) - return error_mark_node; - - ctype = IDENTIFIER_TYPE_VALUE (cname); - - if (ctype == NULL_TREE || ! IS_AGGR_TYPE (ctype)) - { - error ("`%s' not defined as aggregate type", IDENTIFIER_POINTER (cname)); - return name; - } - - rval = build_parse_node (SCOPE_REF, cname, name); - - /* Don't need to push the scope here, but we do need to return - a SCOPE_REF for something like - - class foo { typedef int bar (foo::*foo_fn)(void); }; */ - if (ctype == current_class_type) - return rval; - - pushclass (ctype, 3); - TREE_COMPLEXITY (rval) = current_class_depth; - return rval; -} - -void cplus_decl_attributes (decl, attributes) - tree decl, attributes; -{ - if (decl) - decl_attributes (decl, attributes); -} - -/* CONSTRUCTOR_NAME: - Return the name for the constructor (or destructor) for the specified - class. Argument can be RECORD_TYPE, TYPE_DECL, or IDENTIFIER_NODE. */ -tree -constructor_name (thing) - tree thing; -{ - tree t; - if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE) - return DECL_NAME (UPT_TEMPLATE (thing)); - if (TREE_CODE (thing) == RECORD_TYPE || TREE_CODE (thing) == UNION_TYPE) - thing = TYPE_NAME (thing); - if (TREE_CODE (thing) == TYPE_DECL - || (TREE_CODE (thing) == TEMPLATE_DECL - && DECL_TEMPLATE_IS_CLASS (thing))) - thing = DECL_NAME (thing); - my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197); - t = IDENTIFIER_TEMPLATE (thing); - if (!t) - return thing; - t = TREE_PURPOSE (t); - return DECL_NAME (t); -} - -/* Cache the value of this class's main virtual function table pointer - in a register variable. This will save one indirection if a - more than one virtual function call is made this function. */ -void -setup_vtbl_ptr () -{ - extern rtx base_init_insns; - - if (base_init_insns == 0 - && DECL_CONSTRUCTOR_P (current_function_decl)) - emit_base_init (current_class_type, 0); - -#if 0 - /* This has something a little wrong with it. - - On a sun4, code like: - - be L6 - ld [%i0],%o1 - - is generated, when the below is used when -O4 is given. The delay - slot it filled with an instruction that is safe, when this isn't - used, like in: - - be L6 - sethi %hi(LC1),%o0 - ld [%i0],%o1 - - on code like: - - struct A { - virtual void print() { printf("xxx"); } - void f(); - }; - - void A::f() { - if (this) { - print(); - } else { - printf("0"); - } - } - - And that is why this is disabled for now. (mrs) - */ - - if ((flag_this_is_variable & 1) == 0 - && optimize - && current_class_type - && CLASSTYPE_VSIZE (current_class_type) - && ! DECL_STATIC_FUNCTION_P (current_function_decl)) - { - tree vfield = build_vfield_ref (C_C_D, current_class_type); - current_vtable_decl = CLASSTYPE_VTBL_PTR (current_class_type); - DECL_RTL (current_vtable_decl) = 0; - DECL_INITIAL (current_vtable_decl) = error_mark_node; - /* Have to cast the initializer, since it may have come from a - more base class then we ascribe CURRENT_VTABLE_DECL to be. */ - finish_decl (current_vtable_decl, convert_force (TREE_TYPE (current_vtable_decl), vfield), 0, 0); - current_vtable_decl = build_indirect_ref (current_vtable_decl, 0); - } - else -#endif - current_vtable_decl = NULL_TREE; -} - -/* Record the existence of an addressable inline function. */ -void -mark_inline_for_output (decl) - tree decl; -{ - if (DECL_PENDING_INLINE_INFO (decl) != 0 - && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu) - { - struct pending_inline *t = pending_inlines; - my_friendly_assert (DECL_SAVED_INSNS (decl) == 0, 198); - while (t) - { - if (t == DECL_PENDING_INLINE_INFO (decl)) - break; - t = t->next; - } - if (t == 0) - { - t = DECL_PENDING_INLINE_INFO (decl); - t->next = pending_inlines; - pending_inlines = t; - } - DECL_PENDING_INLINE_INFO (decl) = 0; - } - pending_addressable_inlines = perm_tree_cons (NULL_TREE, decl, - pending_addressable_inlines); -} - -void -clear_temp_name () -{ - temp_name_counter = 0; -} - -/* Hand off a unique name which can be used for variable we don't really - want to know about anyway, for example, the anonymous variables which - are needed to make references work. Declare this thing so we can use it. - The variable created will be of type TYPE. - - STATICP is nonzero if this variable should be static. */ - -tree -get_temp_name (type, staticp) - tree type; - int staticp; -{ - char buf[sizeof (AUTO_TEMP_FORMAT) + 20]; - tree decl; - int toplev = global_bindings_p (); - - push_obstacks_nochange (); - if (toplev || staticp) - { - end_temporary_allocation (); - sprintf (buf, AUTO_TEMP_FORMAT, global_temp_name_counter++); - decl = pushdecl_top_level (build_decl (VAR_DECL, get_identifier (buf), type)); - } - else - { - sprintf (buf, AUTO_TEMP_FORMAT, temp_name_counter++); - decl = pushdecl (build_decl (VAR_DECL, get_identifier (buf), type)); - } - TREE_USED (decl) = 1; - TREE_STATIC (decl) = staticp; - - /* If this is a local variable, then lay out its rtl now. - Otherwise, callers of this function are responsible for dealing - with this variable's rtl. */ - if (! toplev) - { - expand_decl (decl); - expand_decl_init (decl); - } - pop_obstacks (); - - return decl; -} - -/* Get a variable which we can use for multiple assignments. - It is not entered into current_binding_level, because - that breaks things when it comes time to do final cleanups - (which take place "outside" the binding contour of the function). */ -tree -get_temp_regvar (type, init) - tree type, init; -{ - static char buf[sizeof (AUTO_TEMP_FORMAT) + 20] = { '_' }; - tree decl; - - sprintf (buf+1, AUTO_TEMP_FORMAT, temp_name_counter++); - decl = build_decl (VAR_DECL, get_identifier (buf), type); - TREE_USED (decl) = 1; - DECL_REGISTER (decl) = 1; - - if (init) - store_init_value (decl, init); - - /* We can expand these without fear, since they cannot need - constructors or destructors. */ - expand_decl (decl); - expand_decl_init (decl); - - if (type_needs_gc_entry (type)) - DECL_GC_OFFSET (decl) = size_int (++current_function_obstack_index); - - return decl; -} - -/* Make the macro TEMP_NAME_P available to units which do not - include c-tree.h. */ -int -temp_name_p (decl) - tree decl; -{ - return TEMP_NAME_P (decl); -} - -/* Finish off the processing of a UNION_TYPE structure. - If there are static members, then all members are - static, and must be laid out together. If the - union is an anonymous union, we arrange for that - as well. PUBLIC_P is nonzero if this union is - not declared static. */ -void -finish_anon_union (anon_union_decl) - tree anon_union_decl; -{ - tree type = TREE_TYPE (anon_union_decl); - tree field, main_decl = NULL_TREE; - tree elems = NULL_TREE; - int public_p = TREE_PUBLIC (anon_union_decl); - int static_p = TREE_STATIC (anon_union_decl); - int external_p = DECL_EXTERNAL (anon_union_decl); - - if ((field = TYPE_FIELDS (type)) == NULL_TREE) - return; - - if (public_p && (static_p || external_p)) - error ("optimizer cannot handle global anonymous unions"); - - while (field) - { - tree decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); - /* tell `pushdecl' that this is not tentative. */ - DECL_INITIAL (decl) = error_mark_node; - TREE_PUBLIC (decl) = public_p; - TREE_STATIC (decl) = static_p; - DECL_EXTERNAL (decl) = external_p; - decl = pushdecl (decl); - - /* Only write out one anon union element--choose the one that - can hold them all. */ - if (main_decl == NULL_TREE - && DECL_SIZE (decl) == DECL_SIZE (anon_union_decl)) - { - main_decl = decl; - } - else - { - /* ??? This causes there to be no debug info written out - about this decl. */ - TREE_ASM_WRITTEN (decl) = 1; - } - - DECL_INITIAL (decl) = NULL_TREE; - /* If there's a cleanup to do, it belongs in the - TREE_PURPOSE of the following TREE_LIST. */ - elems = tree_cons (NULL_TREE, decl, elems); - TREE_TYPE (elems) = type; - field = TREE_CHAIN (field); - } - if (static_p) - { - make_decl_rtl (main_decl, 0, global_bindings_p ()); - DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); - } - - /* The following call assumes that there are never any cleanups - for anonymous unions--a reasonable assumption. */ - expand_anon_union_decl (anon_union_decl, NULL_TREE, elems); - - if (flag_cadillac) - cadillac_finish_anon_union (anon_union_decl); -} - -/* Finish and output a table which is generated by the compiler. - NAME is the name to give the table. - TYPE is the type of the table entry. - INIT is all the elements in the table. - PUBLICP is non-zero if this table should be given external visibility. */ -tree -finish_table (name, type, init, publicp) - tree name, type, init; - int publicp; -{ - tree itype, atype, decl; - static tree empty_table; - int is_empty = 0; - tree asmspec; - - itype = build_index_type (size_int (list_length (init) - 1)); - atype = build_cplus_array_type (type, itype); - layout_type (atype); - - if (TREE_VALUE (init) == integer_zero_node - && TREE_CHAIN (init) == NULL_TREE) - { - if (empty_table == NULL_TREE) - { - empty_table = get_temp_name (atype, 1); - init = build (CONSTRUCTOR, atype, NULL_TREE, init); - TREE_CONSTANT (init) = 1; - TREE_STATIC (init) = 1; - DECL_INITIAL (empty_table) = init; - asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)), - IDENTIFIER_POINTER (DECL_NAME (empty_table))); - finish_decl (empty_table, init, asmspec, 0); - } - is_empty = 1; - } - - if (name == NULL_TREE) - { - if (is_empty) - return empty_table; - decl = get_temp_name (atype, 1); - } - else - { - decl = build_decl (VAR_DECL, name, atype); - decl = pushdecl (decl); - TREE_STATIC (decl) = 1; - } - - if (is_empty == 0) - { - TREE_PUBLIC (decl) = publicp; - init = build (CONSTRUCTOR, atype, NULL_TREE, init); - TREE_CONSTANT (init) = 1; - TREE_STATIC (init) = 1; - DECL_INITIAL (decl) = init; - asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (decl)), - IDENTIFIER_POINTER (DECL_NAME (decl))); - } - else - { - /* This will cause DECL to point to EMPTY_TABLE in rtl-land. */ - DECL_EXTERNAL (decl) = 1; - TREE_STATIC (decl) = 0; - init = 0; - asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)), - IDENTIFIER_POINTER (DECL_NAME (empty_table))); - } - - finish_decl (decl, init, asmspec, 0); - return decl; -} - -/* Finish processing a builtin type TYPE. It's name is NAME, - its fields are in the array FIELDS. LEN is the number of elements - in FIELDS. - - It is given the same alignment as ALIGN_TYPE. */ -void -finish_builtin_type (type, name, fields, len, align_type) - tree type; - char *name; - tree fields[]; - int len; - tree align_type; -{ - register int i; - - TYPE_FIELDS (type) = fields[0]; - for (i = 0; i < len; i++) - { - layout_type (TREE_TYPE (fields[i])); - DECL_FIELD_CONTEXT (fields[i]) = type; - TREE_CHAIN (fields[i]) = fields[i+1]; - } - DECL_FIELD_CONTEXT (fields[i]) = type; - DECL_CLASS_CONTEXT (fields[i]) = type; - TYPE_ALIGN (type) = TYPE_ALIGN (align_type); - layout_type (type); -#if 0 /* not yet, should get fixed properly later */ - TYPE_NAME (type) = make_type_decl (get_identifier (name), type); -#else - TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type); -#endif - layout_decl (TYPE_NAME (type), 0); -} - -/* Auxiliary functions to make type signatures for - `operator new' and `operator delete' correspond to - what compiler will be expecting. */ - -extern tree sizetype; - -tree -coerce_new_type (type) - tree type; -{ - int e1 = 0, e2 = 0; - - if (TREE_CODE (type) == METHOD_TYPE) - type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); - if (TREE_TYPE (type) != ptr_type_node) - e1 = 1, error ("`operator new' must return type `void *'"); - - /* Technically the type must be `size_t', but we may not know - what that is. */ - if (TYPE_ARG_TYPES (type) == NULL_TREE) - e1 = 1, error ("`operator new' takes type `size_t' parameter"); - else if (TREE_CODE (TREE_VALUE (TYPE_ARG_TYPES (type))) != INTEGER_TYPE - || TYPE_PRECISION (TREE_VALUE (TYPE_ARG_TYPES (type))) != TYPE_PRECISION (sizetype)) - e2 = 1, error ("`operator new' takes type `size_t' as first parameter"); - if (e2) - type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type)))); - else if (e1) - type = build_function_type (ptr_type_node, TYPE_ARG_TYPES (type)); - return type; -} - -tree -coerce_delete_type (type) - tree type; -{ - int e1 = 0, e2 = 0, e3 = 0; - tree arg_types = TYPE_ARG_TYPES (type); - - if (TREE_CODE (type) == METHOD_TYPE) - { - type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types)); - arg_types = TREE_CHAIN (arg_types); - } - if (TREE_TYPE (type) != void_type_node) - e1 = 1, error ("`operator delete' must return type `void'"); - if (arg_types == NULL_TREE - || TREE_VALUE (arg_types) != ptr_type_node) - e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); - - if (arg_types - && TREE_CHAIN (arg_types) - && TREE_CHAIN (arg_types) != void_list_node) - { - /* Again, technically this argument must be `size_t', but again - we may not know what that is. */ - tree t2 = TREE_VALUE (TREE_CHAIN (arg_types)); - if (TREE_CODE (t2) != INTEGER_TYPE - || TYPE_PRECISION (t2) != TYPE_PRECISION (sizetype)) - e3 = 1, error ("second argument to `operator delete' must be of type `size_t'"); - else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node) - { - e3 = 1; - if (TREE_CHAIN (TREE_CHAIN (arg_types))) - error ("too many arguments in declaration of `operator delete'"); - else - error ("`...' invalid in specification of `operator delete'"); - } - } - if (e3) - arg_types = tree_cons (NULL_TREE, ptr_type_node, build_tree_list (NULL_TREE, sizetype)); - else if (e3 |= e2) - { - if (arg_types == NULL_TREE) - arg_types = void_list_node; - else - arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types)); - } - else e3 |= e1; - - if (e3) - type = build_function_type (void_type_node, arg_types); - - return type; -} - -static void -write_vtable_entries (decl) - tree decl; -{ - tree entries = TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (decl))); - - if (flag_dossier) - entries = TREE_CHAIN (entries); - - for (; entries; entries = TREE_CHAIN (entries)) - { - tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)); - tree fn = TREE_OPERAND (fnaddr, 0); - if (! DECL_EXTERNAL (fn) && ! TREE_ASM_WRITTEN (fn) - && DECL_SAVED_INSNS (fn)) - { - if (TREE_PUBLIC (DECL_CLASS_CONTEXT (fn))) - TREE_PUBLIC (fn) = 1; - TREE_ADDRESSABLE (fn) = 1; - output_inline_function (fn); - } - else - assemble_external (fn); - } -} - -/* Note even though prev is never used in here, walk_vtables - expects this to have two arguments, so concede. */ -static void -finish_vtable_typedecl (prev, vars) - tree prev, vars; -{ - tree decl = TYPE_BINFO_VTABLE (TREE_TYPE (vars)); - - /* If we are controlled by `+e2', obey. */ - if (write_virtuals == 2) - { - tree binfo = value_member (DECL_NAME (vars), pending_vtables); - if (binfo) - TREE_PURPOSE (binfo) = void_type_node; - else - decl = NULL_TREE; - } - /* If this type has inline virtual functions, then - write those functions out now. */ - if (decl && write_virtuals >= 0 - && ! DECL_EXTERNAL (decl) && (TREE_PUBLIC (decl) || TREE_USED (decl))) - write_vtable_entries (decl); -} - -static void -finish_vtable_vardecl (prev, vars) - tree prev, vars; -{ - if (write_virtuals >= 0 - && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) - { - extern tree the_null_vtable_entry; - - /* Stuff this virtual function table's size into - `pfn' slot of `the_null_vtable_entry'. */ - tree nelts = array_type_nelts (TREE_TYPE (vars)); - SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts); - /* Kick out the dossier before writing out the vtable. */ - if (flag_dossier) - rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))))), 0), 0, 1, 1); - - /* Write it out. */ - write_vtable_entries (vars); - if (TREE_TYPE (DECL_INITIAL (vars)) == 0) - store_init_value (vars, DECL_INITIAL (vars)); - rest_of_decl_compilation (vars, 0, 1, 1); - } - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); -} - -void -walk_vtables (typedecl_fn, vardecl_fn) - register void (*typedecl_fn)(); - register void (*vardecl_fn)(); -{ - tree prev, vars; - - for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) - { - if (TREE_CODE (vars) == TYPE_DECL - && TYPE_LANG_SPECIFIC (TREE_TYPE (vars)) - && CLASSTYPE_VSIZE (TREE_TYPE (vars))) - { - if (typedecl_fn) (*typedecl_fn) (prev, vars); - } - else if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) - { - if (vardecl_fn) (*vardecl_fn) (prev, vars); - } - else - prev = vars; - } -} - -extern int parse_time, varconst_time; - -#define TIMEVAR(VAR, BODY) \ -do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) - -/* This routine is called from the last rule in yyparse (). - Its job is to create all the code needed to initialize and - destroy the global aggregates. We do the destruction - first, since that way we only need to reverse the decls once. */ - -void -finish_file () -{ - extern int lineno; - int start_time, this_time; - - char *buf; - char *p; - tree fnname; - tree vars = static_aggregates; - int needs_cleaning = 0, needs_messing_up = 0; - - if (main_input_filename == 0) - main_input_filename = input_filename; - if (!first_global_object_name) - first_global_object_name = main_input_filename; - - buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) - + strlen (first_global_object_name)); - - if (flag_detailed_statistics) - dump_tree_statistics (); - - /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type) - return; - - start_time = get_run_time (); - - /* Push into C language context, because that's all - we'll need here. */ - push_lang_context (lang_name_c); - - /* Set up the name of the file-level functions we may need. */ - /* Use a global object (which is already required to be unique over - the program) rather than the file name (which imposes extra - constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */ - sprintf (buf, FILE_FUNCTION_FORMAT, first_global_object_name); - - /* Don't need to pull wierd characters out of global names. */ - if (first_global_object_name == main_input_filename) - { - for (p = buf+11; *p; p++) - if (! ((*p >= '0' && *p <= '9') -#if 0 /* we always want labels, which are valid C++ identifiers (+ `$') */ -#ifndef ASM_IDENTIFY_GCC /* this is required if `.' is invalid -- k. raeburn */ - || *p == '.' -#endif -#endif -#ifndef NO_DOLLAR_IN_LABEL /* this for `$'; unlikely, but... -- kr */ - || *p == '$' -#endif -#ifndef NO_DOT_IN_LABEL /* this for `.'; unlikely, but... */ - || *p == '.' -#endif - || (*p >= 'A' && *p <= 'Z') - || (*p >= 'a' && *p <= 'z'))) - *p = '_'; - } - - /* See if we really need the hassle. */ - while (vars && needs_cleaning == 0) - { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - needs_cleaning = 1; - needs_messing_up = 1; - break; - } - else - needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type); - vars = TREE_CHAIN (vars); - } - if (needs_cleaning == 0) - goto mess_up; - - /* Otherwise, GDB can get confused, because in only knows - about source for LINENO-1 lines. */ - lineno -= 1; - - fnname = get_identifier (buf); - start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); - fnname = DECL_ASSEMBLER_NAME (current_function_decl); - store_parm_decls (); - - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - - /* These must be done in backward order to destroy, - in which they happen to be! */ - while (vars) - { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - tree temp = TREE_PURPOSE (vars); - - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - if (TREE_STATIC (vars)) - expand_start_cond (build_binary_op (NE_EXPR, temp, integer_zero_node, 1), 0); - if (TREE_CODE (type) == ARRAY_TYPE) - temp = decl; - else - { - mark_addressable (decl); - temp = build1 (ADDR_EXPR, TYPE_POINTER_TO (type), decl); - } - temp = build_delete (TREE_TYPE (temp), temp, - integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0, 0); - expand_expr_stmt (temp); - - if (TREE_STATIC (vars)) - expand_end_cond (); - } - vars = TREE_CHAIN (vars); - } - - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - - finish_function (lineno, 0); - - assemble_destructor (IDENTIFIER_POINTER (fnname)); - - /* if it needed cleaning, then it will need messing up: drop through */ - - mess_up: - /* Must do this while we think we are at the top level. */ - vars = nreverse (static_aggregates); - if (vars != NULL_TREE) - { - buf[FILE_FUNCTION_PREFIX_LEN] = 'I'; - - fnname = get_identifier (buf); - start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); - fnname = DECL_ASSEMBLER_NAME (current_function_decl); - store_parm_decls (); - - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - - while (vars) - { - tree decl = TREE_VALUE (vars); - tree init = TREE_PURPOSE (vars); - - /* If this was a static attribute within some function's scope, - then don't initialize it here. Also, don't bother - with initializers that contain errors. */ - if (TREE_STATIC (vars) - || (init && TREE_CODE (init) == TREE_LIST - && value_member (error_mark_node, init))) - { - vars = TREE_CHAIN (vars); - continue; - } - - if (TREE_CODE (decl) == VAR_DECL) - { - /* Set these global variables so that GDB at least puts - us near the declaration which required the initialization. */ - input_filename = DECL_SOURCE_FILE (decl); - lineno = DECL_SOURCE_LINE (decl); - emit_note (input_filename, lineno); - - if (init) - { - if (TREE_CODE (init) == VAR_DECL) - { - /* This behavior results when there are - multiple declarations of an aggregate, - the last of which defines it. */ - if (DECL_RTL (init) == DECL_RTL (decl)) - { - my_friendly_assert (DECL_INITIAL (decl) == error_mark_node - || (TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR - && CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) == NULL_TREE), - 199); - init = DECL_INITIAL (init); - if (TREE_CODE (init) == CONSTRUCTOR - && CONSTRUCTOR_ELTS (init) == NULL_TREE) - init = NULL_TREE; - } -#if 0 - else if (TREE_TYPE (decl) == TREE_TYPE (init)) - { -#if 1 - my_friendly_abort (200); -#else - /* point to real decl's rtl anyway. */ - DECL_RTL (init) = DECL_RTL (decl); - my_friendly_assert (DECL_INITIAL (decl) == error_mark_node, - 201); - init = DECL_INITIAL (init); -#endif /* 1 */ - } -#endif /* 0 */ - } - } - if (IS_AGGR_TYPE (TREE_TYPE (decl)) - || init == 0 - || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - /* Set this up so is_friend() works properly on _GLOBAL_ fns. */ - tree old_dcc = DECL_CLASS_CONTEXT (current_function_decl); - if (old_dcc == NULL_TREE) - DECL_CLASS_CONTEXT (current_function_decl) = TREE_TYPE (decl); - expand_aggr_init (decl, init, 0); - DECL_CLASS_CONTEXT (current_function_decl) = old_dcc; - } - else if (TREE_CODE (init) == TREE_VEC) - { - expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), - TREE_VEC_ELT (init, 1), - TREE_VEC_ELT (init, 2), 0), - const0_rtx, VOIDmode, 0); - free_temp_slots (); - } - else - expand_assignment (decl, init, 0, 0); - } - else if (TREE_CODE (decl) == SAVE_EXPR) - { - if (! PARM_DECL_EXPR (decl)) - { - /* a `new' expression at top level. */ - expand_expr (decl, const0_rtx, VOIDmode, 0); - free_temp_slots (); - expand_aggr_init (build_indirect_ref (decl, 0), init, 0); - } - } - else if (decl == error_mark_node) - ; - else my_friendly_abort (22); - vars = TREE_CHAIN (vars); - } - - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - - finish_function (lineno, 0); - assemble_constructor (IDENTIFIER_POINTER (fnname)); - } - - /* Done with C language context needs. */ - pop_lang_context (); - - /* Now write out any static class variables (which may have since - learned how to be initialized). */ - while (pending_statics) - { - tree decl = TREE_VALUE (pending_statics); - if (TREE_USED (decl) == 1 - || TREE_READONLY (decl) == 0 - || DECL_INITIAL (decl) == 0) - rest_of_decl_compilation (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1); - pending_statics = TREE_CHAIN (pending_statics); - } - - this_time = get_run_time (); - parse_time -= this_time - start_time; - varconst_time += this_time - start_time; - - /* Now write out inline functions which had their addresses taken - and which were not declared virtual and which were not declared - `extern inline'. */ - while (pending_addressable_inlines) - { - tree decl = TREE_VALUE (pending_addressable_inlines); - if (! TREE_ASM_WRITTEN (decl) - && ! DECL_EXTERNAL (decl) - && DECL_SAVED_INSNS (decl)) - output_inline_function (decl); - pending_addressable_inlines = TREE_CHAIN (pending_addressable_inlines); - } - - start_time = get_run_time (); - - /* Now delete from the chain of variables all virtual function tables. - We output them all ourselves, because each will be treated specially. */ - -#if 1 - /* The reason for pushing garbage onto the global_binding_level is to - ensure that we can slice out _DECLs which pertain to virtual function - tables. If the last thing pushed onto the global_binding_level was a - virtual function table, then slicing it out would slice away all the - decls (i.e., we lose the head of the chain). - - There are several ways of getting the same effect, from changing the - way that iterators over the chain treat the elements that pertain to - virtual function tables, moving the implementation of this code to - cp-decl.c (where we can manipulate global_binding_level directly), - popping the garbage after pushing it and slicing away the vtable - stuff, or just leaving it alone. */ - - /* Make last thing in global scope not be a virtual function table. */ -#if 0 /* not yet, should get fixed properly later */ - vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node); -#else - vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node); -#endif - DECL_IGNORED_P (vars) = 1; - DECL_SOURCE_LINE (vars) = 0; - pushdecl (vars); -#endif - - walk_vtables (finish_vtable_typedecl, finish_vtable_vardecl); - - if (write_virtuals == 2) - { - /* Now complain about an virtual function tables promised - but not delivered. */ - while (pending_vtables) - { - if (TREE_PURPOSE (pending_vtables) == NULL_TREE) - error ("virtual function table for `%s' not defined", - IDENTIFIER_POINTER (TREE_VALUE (pending_vtables))); - pending_vtables = TREE_CHAIN (pending_vtables); - } - } - - permanent_allocation (); - this_time = get_run_time (); - parse_time -= this_time - start_time; - varconst_time += this_time - start_time; - - if (flag_detailed_statistics) - dump_time_statistics (); -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-edsel.c b/gnu/usr.bin/gcc2/cc1plus/cp-edsel.c deleted file mode 100644 index 2f60ffacd46..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-edsel.c +++ /dev/null @@ -1,931 +0,0 @@ -/* Interface to LUCID Cadillac system for GNU compiler. - Copyright (C) 1988, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-edsel.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -#include "config.h" - -#include "tree.h" -#include "flags.h" -#include -#include "cp-tree.h" -#include "obstack.h" - -#ifdef CADILLAC -#include -#include -#include -#include -#include -#include - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -void init_cadillac (); - -extern char *input_filename; -extern int lineno; - -/* Put random information we might want to get back from - Cadillac here. */ -typedef struct -{ - /* The connection to the Cadillac kernel. */ - Connection *conn; - - /* Input and output file descriptors for Cadillac. */ - short fd_input, fd_output; - - /* #include nesting of current file. */ - short depth; - - /* State variables for the connection. */ - char messages; - char conversion; - char emission; - char process_until; - - /* #if level of current file. */ - int iflevel; - - /* Line number that starts current source file. */ - int lineno; - - /* Name of current file. */ - char *filename; - - /* Where to stop processing (if process_until is set). */ - char *end_filename; - int end_position; - -} cadillac_struct; -static cadillac_struct cadillacObj; - -/* Nonzero if in the process of exiting. */ -static int exiting; - -void cadillac_note_source (); -static void CWriteLanguageDecl (); -static void CWriteLanguageType (); -static void CWriteTopLevel (); -static void cadillac_note_filepos (); -static void cadillac_process_request (), cadillac_process_requests (); -static void cadillac_switch_source (); -static void exit_cadillac (); - -/* Blocking test. */ -static int -readable_p (fd) - int fd; -{ - fd_set f; - - FD_ZERO (&f); - FD_SET (fd, &f); - - return select (32, &f, NULL, NULL, 0) == 1; -} - -static CObjectType *tree_to_cadillac_map; -struct obstack cadillac_obstack; - - -#include "stack.h" - -struct context_level -{ - struct stack_level base; - - tree context; -}; - -/* Stack for maintaining contexts (in case functions or types are nested). - When defining a struct type, the `context' field is the RECORD_TYPE. - When defining a function, the `context' field is the FUNCTION_DECL. */ - -static struct context_level *context_stack; - -static struct context_level * -push_context_level (stack, obstack) - struct stack_level *stack; - struct obstack *obstack; -{ - struct context_level tem; - - tem.base.prev = stack; - return (struct context_level *)push_stack_level (obstack, &tem, sizeof (tem)); -} - -/* Discard a level of search allocation. */ - -static struct context_level * -pop_context_level (stack) - struct context_level *stack; -{ - stack = (struct context_level *)pop_stack_level (stack); - return stack; -} - -void -init_cadillac () -{ - extern FILE *finput; - extern int errno; - CCompilerMessage* req; - cadillac_struct *cp = &cadillacObj; - int i; - - if (! flag_cadillac) - return; - - tree_to_cadillac_map = (CObjectType*) xmalloc (sizeof (CObjectType) * LAST_CPLUS_TREE_CODE); - for (i = 0; i < LAST_CPLUS_TREE_CODE; i++) - tree_to_cadillac_map[i] = MiscOType; - tree_to_cadillac_map[RECORD_TYPE] = StructOType; - tree_to_cadillac_map[UNION_TYPE] = UnionOType; - tree_to_cadillac_map[ENUMERAL_TYPE] = EnumTypeOType; - tree_to_cadillac_map[TYPE_DECL] = TypedefOType; - tree_to_cadillac_map[VAR_DECL] = VariableOType; - tree_to_cadillac_map[CONST_DECL] = EnumConstantOType; - tree_to_cadillac_map[FUNCTION_DECL] = FunctionOType; - tree_to_cadillac_map[FIELD_DECL] = FieldOType; - -#ifdef sun - on_exit (&exit_cadillac, 0); -#endif - - gcc_obstack_init (&cadillac_obstack); - - /* Yow! This is the way Cadillac was designed to deal with - Oregon C++ compiler! */ - cp->fd_input = flag_cadillac; - cp->fd_output = flag_cadillac; - - /* Start in "turned-on" state. */ - cp->messages = 1; - cp->conversion = 1; - cp->emission = 1; - - /* Establish a connection with Cadillac here. */ - cp->conn = NewConnection (cp, cp->fd_input, cp->fd_output); - - CWriteHeader (cp->conn, WaitingMType, 0); - CWriteRequestBuffer (cp->conn); - - if (!readable_p (cp->fd_input)) - ; - - req = CReadCompilerMessage (cp->conn); - - if (!req) - switch (errno) - { - case EWOULDBLOCK: - sleep (5); - return; - - case 0: - fatal ("init_cadillac: EOF on connection to kernel, exiting\n"); - break; - - default: - perror ("Editor to kernel connection"); - exit (0); - } -} - -static void -cadillac_process_requests (conn) - Connection *conn; -{ - CCompilerMessage *req; - while (req = (CCompilerMessage*) CPeekNextRequest (conn)) - { - req = CReadCompilerMessage (conn); - cadillac_process_request (&cadillacObj, req); - } -} - -static void -cadillac_process_request (cp, req) - cadillac_struct *cp; - CCompilerMessage *req; -{ - if (! req) - return; - - switch (req->reqType) - { - case ProcessUntilMType: - if (cp->process_until) - my_friendly_abort (23); - cp->process_until = 1; - /* This is not really right. */ - cp->end_position = ((CCompilerCommand*)req)->processuntil.position; -#if 0 - cp->end_filename = req->processuntil.filename; -#endif - break; - - case CommandMType: - switch (req->header.data) - { - case MessagesOnCType: - cp->messages = 1; - break; - case MessagesOffCType: - cp->messages = 0; - break; - case ConversionOnCType: - cp->conversion = 1; - break; - case ConversionOffCType: - cp->conversion = 0; - break; - case EmissionOnCType: - cp->emission = 1; - break; - case EmissionOffCType: - cp->emission = 0; - break; - - case FinishAnalysisCType: - return; - - case PuntAnalysisCType: - case ContinueAnalysisCType: - case GotoFileposCType: - case OpenSucceededCType: - case OpenFailedCType: - fprintf (stderr, "request type %d not implemented\n", req->reqType); - return; - - case DieCType: - if (! exiting) - my_friendly_abort (24); - return; - - } - break; - - default: - fatal ("unknown request type %d", req->reqType); - } -} - -void -cadillac_start () -{ - Connection *conn = cadillacObj.conn; - CCompilerMessage *req; - - /* Let Cadillac know that we start in C++ language scope. */ - CWriteHeader (conn, ForeignLinkageMType, LinkCPlus); - CWriteLength (conn); - CWriteRequestBuffer (conn); - - cadillac_process_requests (conn); -} - -static void -cadillac_printf (msg, name) -{ - if (cadillacObj.messages) - printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name); -} - -void -cadillac_start_decl (decl) - tree decl; -{ - Connection *conn = cadillacObj.conn; - CObjectType object_type = tree_to_cadillac_map [TREE_CODE (decl)]; - - if (context_stack) - switch (TREE_CODE (context_stack->context)) - { - case FUNCTION_DECL: - /* Currently, cadillac only implements top-level forms. */ - return; - case RECORD_TYPE: - case UNION_TYPE: - cadillac_printf ("start class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); - break; - default: - my_friendly_abort (25); - } - else - { - cadillac_printf ("start top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - CWriteTopLevel (conn, StartMType); - } - - CWriteLanguageDecl (conn, decl, tree_to_cadillac_map[TREE_CODE (decl)]); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_finish_decl (decl) - tree decl; -{ - Connection *conn = cadillacObj.conn; - - if (context_stack) - switch (TREE_CODE (context_stack->context)) - { - case FUNCTION_DECL: - return; - case RECORD_TYPE: - case UNION_TYPE: - cadillac_printf ("end class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - break; - default: - my_friendly_abort (26); - } - else - { - cadillac_printf ("end top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - CWriteTopLevel (conn, StopMType); - } - - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_start_function (fndecl) - tree fndecl; -{ - Connection *conn = cadillacObj.conn; - - if (context_stack) - /* nested functions not yet handled. */ - my_friendly_abort (27); - - cadillac_printf ("start top-level function", lang_printable_name (fndecl)); - context_stack = push_context_level (context_stack, &cadillac_obstack); - context_stack->context = fndecl; - - CWriteTopLevel (conn, StartMType); - my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 202); - CWriteLanguageDecl (conn, fndecl, - (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE - ? MemberFnOType : FunctionOType)); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_finish_function (fndecl) - tree fndecl; -{ - Connection *conn = cadillacObj.conn; - - cadillac_printf ("end top-level function", lang_printable_name (fndecl)); - context_stack = pop_context_level (context_stack); - - if (context_stack) - /* nested functions not yet implemented. */ - my_friendly_abort (28); - - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - CWriteTopLevel (conn, StopMType); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_finish_anon_union (decl) - tree decl; -{ - Connection *conn = cadillacObj.conn; - - if (! global_bindings_p ()) - return; - cadillac_printf ("finish top-level anon union", ""); - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - CWriteTopLevel (conn, StopMType); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_start_enum (type) - tree type; -{ - Connection *conn = cadillacObj.conn; - - tree name = TYPE_NAME (type); - - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - if (context_stack) - switch (TREE_CODE (context_stack->context)) - { - case FUNCTION_DECL: - return; - case RECORD_TYPE: - case UNION_TYPE: - break; - default: - my_friendly_abort (29); - } - else - { - cadillac_printf ("start top-level enum", IDENTIFIER_POINTER (name)); - CWriteTopLevel (conn, StartMType); - } - - CWriteLanguageType (conn, type, tree_to_cadillac_map[ENUMERAL_TYPE]); -} - -void -cadillac_finish_enum (type) - tree type; -{ - Connection *conn = cadillacObj.conn; - tree name = TYPE_NAME (type); - - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - if (context_stack) - switch (TREE_CODE (context_stack->context)) - { - case FUNCTION_DECL: - return; - case RECORD_TYPE: - case UNION_TYPE: - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - break; - default: - my_friendly_abort (30); - } - else - { - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - cadillac_printf ("finish top-level enum", IDENTIFIER_POINTER (name)); - CWriteTopLevel (conn, StopMType); - } - - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_start_struct (type) - tree type; -{ - Connection *conn = cadillacObj.conn; - tree name = TYPE_NAME (type); - - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - if (context_stack) - switch (TREE_CODE (context_stack->context)) - { - case FUNCTION_DECL: - return; - case RECORD_TYPE: - case UNION_TYPE: - return; - default: - my_friendly_abort (31); - } - else - { - cadillac_printf ("start struct", IDENTIFIER_POINTER (name)); - CWriteTopLevel (conn, StartMType); - } - - context_stack = push_context_level (context_stack, &cadillac_obstack); - context_stack->context = type; - - CWriteLanguageType (conn, type, - TYPE_LANG_SPECIFIC (type) && CLASSTYPE_DECLARED_CLASS (type) ? ClassOType : tree_to_cadillac_map[TREE_CODE (type)]); -} - -void -cadillac_finish_struct (type) - tree type; -{ - Connection *conn = cadillacObj.conn; - tree name = TYPE_NAME (type); - - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - context_stack = pop_context_level (context_stack); - if (context_stack) - return; - - cadillac_printf ("finish struct", IDENTIFIER_POINTER (name)); - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - CWriteTopLevel (conn, StopMType); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_finish_exception (type) - tree type; -{ - Connection *conn = cadillacObj.conn; - - fatal ("cadillac_finish_exception"); - CWriteHeader (conn, EndDefMType, 0); - CWriteLength (conn); - CWriteTopLevel (conn, StopMType); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_push_class (type) - tree type; -{ -} - -void -cadillac_pop_class () -{ -} - -void -cadillac_push_lang (name) - tree name; -{ - Connection *conn = cadillacObj.conn; - CLinkLanguageType m; - - if (name == lang_name_cplusplus) - m = LinkCPlus; - else if (name == lang_name_c) - m = LinkC; - else - my_friendly_abort (32); - CWriteHeader (conn, ForeignLinkageMType, m); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_pop_lang () -{ - Connection *conn = cadillacObj.conn; - - CWriteHeader (conn, ForeignLinkageMType, LinkPop); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_finish_stmt () -{ -} - -void -cadillac_note_source () -{ - cadillacObj.lineno = lineno; - cadillacObj.filename = input_filename; -} - -static void -CWriteTopLevel (conn, m) - Connection *conn; - CMessageSubType m; -{ - static context_id = 0; - CWriteHeader (conn, TopLevelFormMType, m); - cadillac_note_filepos (); - - /* Eventually, this will point somewhere into the digest file. */ - context_id += 1; - CWriteSomething (conn, &context_id, sizeof (BITS32)); - - CWriteSomething (conn, &cadillacObj.iflevel, sizeof (BITS32)); - CWriteLength (conn); -} - -static void -cadillac_note_filepos () -{ - extern FILE *finput; - int pos = ftell (finput); - CWriteSomething (cadillacObj.conn, &pos, sizeof (BITS32)); -} - -void -cadillac_switch_source (startflag) - int startflag; -{ - Connection *conn = cadillacObj.conn; - /* Send out the name of the source file being compiled. */ - - CWriteHeader (conn, SourceFileMType, startflag ? StartMType : StopMType); - CWriteSomething (conn, &cadillacObj.depth, sizeof (BITS16)); - CWriteVstring0 (conn, input_filename); - CWriteLength (conn); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -void -cadillac_push_source () -{ - cadillacObj.depth += 1; - cadillac_switch_source (1); -} - -void -cadillac_pop_source () -{ - cadillacObj.depth -= 1; - cadillac_switch_source (0); -} - -struct cadillac_mdep -{ - short object_type; - char linkage; - char access; - short length; -}; - -static void -CWriteLanguageElem (conn, p, name) - Connection *conn; - struct cadillac_mdep *p; - char *name; -{ - CWriteSomething (conn, &p->object_type, sizeof (BITS16)); - CWriteSomething (conn, &p->linkage, sizeof (BITS8)); - CWriteSomething (conn, &p->access, sizeof (BITS8)); - CWriteSomething (conn, &p->length, sizeof (BITS16)); - CWriteVstring0 (conn, name); - -#if 0 - /* Don't write date_type. */ - CWriteVstring0 (conn, ""); -#endif - CWriteLength (conn); -} - -static void -CWriteLanguageDecl (conn, decl, object_type) - Connection *conn; - tree decl; - CObjectType object_type; -{ - struct cadillac_mdep foo; - tree name; - - CWriteHeader (conn, LanguageElementMType, StartDefineMType); - foo.object_type = object_type; - if (decl_type_context (decl)) - { - foo.linkage = ParentLinkage; - if (TREE_PRIVATE (decl)) - foo.access = PrivateAccess; - else if (TREE_PROTECTED (decl)) - foo.access = ProtectedAccess; - else - foo.access = PublicAccess; - } - else - { - if (TREE_PUBLIC (decl)) - foo.linkage = GlobalLinkage; - else - foo.linkage = FileLinkage; - foo.access = PublicAccess; - } - name = DECL_NAME (decl); - foo.length = IDENTIFIER_LENGTH (name); - - CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -static void -CWriteLanguageType (conn, type, object_type) - Connection *conn; - tree type; - CObjectType object_type; -{ - struct cadillac_mdep foo; - tree name = TYPE_NAME (type); - - CWriteHeader (conn, LanguageElementMType, StartDefineMType); - foo.object_type = object_type; - if (current_class_type) - { - foo.linkage = ParentLinkage; - if (TREE_PRIVATE (type)) - foo.access = PrivateAccess; - else if (TREE_PROTECTED (type)) - foo.access = ProtectedAccess; - else - foo.access = PublicAccess; - } - else - { - foo.linkage = NoLinkage; - foo.access = PublicAccess; - } - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - foo.length = IDENTIFIER_LENGTH (name); - - CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -static void -CWriteUseObject (conn, type, object_type, use) - Connection *conn; - tree type; - CObjectType object_type; - CMessageSubType use; -{ - struct cadillac_mdep foo; - tree name = NULL_TREE; - - CWriteHeader (conn, LanguageElementMType, use); - foo.object_type = object_type; - if (current_class_type) - { - foo.linkage = ParentLinkage; - if (TREE_PRIVATE (type)) - foo.access = PrivateAccess; - else if (TREE_PROTECTED (type)) - foo.access = ProtectedAccess; - else - foo.access = PublicAccess; - } - else - { - foo.linkage = NoLinkage; - foo.access = PublicAccess; - } - switch (TREE_CODE (type)) - { - case VAR_DECL: - case FIELD_DECL: - case TYPE_DECL: - case CONST_DECL: - case FUNCTION_DECL: - name = DECL_NAME (type); - break; - - default: - my_friendly_abort (33); - } - - foo.length = IDENTIFIER_LENGTH (name); - - CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); - CWriteRequestBuffer (conn); - cadillac_process_requests (conn); -} - -/* Here's how we exit under cadillac. */ - -static void -exit_cadillac () -{ - extern int errorcount; - - Connection *conn = cadillacObj.conn; - - if (flag_cadillac) - { - CCompilerMessage *req; - - CWriteHeader (conn, FinishedMType, - errorcount ? 0 : CsObjectWritten | CsComplete); - /* Bye, bye! */ - CWriteRequestBuffer (conn); - - /* Block on read. */ - while (! readable_p (cadillacObj.fd_input)) - { - if (exiting) - my_friendly_abort (34); - exiting = 1; - } - exiting = 1; - - req = CReadCompilerMessage (conn); - cadillac_process_request (&cadillacObj, req); - } -} - -#else -/* Stubs. */ -void init_cadillac () {} -void cadillac_start () {} -void cadillac_start_decl (decl) - tree decl; -{} -void -cadillac_finish_decl (decl) - tree decl; -{} -void -cadillac_start_function (fndecl) - tree fndecl; -{} -void -cadillac_finish_function (fndecl) - tree fndecl; -{} -void -cadillac_finish_anon_union (decl) - tree decl; -{} -void -cadillac_start_enum (type) - tree type; -{} -void -cadillac_finish_enum (type) - tree type; -{} -void -cadillac_start_struct (type) - tree type; -{} -void -cadillac_finish_struct (type) - tree type; -{} -void -cadillac_finish_exception (type) - tree type; -{} -void -cadillac_push_class (type) - tree type; -{} -void -cadillac_pop_class () -{} -void -cadillac_push_lang (name) - tree name; -{} -void -cadillac_pop_lang () -{} -void -cadillac_note_source () -{} -void -cadillac_finish_stmt () -{} -void -cadillac_switch_source () -{} -void -cadillac_push_source () -{} -void -cadillac_pop_source () -{} -#endif diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-except.c b/gnu/usr.bin/gcc2/cc1plus/cp-except.c deleted file mode 100644 index 0de41f51bed..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-except.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* Handle exceptional things in C++. - Copyright (C) 1989, 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-except.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -/* High-level class interface. */ - -#include "config.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" -/* On Suns this can get you to the right definition if you - set the right value for TARGET. */ -#include -#ifdef sequent -/* Can you believe they forgot this? */ -#define _JBLEN 11 -#endif - -#ifndef _JBLEN -#define _JBLEN (sizeof(jmp_buf)/sizeof(int)) -#endif - -#undef NULL -#define NULL (char *)0 - -/* This should be part of `ansi_opname', or at least be defined by the std. */ -#define EXCEPTION_NAME_PREFIX "__ex" -#define EXCEPTION_NAME_LENGTH 4 - -void init_exception_processing (); -void init_exception_processing_1 (); - -/* If non-zero, a VAR_DECL whose cleanup will cause a throw to the - next exception handler. Its value says whether to throw or not. - In the case of functions which do not issue a RAISE, it should be - possible to optimize away this VAR_DECL (and overhead associated - with it). */ -tree exception_throw_decl; -/* Use this to know that we did not set `exception_throw_decl', - until GCC optimizer is smart enough to figure it out for itself. */ -int sets_exception_throw_decl; - -/* The exception `type' currently in scope, or NULL_TREE if none. */ -tree current_exception_type; - -/* The exception handler object for the given scope. */ -tree current_exception_decl; -rtx current_exception_name_as_rtx; -rtx current_exception_parms_as_rtx; - -/* The ``object'' view of the current exception parameters. - We cast up from the `parms' field to `current_exception_type'. */ -tree current_exception_object; - -/* Cache `setjmp', `longjmp', `raise_exception', and `unhandled_exception' - after default conversion. Maybe later they will get built-in. */ -static tree BISJ, BILJ, BIR, BIUE; - -/* Local variables which give the appearance that exception - handling is part of the language and the execution model. */ - -/* The type of the exception handler stack. */ -static tree EHS_type; - -/* The global handler stack. */ -tree EHS_decl; - -/* Cached component refs to fields of `EHS_decl'. */ -static tree EHS_prev, EHS_handler, EHS_parms, EHS_name; -static rtx EHS_parms_as_rtx, EHS_name_as_rtx; - -/* The parameter names of this exception type. */ - -static tree last_exception_fields; -static tree last_exception_field_types; - -/* When ID is VOID_TYPE_NODE, it means ``raise all''. - Cannot be inline, since it uses `alloca', and that - breaks code which pushes the result of this function - on the stack. */ -static tree -exception_object_name (prefix, id) - tree prefix; - tree id; -{ - /* First, cons up the `name' of this exception. */ - char *name; - int length = (id == void_type_node ? 3 : IDENTIFIER_LENGTH (id)) + EXCEPTION_NAME_LENGTH; - - if (prefix) - length += IDENTIFIER_LENGTH (prefix) + 2; - - name = (char *)alloca (length); - strcpy (name, EXCEPTION_NAME_PREFIX); - length = EXCEPTION_NAME_LENGTH; - if (prefix) - { - strcpy (name + length, IDENTIFIER_POINTER (prefix)); -#ifdef JOINER - name[length + IDENTIFIER_LENGTH (prefix)] = JOINER; -#else - name[length + IDENTIFIER_LENGTH (prefix)] = '_'; -#endif - length += IDENTIFIER_LENGTH (prefix) + 1; - } - if (id == void_type_node) - strcpy (name + length, "all"); - else - strcpy (name + length, IDENTIFIER_POINTER (id)); - return get_identifier (name); -} - -tree -lookup_exception_cname (ctype, cname, raise_id) - tree ctype, cname; - tree raise_id; -{ - tree this_cname = TREE_PURPOSE (raise_id); - if (this_cname == NULL_TREE) - { - if (cname) - { - tree name = TREE_VALUE (raise_id); - if (purpose_member (name, CLASSTYPE_TAGS (ctype))) - this_cname = cname; - } - } - else if (this_cname == void_type_node) - this_cname = NULL_TREE; - else if (TREE_CODE (this_cname) != IDENTIFIER_NODE) - { - sorry ("multiple scope refs in `cplus_expand_raise_stmt'"); - this_cname = error_mark_node; - } - return this_cname; -} - -tree -lookup_exception_tname (oname) - tree oname; -{ - return get_identifier (IDENTIFIER_POINTER (oname) + EXCEPTION_NAME_LENGTH); -} - -tree -lookup_exception_object (cname, name, complain) - tree cname, name; - int complain; -{ - tree oname; - tree decl; - - if (cname == void_type_node) - cname = NULL_TREE; - else if (cname && TREE_CODE (cname) != IDENTIFIER_NODE) - { - sorry ("multiple scope refs in `lookup_exception_object'"); - cname = NULL_TREE; - } - oname = exception_object_name (cname, name); - decl = IDENTIFIER_GLOBAL_VALUE (oname); - if (decl == NULL_TREE || TREE_CODE (decl) != VAR_DECL) - { - if (complain) - { - push_obstacks_nochange (); - - if (cname) - error ("no exception name object for name `%s::%s'", - IDENTIFIER_POINTER (cname), - IDENTIFIER_POINTER (name)); - else - error ("no exception name object for name `%s'", - IDENTIFIER_POINTER (name)); - end_temporary_allocation (); - /* Avoid further error messages. */ - pushdecl_top_level (build_lang_field_decl (VAR_DECL, - exception_object_name (cname, name), - error_mark_node)); - pop_obstacks (); - } - return NULL_TREE; - } - return decl; -} - -tree -lookup_exception_type (ctype, cname, raise_id) - tree ctype, cname; - tree raise_id; -{ - tree name = TREE_VALUE (raise_id); - tree purpose = TREE_PURPOSE (raise_id); - - if (cname && purpose == NULL_TREE) - purpose = cname; - - if (purpose && purpose != void_type_node) - { - tree link = NULL_TREE; - - if (TREE_CODE (purpose) != IDENTIFIER_NODE) - { - sorry ("multiple scope refs in `lookup_exception_type'"); - TREE_PURPOSE (raise_id) = NULL_TREE; - return NULL_TREE; - } - if (! is_aggr_typedef (purpose, 1)) - return NULL_TREE; - ctype = IDENTIFIER_TYPE_VALUE (purpose); - link = purpose_member (name, CLASSTYPE_TAGS (ctype)); - if (link) - return TREE_VALUE (link); - } - - ctype = lookup_name (name, 1); - if (ctype && TREE_CODE (ctype) == TYPE_DECL) - ctype = TREE_TYPE (ctype); - if (ctype && TREE_CODE (ctype) == RECORD_TYPE - && CLASSTYPE_DECLARED_EXCEPTION (ctype)) - return ctype; - return NULL_TREE; -} - -tree -finish_exception (e, list_of_fieldlists) - tree e; - tree list_of_fieldlists; -{ - tree parmtypes = NULL_TREE, name_field; - tree cname = TYPE_NAME (e); - - if (TREE_CODE (cname) == TYPE_DECL) - cname = DECL_NAME (cname); - - if (last_exception_fields) - error ("cannot declare exceptions within exceptions"); - if (list_of_fieldlists && ! ANON_AGGRNAME_P (cname)) - error_with_aggr_type (e, "exception name `%s' must follow body declaration"); - if (list_of_fieldlists) - { - tree prev, field; - - /* Note: no public, private, or protected allowed. */ - if (TREE_CHAIN (list_of_fieldlists)) - error ("visibility declarations invalid in exception declaration"); - else if (TREE_PURPOSE (list_of_fieldlists) != (tree)visibility_default) - error ("visibility declarations invalid in exception declaration"); - TREE_PURPOSE (list_of_fieldlists) = (tree)visibility_default; - - /* Note also: no member function declarations allowed. */ - for (prev = 0, field = TREE_VALUE (list_of_fieldlists); - field; prev = field, field = TREE_CHAIN (field)) - { - switch (TREE_CODE (field)) - { - case FIELD_DECL: - /* ok. */ - parmtypes = tree_cons (NULL_TREE, TREE_TYPE (field), parmtypes); - continue; - case FUNCTION_DECL: - error_with_decl (field, "declaration of function `%s' in exception invalid"); - break; - case VAR_DECL: - if (TREE_STATIC (field)) - error_with_decl (field, "declaration of static variable `%s' in exception invalid"); - else - error_with_decl (field, "declaration of constant field `%s' in exception invalid"); - break; - case CONST_DECL: - error_with_decl (field, "declaration of enum value `%s' in exception invalid"); - break; - case SCOPE_REF: - error ("use of `::' in exception context invalid"); - break; - } - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (field); - else - TREE_VALUE (list_of_fieldlists) = TREE_CHAIN (field); - } - } - - /* Now that we've cleaned up the fields, add a name identifier at front. */ - name_field = build_lang_field_decl (FIELD_DECL, get_identifier ("__name"), - ptr_type_node); - if (list_of_fieldlists) - { - TREE_CHAIN (name_field) = TREE_VALUE (list_of_fieldlists); - TREE_VALUE (list_of_fieldlists) = name_field; - } - else - list_of_fieldlists = build_tree_list (NULL_TREE, name_field); - - last_exception_fields = TREE_VALUE (list_of_fieldlists); - if (parmtypes) - { - last_exception_field_types = nreverse (parmtypes); - /* Set the TREE_CHAIN of what is now at the end of the - list to `void_list_node'. */ - TREE_CHAIN (parmtypes) = void_list_node; - } - else - last_exception_field_types = void_list_node; - - popclass (0); - -#if 0 - /* Remove aggregate types from the list of tags, - since these appear at global scope. */ - while (x && IS_AGGR_TYPE (TREE_VALUE (x))) - x = TREE_CHAIN (x); - CLASSTYPE_TAGS (t) = x; - y = x; - while (x) - { - if (IS_AGGR_TYPE (TREE_VALUE (x))) - TREE_CHAIN (y) = TREE_CHAIN (x); - x = TREE_CHAIN (x); - } -#endif - - if (flag_cadillac) - cadillac_finish_exception (e); - - return e; -} - -void -finish_exception_decl (cname, decl) - tree cname, decl; -{ - /* In cp-decl.h. */ - extern tree last_function_parms; - - /* An exception declaration. */ - tree t, ctor; - tree parmdecls = NULL_TREE, fields; - tree list_of_fieldlists = temp_tree_cons (NULL_TREE, - copy_list (last_exception_fields), - NULL_TREE); - tree edecl = build_lang_field_decl (VAR_DECL, - exception_object_name (cname, DECL_NAME (decl)), - ptr_type_node); - - DECL_LANGUAGE (edecl) = lang_c; - TREE_STATIC (edecl) = 1; - TREE_PUBLIC (edecl) = 1; - finish_decl (pushdecl (edecl), NULL_TREE, NULL_TREE, 0); - - /* Now instantiate the exception decl. */ - t = xref_tag (exception_type_node, DECL_NAME (decl), NULL_TREE); - - /* finish_struct will pop this. */ - pushclass (t, 0); - - /* Now add a constructor which takes as parameters all the types we - just defined. */ - ctor = build_lang_decl (FUNCTION_DECL, DECL_NAME (decl), - build_cplus_method_type (t, TYPE_POINTER_TO (t), - last_exception_field_types)); - /* Don't take `name'. The constructor handles that. */ - fields = TREE_CHAIN (TREE_VALUE (list_of_fieldlists)); - while (fields) - { - tree parm = build_decl (PARM_DECL, DECL_NAME (fields), TREE_TYPE (fields)); - /* Since there is a prototype, args are passed in their own types. */ - DECL_ARG_TYPE (parm) = TREE_TYPE (parm); -#ifdef PROMOTE_PROTOTYPES - if (TREE_CODE (TREE_TYPE (fields)) == INTEGER_TYPE - && TYPE_PRECISION (TREE_TYPE (fields)) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (parm) = integer_type_node; -#endif - TREE_CHAIN (parm) = parmdecls; - parmdecls = parm; - fields = TREE_CHAIN (fields); - } - fields = TREE_VALUE (list_of_fieldlists); - last_function_parms = nreverse (parmdecls); - - DECL_CONSTRUCTOR_P (ctor) = 1; - TYPE_HAS_CONSTRUCTOR (t) = 1; - grokclassfn (t, DECL_NAME (decl), ctor, NO_SPECIAL, NULL_TREE); - DECL_EXTERNAL (ctor) = 1; - TREE_STATIC (ctor) = 1; - TREE_PUBLIC (ctor) = 0; - DECL_INLINE (ctor) = 1; - make_decl_rtl (ctor, NULL_PTR, 1); - finish_decl (ctor, NULL_TREE, NULL_TREE, 0); - TREE_CHAIN (ctor) = TREE_VALUE (list_of_fieldlists); - TREE_VALUE (list_of_fieldlists) = ctor; - - finish_struct (t, list_of_fieldlists, 0); - - if (current_function_decl) - error ("cannot define exception inside function scope"); - else - { - enum debug_info_type old_write_symbols = write_symbols; - write_symbols = NO_DEBUG; - - /* Now build the constructor for this exception. */ - parmdecls = DECL_ARGUMENTS (ctor); - start_function (NULL_TREE, ctor, 0, 1); - store_parm_decls (); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - - /* Move all the parameters to the fields, skipping `this'. */ - parmdecls = TREE_CHAIN (parmdecls); - /* Install `name' of this exception handler. */ - DECL_INITIAL (fields) = build_unary_op (ADDR_EXPR, edecl, 0); - fields = TREE_CHAIN (fields); - /* Install all the values. */ - while (fields) - { - /* Set up the initialization for this field. */ - DECL_INITIAL (fields) = parmdecls; - fields = TREE_CHAIN (fields); - parmdecls = TREE_CHAIN (parmdecls); - } - emit_base_init (t, 0); - - finish_function (DECL_SOURCE_LINE (ctor), 1); - write_symbols = old_write_symbols; - } -} - -void -end_exception_decls () -{ - last_exception_field_types = NULL_TREE; - last_exception_fields = NULL_TREE; -} - -/* Statement-level exception semantics. */ - -void -cplus_expand_start_try (implicit) - int implicit; -{ - tree call_to_setjmp; - tree handler, ref; - - /* Start a new block enclosing the whole handler. */ - if (implicit) - { - pushlevel_temporary (1); - } - else - { - pushlevel (0); - clear_last_expr (); - push_momentary (); - - /* Encompass whole exception handler in one big binding contour. - If RAISE should throw out of the whole TRY/EXCEPT block, call - `expand_start_bindings' with argument of 1. */ - expand_start_bindings (0); - } - - /* Allocate handler in that block. It's real name will come later. - Note that it will be the first name in this binding contour. */ - handler = get_temp_name (EHS_type, 0); - DECL_INITIAL (handler) = error_mark_node; - finish_decl (handler, NULL_TREE, NULL_TREE, 0); - - /* Must come after call to `finish_decl', else the cleanup for the temp - for the handler will cause the contour we just created to be popped. */ - if (implicit) - declare_implicit_exception (); - - /* Catch via `setjmp'. */ - ref = build_component_ref (handler, get_identifier ("handler"), NULL_TREE, 0); - call_to_setjmp = build_function_call (BISJ, build_tree_list (NULL_TREE, ref)); - - /* RAISE throws to EXCEPT part. */ - expand_start_try (build_binary_op (EQ_EXPR, call_to_setjmp, integer_zero_node, 1), 0, 1); -} - -/* If KEEP is 1, then declarations in the TRY statement are worth keeping. - If KEEP is 2, then the TRY statement was generated by the compiler. - If KEEP is 0, the declarations in the TRY statement contain errors. */ - -tree -cplus_expand_end_try (keep) - int keep; -{ - tree decls, decl, block; - - if (keep < 2) - pop_implicit_try_blocks (NULL_TREE); - - decls = getdecls (); - - /* Emit code to avoid falling through into a default - handler that might come later. */ - expand_end_try (); - - /* Pops binding contour local to TRY, and get the exception handler - object built by `...start_try'. */ - switch (keep) - { - case 0: - expand_end_bindings (decls, 0, 1); - block = poplevel (0, 0, 0); - pop_momentary (); - decl = getdecls (); - break; - - case 1: - expand_end_bindings (decls, 1, 1); - block = poplevel (1, 1, 0); - pop_momentary (); - decl = getdecls (); - break; - - default: - decl = tree_last (decls); - block = NULL_TREE; - break; - } - - my_friendly_assert (TREE_CODE (decl) == VAR_DECL - && TREE_TYPE (decl) == EHS_type, 203); - if (block) - { - BLOCK_HANDLER_BLOCK (block) = 1; - TREE_USED (block) = 1; - } - - /* Pass it back so that its rtl can be bound to its name - (or vice versa). */ - return decl; -} - -void -cplus_expand_start_except (name, decl) - tree name, decl; -{ - int yes; - tree tmp, init; - - expand_start_except (0, 1); - - /* This is internal `eh'. */ - current_exception_decl = decl; - current_exception_name_as_rtx - = expand_expr (build (COMPONENT_REF, ptr_type_node, - current_exception_decl, TREE_OPERAND (EHS_name, 1)), - 0, 0, 0); - init = build (COMPONENT_REF, ptr_type_node, decl, TREE_OPERAND (EHS_parms, 1)); - current_exception_parms_as_rtx = expand_expr (init, 0, 0, 0); - - if (name) - { - /* Get the exception object into scope (user declared `ex'). */ - tmp = pushdecl (build_decl (VAR_DECL, name, ptr_type_node)); - DECL_INITIAL (tmp) = error_mark_node; - finish_decl (tmp, init, 0, 0); - } - current_exception_type = NULL_TREE; - yes = suspend_momentary (); - if (name) - { - /* From now on, send the user to our faked-up object. */ - current_exception_object = build1 (INDIRECT_REF, void_type_node, tmp); - IDENTIFIER_LOCAL_VALUE (name) = current_exception_object; - } - resume_momentary (yes); - - /* Pop exception handler stack. */ - expand_assignment (EHS_decl, EHS_prev, 0, 0); -} - -/* Generate the call to `unhandled_exception' that is appropriate - for this particular unhandled exception. */ -static tree -call_to_unhandled_exception () -{ - extern int lineno; - extern tree combine_strings (); - tree parms = tree_cons (NULL_TREE, - combine_strings (build_string (strlen (input_filename + 1), input_filename)), - build_tree_list (NULL_TREE, build_int_2 (lineno, 0))); - return build_function_call (BIUE, parms); -} - -/* Note that this must be mirror image of `...start_try'. - DFAULT is the default clause, if there was one. - DFAULT is ERROR_MARK_NODE when this ends an implicit handler. */ -void -cplus_expand_end_except (dfault) - tree dfault; -{ - extern tree expand_end_except (); /* stmt.c. */ - tree decls, raised; - - if (dfault == NULL_TREE) - { - /* Uncaught exception at outermost level. If raised locally, - reraise the exception. Otherwise, generate code to call `abort'. */ - if (in_try_block (1) == 0) - { - expand_start_cond (build (EQ_EXPR, integer_type_node, - exception_throw_decl, integer_zero_node), 0); - expand_expr (call_to_unhandled_exception (), 0, VOIDmode, 0); - expand_end_cond (); - } - /* Try the next handler. */ - if (! expand_escape_except ()) - compiler_error ("except nesting botch"); - } - - raised = expand_end_except (); - - decls = getdecls (); - expand_end_bindings (decls, decls != 0, 1); - poplevel (decls != 0, 1, 0); - - /* Implicit handlers do not use the momentary obstack. */ - if (dfault != error_mark_node) - pop_momentary (); - - if (! in_try_block (1)) - { - /* Check that this function is not raising exceptions - it is not supposed to. */ - while (raised) - { - error_with_decl (TREE_VALUE (raised), "exception `%s' raised but not declared raisable"); - raised = TREE_CHAIN (raised); - } - } - else if (dfault == NULL_TREE || dfault == error_mark_node) - { - expand_start_cond (build (NE_EXPR, integer_type_node, - exception_throw_decl, - integer_zero_node), 0); - /* We fell off the end of this try block. Try going to the next. - The escape_label will be the beginning of the next try block. */ - if (! expand_escape_except ()) - compiler_error ("except nesting botch"); - expand_end_cond (); - } -} - -/* Generate code to raise exception RAISE_ID. - If EXP is NULL_TREE, then PARMS is the list of parameters to use - for constructing this exception. - If EXP is non-NULL, then it is an already constructed object - of the kind that we want. - - FOR_RERAISE is non-zero if this raise is called by reraise. In - this case we do not need to emit extra gotos to avoid warning messages; - the caller will do that once after all the exceptions it reraises - are handled and raised. */ -void -cplus_expand_raise (raise_id, parms, exp, for_reraise) - tree raise_id; - tree parms; - tree exp; - int for_reraise; -{ - /* Allocate new exception of appropriate type, passing - PARMS to its constructor. */ - tree cname, name; - tree decl; - tree xexp = exp; - - cname = lookup_exception_cname (current_class_type, current_class_name, raise_id); - if (cname == error_mark_node) - return; - name = TREE_VALUE (raise_id); - - decl = lookup_exception_object (cname, name, 1); - if (decl == NULL_TREE) - return; - - if (exp == NULL_TREE) - { - exp = build_method_call (NULL_TREE, name, parms, NULL_TREE, LOOKUP_COMPLAIN); - if (exp == error_mark_node) - return; - } - - if (in_try_block (1)) - { - expand_raise (decl); - } - else if (! current_function_decl) - { - if (xexp == NULL_TREE) - error_with_decl (decl, "invalid raise of `%s' outside of functions"); - else - error_with_decl (decl, "invalid reraise of `%s' outside of functions"); - } - else - { - /* Test this raise against what this function permits. */ - tree names = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)); - while (names) - { - if (decl == TREE_TYPE (names)) - break; - names = TREE_CHAIN (names); - } - if (names == NULL_TREE) - { - error ("current function not declared to raise exception `%s'", - IDENTIFIER_POINTER (name)); - return; - } - } - - store_expr (exp, EHS_parms_as_rtx, 0); - - /* Set the global exception handler stack's NAME field - to the `name' of this exception. The global exception - handler stack is the container for the exception object - we just built. - - We go through a function call to make life easier when debugging. */ -#if 0 - expand_assignment (EHS_name, build_unary_op (ADDR_EXPR, decl, 0), 0, 0); -#else - parms = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, EHS_name, 0), - build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, decl, 0))); - expand_expr (build_function_call (BIR, parms), 0, 0, 0); -#endif - - /* Activate thrower. If we are inside a TRY statement, - we can cheat and not do this, saving a longjmp. */ - if (in_try_block (1) == 0) - { - sets_exception_throw_decl = 1; - emit_move_insn (DECL_RTL (exception_throw_decl), const1_rtx); - } - - if (xexp == NULL_TREE) - { - /* Invoke destructors for current procedure or handler. */ - if (! expand_escape_except ()) - compiler_error ("except nesting botch"); - /* Throw via `longjmp'... Done as side-effect of goto. */ - } - /* To avoid spurious warning messages, we add a goto to the end - of the function. This code is dead, and the compiler should - know how to delete it, but for now, we are stuck with it. */ - if (! for_reraise - && TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node) - expand_null_return (); -} - -extern tree cplus_exception_name (); - -tree -ansi_exception_object_lookup (type) - tree type; -{ - tree raise_id = cplus_exception_name (type); - tree decl; - - decl = IDENTIFIER_GLOBAL_VALUE (raise_id); - if (decl == NULL_TREE || TREE_CODE (decl) != VAR_DECL) - { - push_obstacks_nochange (); - end_temporary_allocation (); - decl = build_decl (VAR_DECL, raise_id, ptr_type_node); - TREE_PUBLIC (decl) = 1; - TREE_STATIC (decl) = 1; - pushdecl_top_level (decl); - make_decl_rtl (decl, (char*)0, 1); - pop_obstacks (); - } - return decl; -} - -/* Generate code to throw an exception using EXP. - Usng ANSI syntax and semantics. - If EXP is NULL_TREE< re-raise instead. */ - -void -cplus_expand_throw (exp) - tree exp; -{ - tree parms; - int for_reraise; - /* Allocate new exception of appropriate type, passing - PARMS to its constructor. */ - tree decl = ansi_exception_object_lookup (TREE_TYPE (exp)); - tree xexp = exp; - - if (in_try_block (1)) - { -#if 1 - my_friendly_abort (35); -#else - expand_raise (decl); -#endif - } - else if (! current_function_decl) - error ("invalid throw outside of functions"); - else - { -#if 0 - /* Test this raise against what this function permits. */ - tree names = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)); - while (names) - { - if (decl == TREE_TYPE (names)) - break; - names = TREE_CHAIN (names); - } - if (names == NULL_TREE) - { - error ("current function not declared to raise exception `%s'", - IDENTIFIER_POINTER (name)); - return; - } -#endif - } - - store_expr (exp, EHS_parms_as_rtx, 0); - - /* Set the global exception handler stack's NAME field - to the `name' of this exception. The global exception - handler stack is the container for the exception object - we just built. - - We go through a function call to make life easier when debugging. */ -#if 0 - expand_assignment (EHS_name, build_unary_op (ADDR_EXPR, decl, 0), 0, 0); -#else - parms = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, EHS_name, 0), - build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, decl, 0))); - expand_expr (build_function_call (BIR, parms), 0, 0, 0); -#endif - - /* Activate thrower. If we are inside a TRY statement, - we can cheat and not do this, saving a longjmp. */ - if (in_try_block (1) == 0) - { - sets_exception_throw_decl = 1; - emit_move_insn (DECL_RTL (exception_throw_decl), const1_rtx); - } - - if (xexp == NULL_TREE) - { - /* Invoke destructors for current procedure or handler. */ - if (! expand_escape_except ()) - compiler_error ("except nesting botch"); - /* Throw via `longjmp'... Done as side-effect of goto. */ - } - - /* XXX: for_reraise is never set above here. */ - /* To avoid spurious warning messages, we add a goto to the end - of the function. This code is dead, and the compiler should - know how to delete it, but for now, we are stuck with it. */ - if (! for_reraise - && TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node) - expand_null_return (); -} - -tree -cplus_expand_start_catch (raise_id) - tree raise_id; -{ - tree cname = lookup_exception_cname (current_class_type, current_class_name, raise_id); - tree decl; - tree cond; - - if (cname == error_mark_node) - { - decl = error_mark_node; - cond = error_mark_node; - } - else - { - decl = lookup_exception_object (cname, TREE_VALUE (raise_id), 1); - if (decl == NULL_TREE) - cond = error_mark_node; - else - cond = build_binary_op (EQ_EXPR, build_unary_op (ADDR_EXPR, decl, 0), - build (COMPONENT_REF, ptr_type_node, - current_exception_decl, - TREE_OPERAND (EHS_name, 1)), - 1); - } - expand_start_cond (cond, 0); - - /* Does nothing right now. */ - expand_catch (decl); - if (current_exception_type - && TYPE_NEEDS_DESTRUCTOR (current_exception_type)) - { - /* Make a cleanup for the name-specific exception object now in scope. */ - tree cleanup = maybe_build_cleanup (current_exception_object); - expand_start_bindings (0); - expand_decl_cleanup (NULL_TREE, cleanup); - } - return decl; -} -tree -ansi_expand_start_catch (raise_type) - tree raise_type; -{ - tree decl = ansi_exception_object_lookup (raise_type); - tree cond; - - if (decl == NULL_TREE) - cond = error_mark_node; - else - cond = build_binary_op (EQ_EXPR, build_unary_op (ADDR_EXPR, decl, 0), - build (COMPONENT_REF, ptr_type_node, - current_exception_decl, - TREE_OPERAND (EHS_name, 1)), - 1); - expand_start_cond (cond, 0); - - /* Does nothing right now. */ - expand_catch (decl); - return decl; -} - -void -cplus_expand_end_catch (for_reraise) - int for_reraise; -{ - if (current_exception_type - && TYPE_NEEDS_DESTRUCTOR (current_exception_type)) - { - /* Destroy the specific exception object now in scope. */ - expand_end_bindings (getdecls (), 0, 1); - } - if (for_reraise) - { - if (! expand_escape_except ()) - my_friendly_abort (36); - } - else - { - if (! expand_end_catch ()) - my_friendly_abort (37); - } - expand_end_cond (); -} - -/* Reraise an exception. - If EXCEPTIONS is NULL_TREE, it means reraise whatever exception was caught. - If EXCEPTIONS is an IDENTIFIER_NODE, it means reraise the exception - object named by EXCEPTIONS. This must be a variable declared in - an `except' clause. - If EXCEPTIONS is a TREE_LIST, it is the list of exceptions we are - willing to reraise. */ - -void -cplus_expand_reraise (exceptions) - tree exceptions; -{ - tree ex_ptr; - tree ex_object = current_exception_object; - rtx ex_ptr_as_rtx; - - if (exceptions && TREE_CODE (exceptions) == IDENTIFIER_NODE) - { - /* Don't get tripped up if its TREE_TYPE is `error_mark_node'. */ - ex_object = IDENTIFIER_LOCAL_VALUE (exceptions); - if (ex_object == NULL_TREE || TREE_CODE (ex_object) != INDIRECT_REF) - { - error ("`%s' is not an exception decl", IDENTIFIER_POINTER (exceptions)); - return; - } - my_friendly_assert (TREE_CODE (TREE_OPERAND (ex_object, 0)) == VAR_DECL, - 204); - exceptions = NULL_TREE; - } - - ex_ptr = build1 (NOP_EXPR, ptr_type_node, TREE_OPERAND (ex_object, 0)); - ex_ptr_as_rtx = expand_expr (ex_ptr, 0, 0, 0); - - /* reraise ALL, used by compiler. */ - if (exceptions == NULL_TREE) - { - /* Now treat reraise like catch/raise. */ - expand_catch (error_mark_node); - expand_raise (error_mark_node); - emit_move_insn (EHS_name_as_rtx, current_exception_name_as_rtx); - store_expr ((tree) EHS_parms_as_rtx, current_exception_parms_as_rtx, 0); - if (in_try_block (1) == 0) - { - sets_exception_throw_decl = 1; - emit_move_insn (DECL_RTL (exception_throw_decl), const1_rtx); - } - /* Set to zero so that destructor will not be called. */ - emit_move_insn (ex_ptr_as_rtx, const0_rtx); - if (! expand_escape_except ()) - my_friendly_abort (38); - - /* To avoid spurious warning messages, we add a goto to the end - of the function. This code is dead, and the compiler should - know how to delete it, but for now, we are stuck with it. */ - if (TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node) - expand_null_return (); - - return; - } - - /* reraise from a list of exceptions. */ - while (exceptions) - { - tree type = lookup_exception_type (current_class_type, current_class_name, - exceptions); - if (type == NULL_TREE) - { - error ("`%s' is not an exception type", - IDENTIFIER_POINTER (TREE_VALUE (exceptions))); - current_exception_type = NULL_TREE; - TREE_TYPE (ex_object) = error_mark_node; - TREE_TYPE (ex_ptr) = error_mark_node; - } - else - { - current_exception_type = type; - /* In-place union. */ - TREE_TYPE (ex_object) = type; - TREE_TYPE (ex_ptr) = TYPE_POINTER_TO (type); - } - - /* Now treat reraise like catch/raise. */ - cplus_expand_start_catch (exceptions); - cplus_expand_raise (exceptions, NULL_TREE, ex_ptr, 1); - /* Set to zero so that destructor will not be called. */ - if (TREE_TYPE (ex_ptr) != error_mark_node) - emit_move_insn (ex_ptr_as_rtx, const0_rtx); - cplus_expand_end_catch (1); - exceptions = TREE_CHAIN (exceptions); - } - /* Don't propagate any unhandled exceptions. */ - expand_expr (call_to_unhandled_exception (), 0, VOIDmode, 0); - - /* To avoid spurious warning messages, we add a goto to the end - of the function. This code is dead, and the compiler should - know how to delete it, but for now, we are stuck with it. */ - if (TREE_TYPE (DECL_RESULT (current_function_decl)) != void_type_node) - expand_null_return (); -} - -void -setup_exception_throw_decl () -{ - tree call_to_longjmp, parms; - - int old = suspend_momentary (); - - exception_throw_decl = build_decl (VAR_DECL, get_identifier (THROW_NAME), integer_type_node); - pushdecl (exception_throw_decl); - parms = tree_cons (NULL_TREE, EHS_handler, - build_tree_list (0, integer_one_node)); - call_to_longjmp = build_function_call (BILJ, parms); - - expand_decl (exception_throw_decl); - expand_decl_cleanup (exception_throw_decl, - build (COND_EXPR, void_type_node, - exception_throw_decl, - call_to_longjmp, integer_zero_node)); - DECL_INITIAL (exception_throw_decl) = integer_zero_node; - sets_exception_throw_decl = 0; - resume_momentary (old); - - /* Cache these, since they won't change throughout the function. */ - EHS_parms_as_rtx = expand_expr (EHS_parms, 0, 0, 0); - EHS_name_as_rtx = expand_expr (EHS_name, 0, 0, 0); -} - -void -init_exception_processing () -{ - extern tree build_function_type (), define_function (); - extern tree unhandled_exception_fndecl; - tree cname = get_identifier ("ExceptionHandler"); - tree field, chain; - tree ctor, dtor; - tree jmp_buf_type = build_array_type (integer_type_node, - build_index_type (build_int_2 (_JBLEN-1, 0))); - tree jmp_buf_arg_type = build_pointer_type (integer_type_node); - - tree parmtypes = hash_tree_chain (jmp_buf_arg_type, void_list_node); - tree setjmp_fndecl, longjmp_fndecl, raise_fndecl; - - int old_interface_only = interface_only; - int old_interface_unknown = interface_unknown; - interface_only = 1; - interface_unknown = 0; - EHS_type = xref_tag (record_type_node, cname, NULL_TREE); - push_lang_context (lang_name_c); - setjmp_fndecl = define_function ("setjmp", - build_function_type (integer_type_node, - parmtypes), - NOT_BUILT_IN, pushdecl, 0); - BISJ = default_conversion (setjmp_fndecl); - parmtypes = hash_tree_chain (jmp_buf_arg_type, - hash_tree_chain (integer_type_node, void_list_node)); - longjmp_fndecl = define_function ("longjmp", - build_function_type (void_type_node, parmtypes), - NOT_BUILT_IN, pushdecl, 0); - raise_fndecl = define_function ("__raise_exception", - build_function_type (void_type_node, - hash_tree_chain (ptr_type_node, - hash_tree_chain (build_pointer_type (ptr_type_node), void_list_node))), - NOT_BUILT_IN, pushdecl, 0); - BILJ = default_conversion (longjmp_fndecl); - BIR = default_conversion (raise_fndecl); - BIUE = default_conversion (unhandled_exception_fndecl); - - pop_lang_context (); - - /* finish_struct will pop this. */ - pushclass (EHS_type, 0); - field = build_lang_field_decl (FIELD_DECL, get_identifier ("parms"), ptr_type_node); - chain = field; - field = build_lang_field_decl (FIELD_DECL, get_identifier ("name"), - build_pointer_type (default_function_type)); - TREE_CHAIN (field) = chain; - chain = field; - field = build_lang_field_decl (FIELD_DECL, get_identifier ("handler"), jmp_buf_type); - TREE_CHAIN (field) = chain; - chain = field; - field = build_lang_field_decl (FIELD_DECL, get_identifier ("prev"), - TYPE_POINTER_TO (EHS_type)); - TREE_CHAIN (field) = chain; - chain = field; - - ctor = build_lang_decl (FUNCTION_DECL, cname, - build_cplus_method_type (EHS_type, TYPE_POINTER_TO (EHS_type), void_list_node)); - DECL_CONSTRUCTOR_P (ctor) = 1; - TREE_STATIC (ctor) = 1; - TREE_PUBLIC (ctor) = 1; - DECL_EXTERNAL (ctor) = 1; - grokclassfn (EHS_type, cname, ctor, NO_SPECIAL, 0); - grok_ctor_properties (EHS_type, ctor); - finish_decl (pushdecl (ctor), NULL_TREE, NULL_TREE, 0); - /* Must copy the node here because the FUNCTION_DECL - used inside the struct ain't the same as the - FUNCTION_DECL we stick into the global binding - contour. */ - ctor = copy_node (ctor); - TREE_CHAIN (ctor) = chain; - chain = ctor; - dtor = build_lang_decl (FUNCTION_DECL, cname, - build_cplus_method_type (EHS_type, TYPE_POINTER_TO (EHS_type), void_list_node)); - TREE_STATIC (dtor) = 1; - TREE_PUBLIC (dtor) = 1; - DECL_EXTERNAL (dtor) = 1; - grokclassfn (EHS_type, cname, dtor, DTOR_FLAG, 0); - finish_decl (pushdecl (dtor), NULL_TREE, NULL_TREE, 0); - /* Copy for the same reason as copying ctor. */ - dtor = copy_node (dtor); - TREE_CHAIN (dtor) = chain; - chain = dtor; - TYPE_HAS_CONSTRUCTOR (EHS_type) = 1; - TYPE_HAS_DESTRUCTOR (EHS_type) = 1; - finish_struct (EHS_type, temp_tree_cons (NULL_TREE, chain, NULL_TREE), 0); - interface_only = old_interface_only; - interface_unknown = old_interface_unknown; -} - -void -init_exception_processing_1 () -{ - register tree EHS_id = get_identifier ("exceptionHandlerStack"); - - EHS_decl = IDENTIFIER_GLOBAL_VALUE (EHS_id); - - /* If we have no other definition, default to library implementation. */ - if (EHS_decl == NULL_TREE) - { - EHS_decl = build_decl (VAR_DECL, EHS_id, TYPE_POINTER_TO (EHS_type)); - /* If we don't push this, its definition, should it be encountered, - will not be seen. */ - EHS_decl = pushdecl (EHS_decl); - DECL_EXTERNAL (EHS_decl) = 1; - TREE_STATIC (EHS_decl) = 1; - TREE_PUBLIC (EHS_decl) = 1; - finish_decl (EHS_decl, NULL_TREE, NULL_TREE, 0); - } - else if (TREE_CODE (EHS_decl) != VAR_DECL - || TREE_TYPE (EHS_decl) != TYPE_POINTER_TO (EHS_type)) - fatal ("exception handling declarations conflict with compiler's internal model"); - - if (EHS_prev == NULL_TREE) - { - register tree EHS_DECL = build1 (INDIRECT_REF, EHS_type, EHS_decl); - EHS_prev = build_component_ref (EHS_DECL, get_identifier ("prev"), 0, 0); - EHS_handler = build_component_ref (EHS_DECL, get_identifier ("handler"), 0, 0); - EHS_parms = build_component_ref (EHS_DECL, get_identifier ("parms"), 0, 0); - EHS_name = build_component_ref (EHS_DECL, get_identifier ("name"), 0, 0); - } -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-expr.c b/gnu/usr.bin/gcc2/cc1plus/cp-expr.c deleted file mode 100644 index bb88b0172d4..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-expr.c +++ /dev/null @@ -1,225 +0,0 @@ -/* Convert language-specific tree expression to rtl instructions, - for GNU compiler. - Copyright (C) 1988, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-expr.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -#include "config.h" -#include "rtl.h" -#include "tree.h" -#include "flags.h" -#include "expr.h" -#include "cp-tree.h" - -#undef NULL -#define NULL 0 - -/* Hook used by expand_expr to expand language-specific tree codes. */ - -rtx -cplus_expand_expr (exp, target, tmode, modifier) - tree exp; - rtx target; - enum machine_mode tmode; - enum expand_modifier modifier; -{ - tree type = TREE_TYPE (exp); - register enum machine_mode mode = TYPE_MODE (type); - register enum tree_code code = TREE_CODE (exp); - rtx original_target = target; - int ignore = target == const0_rtx; - - if (ignore) target = 0, original_target = 0; - - /* No sense saving up arithmetic to be done - if it's all in the wrong mode to form part of an address. - And force_operand won't know whether to sign-extend or zero-extend. */ - - if (mode != Pmode && modifier == EXPAND_SUM) - modifier = EXPAND_NORMAL; - - switch (code) - { - case NEW_EXPR: - { - /* Something needs to be initialized, but we didn't know - where that thing was when building the tree. For example, - it could be the return value of a function, or a parameter - to a function which lays down in the stack, or a temporary - variable which must be passed by reference. - - Cleanups are handled in a language-specific way: they - might be run by the called function (true in GNU C++ - for parameters with cleanups), or they might be - run by the caller, after the call (true in GNU C++ - for other cleanup needs). */ - - tree func = TREE_OPERAND (exp, 0); - tree args = TREE_OPERAND (exp, 1); - tree type = TREE_TYPE (exp), slot; - tree fn_type = TREE_TYPE (TREE_TYPE (func)); - tree return_type = TREE_TYPE (fn_type); - rtx call_target, return_target; - - /* The expression `init' wants to initialize what - `target' represents. SLOT holds the slot for TARGET. */ - slot = TREE_OPERAND (exp, 2); - - if (target == 0) - { - /* Should always be called with a target in BLKmode case. */ - my_friendly_assert (mode != BLKmode, 205); - my_friendly_assert (DECL_RTL (slot) != 0, 206); - - target = gen_reg_rtx (mode); - } - - /* The target the initializer will initialize (CALL_TARGET) - must now be directed to initialize the target we are - supposed to initialize (TARGET). The semantics for - choosing what CALL_TARGET is is language-specific, - as is building the call which will perform the - initialization. It is left here to show the choices that - exist for C++. */ - - if (TREE_CODE (func) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL - && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) - { - type = TYPE_POINTER_TO (type); - /* Don't clobber a value that might be part of a default - parameter value. */ - if (TREE_PERMANENT (args)) - args = tree_cons (0, build1 (ADDR_EXPR, type, slot), - TREE_CHAIN (args)); - else - TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot); - call_target = 0; - } - else if (TREE_CODE (return_type) == REFERENCE_TYPE) - { - type = return_type; - call_target = 0; - } - else - { - call_target = target; - } - if (call_target) - preserve_temp_slots (call_target); - preserve_temp_slots (DECL_RTL (slot)); - return_target = expand_expr (build (CALL_EXPR, type, func, args, 0), call_target, mode, 0); - free_temp_slots (); - if (call_target == 0) - call_target = return_target; - else if (call_target != return_target) - { - if (GET_MODE (return_target) == BLKmode) - emit_block_move (call_target, return_target, expr_size (exp), - TYPE_ALIGN (type) / BITS_PER_UNIT); - else - emit_move_insn (call_target, return_target); - } - - if (TREE_CODE (return_type) == REFERENCE_TYPE) - { - tree init; - - if (GET_CODE (call_target) == REG - && REGNO (call_target) < FIRST_PSEUDO_REGISTER) - my_friendly_abort (39); - - type = TREE_TYPE (exp); - - init = build (RTL_EXPR, return_type, 0, call_target); - /* We got back a reference to the type we want. Now initialize - target with that. */ - expand_aggr_init (slot, init, 0); - } - - if (DECL_RTL (slot) != target) - emit_move_insn (DECL_RTL (slot), target); - return DECL_RTL (slot); - } - - case OFFSET_REF: - { - tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0); - tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0); - return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset), - target, tmode, EXPAND_NORMAL); - } - - default: - break; - } - my_friendly_abort (40); - /* NOTREACHED */ - return NULL; -} - -void -init_cplus_expand () -{ - lang_expand_expr = cplus_expand_expr; -} - -/* If DECL had its rtl moved from where callers expect it - to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL, - which may be a pseudo instead of a hard register. */ - -void -fixup_result_decl (decl, result) - tree decl; - rtx result; -{ - if (REG_P (result)) - { - if (REGNO (result) >= FIRST_PSEUDO_REGISTER) - { - rtx real_decl_result; - -#ifdef FUNCTION_OUTGOING_VALUE - real_decl_result - = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl); -#else - real_decl_result - = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl); -#endif - REG_FUNCTION_VALUE_P (real_decl_result) = 1; - result = real_decl_result; - } - emit_move_insn (result, DECL_RTL (decl)); - emit_insn (gen_rtx (USE, VOIDmode, result)); - } -} - -/* Return nonzero iff DECL is memory-based. The DECL_RTL of - certain const variables might be a CONST_INT, or a REG - in some cases. We cannot use `memory_operand' as a test - here because on most RISC machines, a variable's address - is not, by itself, a legitimate address. */ -int -decl_in_memory_p (decl) - tree decl; -{ - return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM; -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-gc.c b/gnu/usr.bin/gcc2/cc1plus/cp-gc.c deleted file mode 100644 index 4bf660a8687..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-gc.c +++ /dev/null @@ -1,796 +0,0 @@ -/* Garbage collection primitives for GNU C++. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-gc.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -#include "config.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" - -#undef NULL -#define NULL 0 - -extern tree define_function (); -extern tree build_t_desc_overload (); - -/* This is the function decl for the (pseudo-builtin) __gc_protect - function. Args are (class *value, int index); Returns value. */ -tree gc_protect_fndecl; - -/* This is the function decl for the (pseudo-builtin) __gc_unprotect - function. Args are (int index); void return. */ -tree gc_unprotect_fndecl; - -/* This is the function decl for the (pseudo-builtin) __gc_push - function. Args are (int length); void return. */ -tree gc_push_fndecl; - -/* This is the function decl for the (pseudo-builtin) __gc_pop - function. Args are void; void return. */ -tree gc_pop_fndecl; - -/* Special integers that are used to represent bits in gc-safe objects. */ -tree gc_nonobject; -tree gc_visible; -tree gc_white; -tree gc_offwhite; -tree gc_grey; -tree gc_black; - -/* in c-common.c */ -extern tree combine_strings PROTO((tree)); - -/* Predicate that returns non-zero if TYPE needs some kind of - entry for the GC. Returns zero otherwise. */ -int -type_needs_gc_entry (type) - tree type; -{ - tree ttype = type; - - if (! flag_gc || type == error_mark_node) - return 0; - - /* Aggregate types need gc entries if any of their members - need gc entries. */ - if (IS_AGGR_TYPE (type)) - { - tree binfos; - tree fields = TYPE_FIELDS (type); - int i; - - /* We don't care about certain pointers. Pointers - to virtual baseclasses are always up front. We also - cull out virtual function table pointers because it's - easy, and it simplifies the logic.*/ - while (fields - && (DECL_NAME (fields) == NULL_TREE - || VFIELD_NAME_P (DECL_NAME (fields)) - || VBASE_NAME_P (DECL_NAME (fields)) - || !strcmp (IDENTIFIER_POINTER (DECL_NAME (fields)), "__bits"))) - fields = TREE_CHAIN (fields); - - while (fields) - { - if (type_needs_gc_entry (TREE_TYPE (fields))) - return 1; - fields = TREE_CHAIN (fields); - } - - binfos = TYPE_BINFO_BASETYPES (type); - if (binfos) - for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--) - if (type_needs_gc_entry (BINFO_TYPE (TREE_VEC_ELT (binfos, i)))) - return 1; - - return 0; - } - - while (TREE_CODE (ttype) == ARRAY_TYPE - && TREE_CODE (TREE_TYPE (ttype)) == ARRAY_TYPE) - ttype = TREE_TYPE (ttype); - if ((TREE_CODE (ttype) == POINTER_TYPE - || TREE_CODE (ttype) == ARRAY_TYPE - || TREE_CODE (ttype) == REFERENCE_TYPE) - && IS_AGGR_TYPE (TREE_TYPE (ttype)) - && CLASSTYPE_DOSSIER (TREE_TYPE (ttype))) - return 1; - - return 0; -} - -/* Predicate that returns non-zero iff FROM is safe from the GC. - - If TO is nonzero, it means we know that FROM is being stored - in TO, which make make it safe. */ -int -value_safe_from_gc (to, from) - tree to, from; -{ - /* First, return non-zero for easy cases: parameters, - static variables. */ - if (TREE_CODE (from) == PARM_DECL - || (TREE_CODE (from) == VAR_DECL - && TREE_STATIC (from))) - return 1; - - /* If something has its address taken, it cannot be - in the heap, so it doesn't need to be protected. */ - if (TREE_CODE (from) == ADDR_EXPR || TREE_REFERENCE_EXPR (from)) - return 1; - - /* If we are storing into a static variable, then what - we store will be safe from the gc. */ - if (to && TREE_CODE (to) == VAR_DECL - && TREE_STATIC (to)) - return 1; - - /* Now recurse on structure of FROM. */ - switch (TREE_CODE (from)) - { - case COMPONENT_REF: - /* These guys are special, and safe. */ - if (TREE_CODE (TREE_OPERAND (from, 1)) == FIELD_DECL - && (VFIELD_NAME_P (DECL_NAME (TREE_OPERAND (from, 1))) - || VBASE_NAME_P (DECL_NAME (TREE_OPERAND (from, 1))))) - return 1; - /* fall through... */ - case NOP_EXPR: - case CONVERT_EXPR: - case NON_LVALUE_EXPR: - case WITH_CLEANUP_EXPR: - case SAVE_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - if (value_safe_from_gc (to, TREE_OPERAND (from, 0))) - return 1; - break; - - case VAR_DECL: - case PARM_DECL: - /* We can safely pass these things as parameters to functions. */ - if (to == 0) - return 1; - - case ARRAY_REF: - case INDIRECT_REF: - case RESULT_DECL: - case OFFSET_REF: - case CALL_EXPR: - case METHOD_CALL_EXPR: - break; - - case COMPOUND_EXPR: - case TARGET_EXPR: - if (value_safe_from_gc (to, TREE_OPERAND (from, 1))) - return 1; - break; - - case COND_EXPR: - if (value_safe_from_gc (to, TREE_OPERAND (from, 1)) - && value_safe_from_gc (to, TREE_OPERAND (from, 2))) - return 1; - break; - - case PLUS_EXPR: - case MINUS_EXPR: - if ((type_needs_gc_entry (TREE_TYPE (TREE_OPERAND (from, 0))) - || value_safe_from_gc (to, TREE_OPERAND (from, 0))) - && (type_needs_gc_entry (TREE_TYPE (TREE_OPERAND (from, 1))) == 0 - || value_safe_from_gc (to, TREE_OPERAND (from, 1)))) - return 1; - break; - - case RTL_EXPR: - /* Every time we build an RTL_EXPR in the front-end, we must - ensure that everything in it is safe from the garbage collector. - ??? This has only been done for `build_new'. */ - return 1; - - default: - my_friendly_abort (41); - } - - if (to == 0) - return 0; - - /* FROM wasn't safe. But other properties of TO might make it safe. */ - switch (TREE_CODE (to)) - { - case VAR_DECL: - case PARM_DECL: - /* We already culled out static VAR_DECLs above. */ - return 0; - - case COMPONENT_REF: - /* These guys are special, and safe. */ - if (TREE_CODE (TREE_OPERAND (to, 1)) == FIELD_DECL - && (VFIELD_NAME_P (DECL_NAME (TREE_OPERAND (to, 1))) - || VBASE_NAME_P (DECL_NAME (TREE_OPERAND (to, 1))))) - return 1; - /* fall through... */ - - case NOP_EXPR: - case NON_LVALUE_EXPR: - case WITH_CLEANUP_EXPR: - case SAVE_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - return value_safe_from_gc (TREE_OPERAND (to, 0), from); - - case COMPOUND_EXPR: - case TARGET_EXPR: - return value_safe_from_gc (TREE_OPERAND (to, 1), from); - - case COND_EXPR: - return (value_safe_from_gc (TREE_OPERAND (to, 1), from) - && value_safe_from_gc (TREE_OPERAND (to, 2), from)); - - case INDIRECT_REF: - case ARRAY_REF: - /* This used to be 0, but our current restricted model - allows this to be 1. We'll never get arrays this way. */ - return 1; - - default: - my_friendly_abort (42); - } - - /* Catch-all case is that TO/FROM is not safe. */ - return 0; -} - -/* Function to build a static GC entry for DECL. TYPE is DECL's type. - - For objects of type `class *', this is just an entry in the - static vector __PTR_LIST__. - - For objects of type `class[]', this requires building an entry - in the static vector __ARR_LIST__. - - For aggregates, this records all fields of type `class *' - and `class[]' in the respective lists above. */ -void -build_static_gc_entry (decl, type) - tree decl; - tree type; -{ - /* Now, figure out what sort of entry to build. */ - if (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == REFERENCE_TYPE) - assemble_gc_entry (IDENTIFIER_POINTER (DECL_NAME (decl))); - else if (TREE_CODE (type) == RECORD_TYPE) - { - tree ref = get_temp_name (build_reference_type (type), 1); - DECL_INITIAL (ref) = build1 (ADDR_EXPR, TREE_TYPE (ref), decl); - TREE_CONSTANT (DECL_INITIAL (ref)) = 1; - finish_decl (ref, DECL_INITIAL (ref), 0, 0); - } - else - { - /* Not yet implemented. - - Cons up a static variable that holds address and length info - and add that to ___ARR_LIST__. */ - my_friendly_abort (43); - } -} - -/* Protect FROM from the GC, assuming FROM is going to be - stored into TO. We handle three cases for TO here: - - case 1: TO is a stack variable. - case 2: TO is zero (which means it is a parameter). - case 3: TO is a return value. */ - -tree -protect_value_from_gc (to, from) - tree to, from; -{ - if (to == 0) - { - tree cleanup; - - to = get_temp_regvar (TREE_TYPE (from), from); - - /* Convert from integer to list form since we'll use it twice. */ - DECL_GC_OFFSET (to) = build_tree_list (NULL_TREE, DECL_GC_OFFSET (to)); - cleanup = build_function_call (gc_unprotect_fndecl, - DECL_GC_OFFSET (to)); - - if (! expand_decl_cleanup (to, cleanup)) - { - compiler_error ("cannot unprotect parameter in this scope"); - return error_mark_node; - } - } - - /* Should never need to protect a value that's headed for static storage. */ - if (TREE_STATIC (to)) - my_friendly_abort (44); - - switch (TREE_CODE (to)) - { - case COMPONENT_REF: - case INDIRECT_REF: - return protect_value_from_gc (TREE_OPERAND (to, 0), from); - - case VAR_DECL: - case PARM_DECL: - { - tree rval; - if (DECL_GC_OFFSET (to) == NULL_TREE) - { - /* Because of a cast or a conversion, we might stick - a value into a variable that would not normally - have a GC entry. */ - DECL_GC_OFFSET (to) = size_int (++current_function_obstack_index); - } - - if (TREE_CODE (DECL_GC_OFFSET (to)) != TREE_LIST) - { - DECL_GC_OFFSET (to) - = build_tree_list (NULL_TREE, DECL_GC_OFFSET (to)); - } - - current_function_obstack_usage = 1; - rval = build_function_call (gc_protect_fndecl, - tree_cons (NULL_TREE, from, - DECL_GC_OFFSET (to))); - TREE_TYPE (rval) = TREE_TYPE (from); - return rval; - } - } - - /* If we fall through the switch, assume we lost. */ - my_friendly_abort (45); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Given the expression EXP of type `class *', return the head - of the object pointed to by EXP. */ -tree -build_headof (exp) - tree exp; -{ - tree type = TREE_TYPE (exp); - tree vptr, offset; - - if (TREE_CODE (type) != POINTER_TYPE) - { - error ("`headof' applied to non-pointer type"); - return error_mark_node; - } - - vptr = build1 (INDIRECT_REF, TYPE_POINTER_TO (vtable_entry_type), exp); - offset = build_component_ref (build_array_ref (vptr, integer_one_node), - get_identifier (VTABLE_DELTA_NAME), - NULL_TREE, 0); - return build (PLUS_EXPR, class_star_type_node, exp, - convert (integer_type_node, offset)); -} - -/* Given the expression EXP of type `class *', return the - type descriptor for the object pointed to by EXP. */ -tree -build_classof (exp) - tree exp; -{ - tree type = TREE_TYPE (exp); - tree vptr; - tree t_desc_entry; - - if (TREE_CODE (type) != POINTER_TYPE) - { - error ("`classof' applied to non-pointer type"); - return error_mark_node; - } - - vptr = build1 (INDIRECT_REF, TYPE_POINTER_TO (vtable_entry_type), exp); - t_desc_entry = build_component_ref (build_array_ref (vptr, integer_one_node), - get_identifier (VTABLE_PFN_NAME), - NULL_TREE, 0); - TREE_TYPE (t_desc_entry) = TYPE_POINTER_TO (__t_desc_type_node); - return t_desc_entry; -} - -/* Build and initialize various sorts of descriptors. Every descriptor - node has a name associated with it (the name created by mangling). - For this reason, we use the identifier as our access to the __*_desc - nodes, instead of sticking them directly in the types. Otherwise we - would burden all built-in types (and pointer types) with slots that - we don't necessarily want to use. - - For each descriptor we build, we build a variable that contains - the descriptor's information. When we need this info at runtime, - all we need is access to these variables. - - Note: these constructors always return the address of the descriptor - info, since that is simplest for their mutual interaction. */ - -static tree -build_generic_desc (decl, elems) - tree decl; - tree elems; -{ - tree init = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, elems); - TREE_CONSTANT (init) = 1; - TREE_STATIC (init) = 1; - TREE_READONLY (init) = 1; - - DECL_INITIAL (decl) = init; - TREE_STATIC (decl) = 1; - layout_decl (decl, 0); - finish_decl (decl, init, 0, 0); - - return IDENTIFIER_AS_DESC (DECL_NAME (decl)); -} - -/* Build an initializer for a __t_desc node. So that we can take advantage - of recursion, we accept NULL for TYPE. - DEFINITION is greater than zero iff we must define the type descriptor - (as opposed to merely referencing it). 1 means treat according to - #pragma interface/#pragma implementation rules. 2 means define as - global and public, no matter what. */ -tree -build_t_desc (type, definition) - tree type; - int definition; -{ - tree tdecl; - tree tname, name_string; - tree elems, fields; - tree parents, vbases, offsets, ivars, methods, target_type; - int method_count = 0, field_count = 0; - - if (type == NULL_TREE) - return NULL_TREE; - - tname = build_t_desc_overload (type); - if (IDENTIFIER_AS_DESC (tname) - && (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname)))) - return IDENTIFIER_AS_DESC (tname); - - tdecl = lookup_name (tname, 0); - if (tdecl == NULL_TREE) - { - tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node); - DECL_EXTERNAL (tdecl) = 1; - TREE_PUBLIC (tdecl) = 1; - tdecl = pushdecl_top_level (tdecl); - } - /* If we previously defined it, return the defined result. */ - else if (definition && DECL_INITIAL (tdecl)) - return IDENTIFIER_AS_DESC (tname); - - if (definition) - { - tree taggr = type; - /* Let T* and T& be written only when T is written (if T is an aggr). - We do this for const, but not for volatile, since volatile - is rare and const is not. */ - if (!TYPE_VOLATILE (taggr) - && (TREE_CODE (taggr) == POINTER_TYPE - || TREE_CODE (taggr) == REFERENCE_TYPE) - && IS_AGGR_TYPE (TREE_TYPE (taggr))) - taggr = TREE_TYPE (taggr); - - /* If we know that we don't need to write out this type's - vtable, then don't write out it's dossier. Somebody - else will take care of that. */ - if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr)) - { - if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr)) - { - TREE_PUBLIC (tdecl) = !(CLASSTYPE_INTERFACE_ONLY (taggr) - || CLASSTYPE_INTERFACE_UNKNOWN (taggr)); - TREE_STATIC (tdecl) = 1; - DECL_EXTERNAL (tdecl) = 0; - } - else - { - if (write_virtuals != 0) - TREE_PUBLIC (tdecl) = 1; - } - } - else - { - DECL_EXTERNAL (tdecl) = 0; - TREE_STATIC (tdecl) = 1; - TREE_PUBLIC (tdecl) = (definition > 1); - } - } - SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0)); - if (!definition || DECL_EXTERNAL (tdecl)) - { - /* That's it! */ - finish_decl (tdecl, 0, 0, 0); - return IDENTIFIER_AS_DESC (tname); - } - - /* Show that we are defining the t_desc for this type. */ - DECL_INITIAL (tdecl) = error_mark_node; - - parents = build_tree_list (NULL_TREE, integer_zero_node); - vbases = build_tree_list (NULL_TREE, integer_zero_node); - offsets = build_tree_list (NULL_TREE, integer_zero_node); - methods = NULL_TREE; - ivars = NULL_TREE; - - if (TYPE_LANG_SPECIFIC (type)) - { - int i = CLASSTYPE_N_BASECLASSES (type); - tree method_vec = CLASSTYPE_METHOD_VEC (type); - tree *meth, *end; - tree binfos = TYPE_BINFO_BASETYPES (type); - tree vb = CLASSTYPE_VBASECLASSES (type); - - while (--i >= 0) - parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents); - - while (vb) - { - vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases); - offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets); - vb = TREE_CHAIN (vb); - } - - if (method_vec) - for (meth = TREE_VEC_END (method_vec), - end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; ) - if (*meth) - { - methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods); - method_count++; - } - } - - if (IS_AGGR_TYPE (type)) - { - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - if (TREE_CODE (fields) == FIELD_DECL - || TREE_CODE (fields) == VAR_DECL) - { - ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars); - field_count++; - } - ivars = nreverse (ivars); - } - - parents = finish_table (0, TYPE_POINTER_TO (__t_desc_type_node), parents, 0); - vbases = finish_table (0, TYPE_POINTER_TO (__t_desc_type_node), vbases, 0); - offsets = finish_table (0, integer_type_node, offsets, 0); - methods = finish_table (0, __m_desc_type_node, methods, 0); - ivars = finish_table (0, __i_desc_type_node, ivars, 0); - if (TREE_TYPE (type)) - target_type = build_t_desc (TREE_TYPE (type), definition); - else - target_type = integer_zero_node; - - name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname))); - - elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0), - tree_cons (NULL_TREE, - TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node, - /* really should use bitfield initialization here. */ - tree_cons (NULL_TREE, integer_zero_node, - tree_cons (NULL_TREE, target_type, - tree_cons (NULL_TREE, build_int_2 (field_count, 2), - tree_cons (NULL_TREE, build_int_2 (method_count, 2), - tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, ivars, 0), - tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, methods, 0), - tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0), - tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0), - build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0)))))))))))); - return build_generic_desc (tdecl, elems); -} - -/* Build an initializer for a __i_desc node. */ -tree -build_i_desc (decl) - tree decl; -{ - tree elems, name_string; - tree taggr; - - name_string = DECL_NAME (decl); - name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string))); - - /* Now decide whether this ivar should cause it's type to get - def'd or ref'd in this file. If the type we are looking at - has a proxy definition, we look at the proxy (i.e., a - `foo *' is equivalent to a `foo'). */ - taggr = TREE_TYPE (decl); - - if ((TREE_CODE (taggr) == POINTER_TYPE - || TREE_CODE (taggr) == REFERENCE_TYPE) - && TYPE_VOLATILE (taggr) == 0) - taggr = TREE_TYPE (taggr); - - elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0), - tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl), - build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl), - ! IS_AGGR_TYPE (taggr))))); - taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems); - TREE_CONSTANT (taggr) = 1; - TREE_STATIC (taggr) = 1; - TREE_READONLY (taggr) = 1; - return taggr; -} - -/* Build an initializer for a __m_desc node. */ -tree -build_m_desc (decl) - tree decl; -{ - tree taggr, elems, name_string; - tree parm_count, req_count, vindex, vcontext; - tree parms; - int p_count, r_count; - tree parm_types = NULL_TREE; - - for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0; - parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++) - { - taggr = TREE_VALUE (parms); - if ((TREE_CODE (taggr) == POINTER_TYPE - || TREE_CODE (taggr) == REFERENCE_TYPE) - && TYPE_VOLATILE (taggr) == 0) - taggr = TREE_TYPE (taggr); - - parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms), - ! IS_AGGR_TYPE (taggr)), - parm_types); - if (TREE_PURPOSE (parms) == NULL_TREE) - r_count++; - } - - parm_types = finish_table (0, TYPE_POINTER_TO (__t_desc_type_node), - nreverse (parm_types), 0); - parm_count = build_int_2 (p_count, 0); - req_count = build_int_2 (r_count, 0); - - if (DECL_VINDEX (decl)) - vindex = DECL_VINDEX (decl); - else - vindex = integer_zero_node; - if (DECL_CONTEXT (decl) - && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't') - vcontext = build_t_desc (DECL_CONTEXT (decl), 0); - else - vcontext = integer_zero_node; - name_string = DECL_NAME (decl); - if (name_string == NULL) - name_string = DECL_ASSEMBLER_NAME (decl); - name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string))); - - /* Now decide whether the return type of this mvar - should cause it's type to get def'd or ref'd in this file. - If the type we are looking at has a proxy definition, - we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */ - taggr = TREE_TYPE (TREE_TYPE (decl)); - - if ((TREE_CODE (taggr) == POINTER_TYPE - || TREE_CODE (taggr) == REFERENCE_TYPE) - && TYPE_VOLATILE (taggr) == 0) - taggr = TREE_TYPE (taggr); - - elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0), - tree_cons (NULL_TREE, vindex, - tree_cons (NULL_TREE, vcontext, - tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)), - ! IS_AGGR_TYPE (taggr)), - tree_cons (NULL_TREE, build_c_cast (TYPE_POINTER_TO (default_function_type), build_unary_op (ADDR_EXPR, decl, 0)), - tree_cons (NULL_TREE, parm_count, - tree_cons (NULL_TREE, req_count, - build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0))))))))); - - taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems); - TREE_CONSTANT (taggr) = 1; - TREE_STATIC (taggr) = 1; - TREE_READONLY (taggr) = 1; - return taggr; -} - -/* Conditionally emit code to set up an unwind-protect for the - garbage collector. If this function doesn't do anything that involves - the garbage collector, then do nothing. Otherwise, call __gc_push - at the beginning and __gc_pop at the end. - - NOTE! The __gc_pop function must operate transparently, since - it comes where the logical return label lies. This means that - at runtime *it* must preserve any return value registers. */ - -void -expand_gc_prologue_and_epilogue () -{ - extern tree maybe_gc_cleanup; - struct rtx_def *last_parm_insn, *mark; - extern struct rtx_def *get_last_insn (); - extern struct rtx_def *get_first_nonparm_insn (); - extern struct rtx_def *previous_insn (); - tree action; - - /* If we didn't need the obstack, don't cons any space. */ - if (current_function_obstack_index == 0 - || current_function_obstack_usage == 0) - return; - - mark = get_last_insn (); - last_parm_insn = get_first_nonparm_insn (); - if (last_parm_insn == 0) last_parm_insn = mark; - else last_parm_insn = previous_insn (last_parm_insn); - - action = build_function_call (gc_push_fndecl, - build_tree_list (NULL_TREE, size_int (++current_function_obstack_index))); - expand_expr_stmt (action); - - reorder_insns (next_insn (mark), get_last_insn (), last_parm_insn); - - /* This will be expanded as a cleanup. */ - TREE_VALUE (maybe_gc_cleanup) - = build_function_call (gc_pop_fndecl, NULL_TREE); -} - -/* Some day we'll use this function as a call-back and clean - up all the unnecessary gc dribble that we otherwise create. */ -void -lang_expand_end_bindings (first, last) - struct rtx_def *first, *last; -{ -} - -void -init_gc_processing () -{ - tree parmtypes = hash_tree_chain (class_star_type_node, - hash_tree_chain (integer_type_node, NULL_TREE)); - gc_protect_fndecl = define_function ("__gc_protect", - build_function_type (class_star_type_node, parmtypes), - NOT_BUILT_IN, 0, 0); - - parmtypes = hash_tree_chain (integer_type_node, NULL_TREE); - gc_unprotect_fndecl = define_function ("__gc_unprotect", - build_function_type (void_type_node, parmtypes), - NOT_BUILT_IN, 0, 0); - - gc_push_fndecl = define_function ("__gc_push", - TREE_TYPE (gc_unprotect_fndecl), - NOT_BUILT_IN, 0, 0); - - gc_pop_fndecl = define_function ("__gc_pop", - build_function_type (void_type_node, - void_list_node), - NOT_BUILT_IN, 0, 0); - gc_nonobject = build_int_2 (0x80000000, 0); - gc_visible = build_int_2 (0x40000000, 0); - gc_white = integer_zero_node; - gc_offwhite = build_int_2 (0x10000000, 0); - gc_grey = build_int_2 (0x20000000, 0); - gc_black = build_int_2 (0x30000000, 0); -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-hash.h b/gnu/usr.bin/gcc2/cc1plus/cp-hash.h deleted file mode 100644 index 8c8b5c468b6..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-hash.h +++ /dev/null @@ -1,189 +0,0 @@ -/* C code produced by gperf version 2.5 (GNU C++ version - - $Id: cp-hash.h,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $ -*/ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -struct resword { char *name; short token; enum rid rid;}; - -#define TOTAL_KEYWORDS 82 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 13 -#define MIN_HASH_VALUE 4 -#define MAX_HASH_VALUE 140 -/* maximum key range = 137, duplicates = 0 */ - -#ifdef __GNUC__ -inline -#endif -static unsigned int -hash (str, len) - register char *str; - register int unsigned len; -{ - static unsigned char asso_values[] = - { - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 0, 141, 49, 3, 28, - 28, 0, 5, 11, 32, 37, 141, 2, 24, 35, - 51, 0, 19, 141, 23, 0, 8, 48, 0, 36, - 0, 11, 141, 141, 141, 141, 141, 141, - }; - register int hval = len; - - switch (hval) - { - default: - case 7: - hval += asso_values[str[6]]; - case 6: - case 5: - case 4: - hval += asso_values[str[3]]; - case 3: - case 2: - case 1: - hval += asso_values[str[0]]; - } - return hval + asso_values[str[len - 1]]; -} - -#ifdef __GNUC__ -inline -#endif -struct resword * -is_reserved_word (str, len) - register char *str; - register unsigned int len; -{ - static struct resword wordlist[] = - { - {"",}, {"",}, {"",}, {"",}, - {"else", ELSE, NORID,}, - {"",}, {"",}, - {"__asm__", GCC_ASM_KEYWORD, NORID}, - {"",}, {"",}, - {"__headof__", HEADOF, NORID}, - {"sizeof", SIZEOF, NORID,}, - {"this", THIS, NORID,}, - {"__headof", HEADOF, NORID}, - {"except", EXCEPT, NORID /* Extension */,}, - {"goto", GOTO, NORID,}, - {"",}, - {"__const__", TYPE_QUAL, RID_CONST}, - {"__volatile", TYPE_QUAL, RID_VOLATILE}, - {"typeof", TYPEOF, NORID,}, - {"__volatile__", TYPE_QUAL, RID_VOLATILE}, - {"__typeof__", TYPEOF, NORID}, - {"try", TRY, NORID /* Extension */,}, - {"__const", TYPE_QUAL, RID_CONST}, - {"__typeof", TYPEOF, NORID}, - {"typedef", SCSPEC, RID_TYPEDEF,}, - {"private", VISSPEC, RID_PRIVATE,}, - {"",}, - {"raise", RAISE, NORID /* Extension */,}, - {"raises", RAISES, NORID /* Extension */,}, - {"do", DO, NORID,}, - {"for", FOR, NORID,}, - {"case", CASE, NORID,}, - {"class", AGGR, RID_CLASS,}, - {"delete", DELETE, NORID,}, - {"__classof__", CLASSOF, NORID}, - {"short", TYPESPEC, RID_SHORT,}, - {"double", TYPESPEC, RID_DOUBLE,}, - {"__classof", CLASSOF, NORID}, - {"friend", SCSPEC, RID_FRIEND,}, - {"__asm", GCC_ASM_KEYWORD, NORID}, - {"const", TYPE_QUAL, RID_CONST,}, - {"static", SCSPEC, RID_STATIC,}, - {"template", TEMPLATE, NORID,}, - {"if", IF, NORID,}, - {"classof", CLASSOF, NORID,}, - {"switch", SWITCH, NORID,}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"int", TYPESPEC, RID_INT,}, - {"throw", THROW, NORID /* Extension */,}, - {"long", TYPESPEC, RID_LONG,}, - {"",}, {"",}, - {"auto", SCSPEC, RID_AUTO,}, - {"operator", OPERATOR, NORID,}, - {"",}, - {"__attribute", ATTRIBUTE, NORID}, - {"extern", SCSPEC, RID_EXTERN,}, - {"__attribute__", ATTRIBUTE, NORID}, - {"break", BREAK, NORID,}, - {"void", TYPESPEC, RID_VOID,}, - {"",}, - {"struct", AGGR, RID_RECORD,}, - {"virtual", SCSPEC, RID_VIRTUAL,}, - {"__extension__", EXTENSION, NORID}, - {"while", WHILE, NORID,}, - {"",}, - {"float", TYPESPEC, RID_FLOAT,}, - {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, - {"",}, {"",}, - {"headof", HEADOF, NORID,}, - {"protected", VISSPEC, RID_PROTECTED,}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"enum", ENUM, NORID,}, - {"",}, - {"all", ALL, NORID /* Extension */,}, - {"public", VISSPEC, RID_PUBLIC,}, - {"char", TYPESPEC, RID_CHAR,}, - {"reraise", RERAISE, NORID /* Extension */,}, - {"inline", SCSPEC, RID_INLINE,}, - {"volatile", TYPE_QUAL, RID_VOLATILE,}, - {"__label__", LABEL, NORID}, - {"",}, {"",}, - {"signed", TYPESPEC, RID_SIGNED,}, - {"__alignof__", ALIGNOF, NORID}, - {"asm", ASM_KEYWORD, NORID,}, - {"",}, - {"__alignof", ALIGNOF, NORID}, - {"new", NEW, NORID,}, - {"register", SCSPEC, RID_REGISTER,}, - {"continue", CONTINUE, NORID,}, - {"catch", CATCH, NORID,}, - {"",}, {"",}, {"",}, - {"exception", AGGR, RID_EXCEPTION /* Extension */,}, - {"",}, {"",}, - {"default", DEFAULT, NORID,}, - {"",}, {"",}, {"",}, - {"union", AGGR, RID_UNION,}, - {"",}, {"",}, {"",}, - {"overload", OVERLOAD, NORID,}, - {"",}, - {"__inline", SCSPEC, RID_INLINE}, - {"",}, - {"__inline__", SCSPEC, RID_INLINE}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"unsigned", TYPESPEC, RID_UNSIGNED,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"return", RETURN, NORID,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, {"",}, - {"dynamic", DYNAMIC, NORID,}, - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register char *s = wordlist[key].name; - - if (*s == *str && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-init.c b/gnu/usr.bin/gcc2/cc1plus/cp-init.c deleted file mode 100644 index fc8223cb8e8..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-init.c +++ /dev/null @@ -1,4011 +0,0 @@ -/* Handle initialization things in C++. - Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-init.c,v 1.1.1.1 1995/10/18 08:39:31 deraadt Exp $"; -#endif /* not lint */ - -/* High-level class interface. */ - -#include "config.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" - -#undef NULL -#define NULL 0 - -/* In C++, structures with well-defined constructors are initialized by - those constructors, unasked. CURRENT_BASE_INIT_LIST - holds a list of stmts for a BASE_INIT term in the grammar. - This list has one element for each base class which must be - initialized. The list elements are [basename, init], with - type basetype. This allows the possibly anachronistic form - (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)" - where each successive term can be handed down the constructor - line. Perhaps this was not intended. */ -tree current_base_init_list, current_member_init_list; - -void emit_base_init (); -void check_base_init (); -static void expand_aggr_vbase_init (); -void expand_member_init (); -void expand_aggr_init (); - -static void expand_aggr_init_1 (); -static void expand_recursive_init_1 (); -static void expand_recursive_init (); -tree expand_vec_init (); -tree build_vec_delete (); - -static void add_friend (), add_friends (); - -/* Cache _builtin_new and _builtin_delete exprs. */ -static tree BIN, BID; - -static tree minus_one; - -/* Set up local variable for this file. MUST BE CALLED AFTER - INIT_DECL_PROCESSING. */ - -tree BI_header_type, BI_header_size; - -void init_init_processing () -{ - tree op_id; - tree fields[2]; - - /* Define implicit `operator new' and `operator delete' functions. */ - BIN = default_conversion (TREE_VALUE (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) NEW_EXPR]))); - TREE_USED (TREE_OPERAND (BIN, 0)) = 0; - BID = default_conversion (TREE_VALUE (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR]))); - TREE_USED (TREE_OPERAND (BID, 0)) = 0; - minus_one = build_int_2 (-1, -1); - - op_id = ansi_opname[(int) NEW_EXPR]; - IDENTIFIER_GLOBAL_VALUE (op_id) = BIN; - op_id = ansi_opname[(int) DELETE_EXPR]; - IDENTIFIER_GLOBAL_VALUE (op_id) = BID; - - /* Define the structure that holds header information for - arrays allocated via operator new. */ - BI_header_type = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("nelts"), - sizetype); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("ptr_2comp"), - ptr_type_node); - finish_builtin_type (BI_header_type, "__new_cookie", fields, 1, double_type_node); - BI_header_size = size_in_bytes (BI_header_type); -} - -/* Recursive subroutine of emit_base_init. For main type T, - recursively initialize the vfields of the base type PARENT. - RECURSE is non-zero when this function is being called - recursively. */ - -static void -init_vfields (t, parent, recurse) - tree t, parent; - int recurse; -{ - tree vfields; - - /* Initialize all the virtual function table fields that - do not come from virtual base classes. */ - vfields = CLASSTYPE_VFIELDS (parent); - while (vfields) - { - tree basetype = VF_DERIVED_VALUE (vfields) - ? TYPE_MAIN_VARIANT (VF_DERIVED_VALUE (vfields)) - : VF_BASETYPE_VALUE (vfields); - - /* If the vtable installed by the constructor was not - the right one, fix that here. */ - if (TREE_ADDRESSABLE (vfields) - && CLASSTYPE_NEEDS_VIRTUAL_REINIT (basetype) - && (recurse > 0 - || TYPE_HAS_CONSTRUCTOR (basetype) - /* BASE_INIT_LIST has already initialized the immediate basetypes. */ - || get_base_distance (basetype, t, 0, (tree *) 0) > 1)) - { - tree binfo = binfo_value (basetype, t); - if ((recurse != 0 && (binfo != binfo_value (basetype, parent))) - || (recurse == 0 - && BINFO_VTABLE (binfo) != TYPE_BINFO_VTABLE (basetype))) - { - tree ptr = convert_pointer_to (binfo, current_class_decl); - expand_expr_stmt (build_virtual_init (TYPE_BINFO (t), binfo, ptr)); - } - init_vfields (t, basetype, recurse+1); - } - vfields = TREE_CHAIN (vfields); - } -} - -/* Perform whatever initialization have yet to be done on the - base class of the class variable. These actions are in - the global variable CURRENT_BASE_INIT_LIST. Such an - action could be NULL_TREE, meaning that the user has explicitly - called the base class constructor with no arguments. - - If there is a need for a call to a constructor, we - must surround that call with a pushlevel/poplevel pair, - since we are technically at the PARM level of scope. - - Argument IMMEDIATELY, if zero, forces a new sequence to be generated - to contain these new insns, so it can be emitted later. This sequence - is saved in the global variable BASE_INIT_INSNS. Otherwise, the insns - are emitted into the current sequence. - - Note that emit_base_init does *not* initialize virtual - base classes. That is done specially, elsewhere. */ - -void -emit_base_init (t, immediately) - tree t; - int immediately; -{ - extern tree in_charge_identifier; - - tree member, decl, vbases; - tree init_list; - int pass, start; - tree t_binfo = TYPE_BINFO (t); - tree binfos = BINFO_BASETYPES (t_binfo); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree fields_to_unmark = NULL_TREE; - - if (! immediately) - { - do_pending_stack_adjust (); - start_sequence (); - } - - if (write_symbols == NO_DEBUG) - /* As a matter of principle, `start_sequence' should do this. */ - emit_note (0, -1); - else - /* Always emit a line number note so we can step into constructors. */ - emit_line_note_force (DECL_SOURCE_FILE (current_function_decl), - DECL_SOURCE_LINE (current_function_decl)); - - /* In this case, we always need IN_CHARGE_NODE, because we have - to know whether to deallocate or not before exiting. */ - if (flag_handle_exceptions == 2 - && lookup_name (in_charge_identifier, 0) == NULL_TREE) - { - tree in_charge_node = pushdecl (build_decl (VAR_DECL, in_charge_identifier, - integer_type_node)); - store_init_value (in_charge_node, build (EQ_EXPR, integer_type_node, - current_class_decl, - integer_zero_node)); - expand_decl (in_charge_node); - expand_decl_init (in_charge_node); - } - - start = ! TYPE_USES_VIRTUAL_BASECLASSES (t); - for (pass = start; pass < 2; pass++) - { - tree vbase_init_list = NULL_TREE; - - for (init_list = current_base_init_list; init_list; - init_list = TREE_CHAIN (init_list)) - { - tree basename = TREE_PURPOSE (init_list); - tree binfo; - tree init = TREE_VALUE (init_list); - - if (basename == NULL_TREE) - { - /* Initializer for single base class. Must not - use multiple inheritance or this is ambiguous. */ - switch (n_baseclasses) - { - case 0: - error ("type `%s' does not have a base class to initialize", - IDENTIFIER_POINTER (current_class_name)); - return; - case 1: - break; - default: - error ("unnamed initializer ambiguous for type `%s' which uses multiple inheritance", IDENTIFIER_POINTER (current_class_name)); - return; - } - binfo = TREE_VEC_ELT (binfos, 0); - } - else if (is_aggr_typedef (basename, 1)) - { - binfo = binfo_or_else (IDENTIFIER_TYPE_VALUE (basename), t); - if (binfo == NULL_TREE) - continue; - - /* Virtual base classes are special cases. Their initializers - are recorded with this constructor, and they are used when - this constructor is the top-level constructor called. */ - if (! TREE_VIA_VIRTUAL (binfo)) - { - /* Otherwise, if it is not an immediate base class, complain. */ - for (i = n_baseclasses-1; i >= 0; i--) - if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i))) - break; - if (i < 0) - { - error ("type `%s' is not an immediate base class of type `%s'", - IDENTIFIER_POINTER (basename), - IDENTIFIER_POINTER (current_class_name)); - continue; - } - } - } - else - continue; - - /* The base initialization list goes up to the first - base class which can actually use it. */ - - if (pass == start) - { - char *msgp = (! TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo))) - ? "cannot pass initialization up to class `%s'" : 0; - - while (! TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo)) - && BINFO_BASETYPES (binfo) != NULL_TREE - && TREE_VEC_LENGTH (BINFO_BASETYPES (binfo)) == 1) - { - /* ?? This should be fixed in RENO by forcing - default constructors to exist. */ - SET_BINFO_BASEINIT_MARKED (binfo); - binfo = BINFO_BASETYPE (binfo, 0); - } - - if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo))) - { - if (msgp) - { - if (pedantic) - error_with_aggr_type (binfo, msgp); - else - msgp = 0; - } - } - else - { - msgp = "no constructor found for initialization of `%s'"; - error (msgp, IDENTIFIER_POINTER (basename)); - } - - if (BINFO_BASEINIT_MARKED (binfo)) - { - msgp = "class `%s' initializer already specified"; - error (msgp, IDENTIFIER_POINTER (basename)); - } - if (msgp) - continue; - - SET_BINFO_BASEINIT_MARKED (binfo); - if (TREE_VIA_VIRTUAL (binfo)) - { - vbase_init_list = tree_cons (init, BINFO_TYPE (binfo), - vbase_init_list); - continue; - } - if (pass == 0) - continue; - } - else if (TREE_VIA_VIRTUAL (binfo)) - continue; - - member = convert_pointer_to (binfo, current_class_decl); - expand_aggr_init_1 (t_binfo, 0, - build_indirect_ref (member, 0), init, - BINFO_OFFSET_ZEROP (binfo), - LOOKUP_PROTECTED_OK|LOOKUP_COMPLAIN); - if (flag_handle_exceptions == 2 && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) - { - cplus_expand_start_try (1); - push_exception_cleanup (member); - } - } - - if (pass == 0) - { - tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); - tree vbases; - - if (DECL_NAME (current_function_decl) == NULL_TREE - && TREE_CHAIN (first_arg) != NULL_TREE) - { - /* If there are virtual baseclasses without initialization - specified, and this is a default X(X&) constructor, - build the initialization list so that each virtual baseclass - of the new object is initialized from the virtual baseclass - of the incoming arg. */ - tree init_arg = build_unary_op (ADDR_EXPR, TREE_CHAIN (first_arg), 0); - for (vbases = CLASSTYPE_VBASECLASSES (t); - vbases; vbases = TREE_CHAIN (vbases)) - { - if (BINFO_BASEINIT_MARKED (vbases) == 0) - { - member = convert_pointer_to (vbases, init_arg); - if (member == init_arg) - member = TREE_CHAIN (first_arg); - else - TREE_TYPE (member) = build_reference_type (BINFO_TYPE (vbases)); - vbase_init_list = tree_cons (convert_from_reference (member), - vbases, vbase_init_list); - SET_BINFO_BASEINIT_MARKED (vbases); - } - } - } - expand_start_cond (first_arg, 0); - expand_aggr_vbase_init (t_binfo, C_C_D, current_class_decl, - vbase_init_list); - expand_expr_stmt (build_vbase_vtables_init (t_binfo, t_binfo, - C_C_D, current_class_decl, 1)); - expand_end_cond (); - } - } - current_base_init_list = NULL_TREE; - - /* Now, perform default initialization of all base classes which - have not yet been initialized, and unmark baseclasses which - have been initialized. */ - for (i = 0; i < n_baseclasses; i++) - { - tree base = current_class_decl; - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) - { - if (! TREE_VIA_VIRTUAL (base_binfo) - && ! BINFO_BASEINIT_MARKED (base_binfo)) - { - tree ref; - - if (BINFO_OFFSET_ZEROP (base_binfo)) - base = build1 (NOP_EXPR, - TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), - current_class_decl); - else - base = build (PLUS_EXPR, - TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), - current_class_decl, BINFO_OFFSET (base_binfo)); - - ref = build_indirect_ref (base, 0); - expand_aggr_init_1 (t_binfo, 0, ref, NULL_TREE, - BINFO_OFFSET_ZEROP (base_binfo), - LOOKUP_PROTECTED_OK|LOOKUP_COMPLAIN); - if (flag_handle_exceptions == 2 - && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - cplus_expand_start_try (1); - push_exception_cleanup (base); - } - } - } - CLEAR_BINFO_BASEINIT_MARKED (base_binfo); - } - for (vbases = CLASSTYPE_VBASECLASSES (t); vbases; vbases = TREE_CHAIN (vbases)) - CLEAR_BINFO_BASEINIT_MARKED (vbases); - - /* Initialize all the virtual function table fields that - do not come from virtual base classes. */ - init_vfields (t, t, 0); - - if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (t)) - expand_expr_stmt (build_virtual_init (TYPE_BINFO (t), t, - current_class_decl)); - - /* Members we through expand_member_init. We initialize all the members - needing initialization that did not get it so far. */ - for (; current_member_init_list; - current_member_init_list = TREE_CHAIN (current_member_init_list)) - { - tree name = TREE_PURPOSE (current_member_init_list); - tree init = TREE_VALUE (current_member_init_list); - tree field = (TREE_CODE (name) == COMPONENT_REF - ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name)); - tree type; - - /* If one member shadows another, get the outermost one. */ - if (TREE_CODE (field) == TREE_LIST) - { - field = TREE_VALUE (field); - if (decl_type_context (field) != current_class_type) - error ("field `%s' not in immediate context"); - } - - type = TREE_TYPE (field); - - if (TREE_STATIC (field)) - { - error_with_aggr_type (DECL_FIELD_CONTEXT (field), - "field `%s::%s' is static; only point of initialization is its declaration", IDENTIFIER_POINTER (name)); - continue; - } - - if (DECL_NAME (field)) - { - if (TREE_HAS_CONSTRUCTOR (field)) - error ("multiple initializations given for member `%s'", - IDENTIFIER_POINTER (DECL_NAME (field))); - } - - /* Mark this node as having been initialized. */ - TREE_HAS_CONSTRUCTOR (field) = 1; - if (DECL_FIELD_CONTEXT (field) != t) - fields_to_unmark = tree_cons (NULL_TREE, field, fields_to_unmark); - - if (TREE_CODE (name) == COMPONENT_REF) - { - /* Initialization of anonymous union. */ - expand_assignment (name, init, 0, 0); - continue; - } - decl = build_component_ref (C_C_D, name, 0, 1); - - if (TYPE_NEEDS_CONSTRUCTING (type)) - { - if (TREE_CODE (type) == ARRAY_TYPE - && init != NULL_TREE - && TREE_CHAIN (init) == NULL_TREE - && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) - { - /* Initialization of one array from another. */ - expand_vec_init (TREE_OPERAND (decl, 1), decl, - array_type_nelts (type), TREE_VALUE (init), 1); - } - else - expand_aggr_init (decl, init, 0); - } - else - { - if (init == NULL_TREE) - { - error ("types without constructors must have complete initializers"); - init = error_mark_node; - } - else if (TREE_CHAIN (init)) - { - warning ("initializer list treated as compound expression"); - init = build_compound_expr (init); - } - else - init = TREE_VALUE (init); - - expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); - } - if (flag_handle_exceptions == 2 && TYPE_NEEDS_DESTRUCTOR (type)) - { - cplus_expand_start_try (1); - push_exception_cleanup (build_unary_op (ADDR_EXPR, decl, 0)); - } - } - - for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) - { - /* All we care about is this unique member. It contains - all the information we need to know, and that right early. */ - tree type = TREE_TYPE (member); - tree init = TREE_HAS_CONSTRUCTOR (member) - ? error_mark_node : DECL_INITIAL (member); - - /* Unmark this field. If it is from an anonymous union, - then unmark the field recursively. */ - TREE_HAS_CONSTRUCTOR (member) = 0; - if (TREE_ANON_UNION_ELEM (member)) - emit_base_init (TREE_TYPE (member), 1); - - /* Member had explicit initializer. */ - if (init == error_mark_node) - continue; - - if (TREE_CODE (member) != FIELD_DECL) - continue; - - if (type == error_mark_node) - continue; - - if (TYPE_NEEDS_CONSTRUCTING (type)) - { - if (init) - init = build_tree_list (NULL_TREE, init); - decl = build_component_ref (C_C_D, DECL_NAME (member), 0, 0); - expand_aggr_init (decl, init, 0); - } - else - { - if (init) - { - decl = build_component_ref (C_C_D, DECL_NAME (member), 0, 0); - expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); - } - else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE) - warning ("uninitialized reference member `%s'", - IDENTIFIER_POINTER (DECL_NAME (member))); - } - if (flag_handle_exceptions == 2 && TYPE_NEEDS_DESTRUCTOR (type)) - { - cplus_expand_start_try (1); - push_exception_cleanup (build_unary_op (ADDR_EXPR, decl, 0)); - } - } - /* Unmark fields which are initialized for the base class. */ - while (fields_to_unmark) - { - TREE_HAS_CONSTRUCTOR (TREE_VALUE (fields_to_unmark)) = 0; - fields_to_unmark = TREE_CHAIN (fields_to_unmark); - } - - /* It is possible for the initializers to need cleanups. - Expand those cleanups now that all the initialization - has been done. */ - expand_cleanups_to (NULL_TREE); - - if (! immediately) - { - extern rtx base_init_insns; - - do_pending_stack_adjust (); - my_friendly_assert (base_init_insns == 0, 207); - base_init_insns = get_insns (); - end_sequence (); - } - - /* All the implicit try blocks we built up will be zapped - when we come to a real binding contour boundary. */ -} - -/* Check that all fields are properly initialized after - an assignment to `this'. */ -void -check_base_init (t) - tree t; -{ - tree member; - for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) - if (DECL_NAME (member) && TREE_USED (member)) - error ("field `%s' used before initialized (after assignment to `this')", - IDENTIFIER_POINTER (DECL_NAME (member))); -} - -/* This code sets up the virtual function tables appropriate for - the pointer DECL. It is a one-ply initialization. - - BINFO is the exact type that DECL is supposed to be. In - multiple inheritance, this might mean "C's A" if C : A, B. */ -tree -build_virtual_init (main_binfo, binfo, decl) - tree main_binfo, binfo; - tree decl; -{ - tree type; - tree vtbl, vtbl_ptr; - tree vtype; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (TREE_CODE (binfo) == RECORD_TYPE) - { - type = binfo; - binfo = TYPE_BINFO (type); - } - else - my_friendly_abort (46); - - vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); -#if 0 - /* This code suggests that it's time to rewrite how we handle - replicated baseclasses in G++. */ - if (get_base_distance (vtype, TREE_TYPE (TREE_TYPE (decl)), - 0, (tree *) 0) == -2) - { - tree binfos = TYPE_BINFO_BASETYPES (TREE_TYPE (TREE_TYPE (decl))); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree result = NULL_TREE; - - for (i = n_baselinks-1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree this_decl; - - if (get_base_distance (vtype, BINFO_TYPE (base_binfo), 0, 0) == -1) - continue; - - if (TREE_VIA_VIRTUAL (base_binfo)) - this_decl = build_vbase_pointer (build_indirect_ref (decl), BINFO_TYPE (base_binfo)); - else if (BINFO_OFFSET_ZEROP (base_binfo)) - this_decl = build1 (NOP_EXPR, TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), - decl); - else - this_decl = build (PLUS_EXPR, TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), - decl, BINFO_OFFSET (base_binfo)); - result = tree_cons (NULL_TREE, build_virtual_init (main_binfo, base_binfo, this_decl), result); - } - return build_compound_expr (result); - } -#endif - - { -#if 1 -#if 1 - vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); -#else - /* The below does not work when we have to step through the - vfield, on our way down to the most base class for the - vfield. */ - vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), - BINFO_TYPE (main_binfo))); -#endif -#else - my_friendly_assert (BINFO_TYPE (main_binfo) == BINFO_TYPE (binfo), 208); - vtbl = BINFO_VTABLE (main_binfo); -#endif /* 1 */ - assemble_external (vtbl); - TREE_USED (vtbl) = 1; - vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl); - } - decl = convert_pointer_to (vtype, decl); - vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, 0), vtype); - if (vtbl_ptr == error_mark_node) - return error_mark_node; - - /* Have to convert VTBL since array sizes may be different. */ - return build_modify_expr (vtbl_ptr, NOP_EXPR, - convert (TREE_TYPE (vtbl_ptr), vtbl)); -} - -/* Subroutine of `expand_aggr_vbase_init'. - BINFO is the binfo of the type that is being initialized. - INIT_LIST is the list of initializers for the virtual baseclass. */ -static void -expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) - tree binfo, exp, addr, init_list; -{ - tree init = value_member (BINFO_TYPE (binfo), init_list); - tree ref = build_indirect_ref (addr, 0); - if (init) - init = TREE_PURPOSE (init); - /* Call constructors, but don't set up vtables. */ - expand_aggr_init_1 (binfo, exp, ref, init, 0, - LOOKUP_PROTECTED_OK|LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY); - CLEAR_BINFO_VBASE_INIT_MARKED (binfo); -} - -/* Initialize this object's virtual base class pointers. This must be - done only at the top-level of the object being constructed. - - INIT_LIST is list of initialization for constructor to perform. */ -static void -expand_aggr_vbase_init (binfo, exp, addr, init_list) - tree binfo; - tree exp; - tree addr; - tree init_list; -{ - tree type = BINFO_TYPE (binfo); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - tree result = init_vbase_pointers (type, addr); - tree vbases; - - if (result) - expand_expr_stmt (build_compound_expr (result)); - - /* Mark everything as having an initializer - (either explicit or default). */ - for (vbases = CLASSTYPE_VBASECLASSES (type); - vbases; vbases = TREE_CHAIN (vbases)) - SET_BINFO_VBASE_INIT_MARKED (vbases); - - /* First, initialize baseclasses which could be baseclasses - for other virtual baseclasses. */ - for (vbases = CLASSTYPE_VBASECLASSES (type); - vbases; vbases = TREE_CHAIN (vbases)) - /* Don't initialize twice. */ - if (BINFO_VBASE_INIT_MARKED (vbases)) - { - tree tmp = result; - - while (BINFO_TYPE (vbases) != BINFO_TYPE (TREE_PURPOSE (tmp))) - tmp = TREE_CHAIN (tmp); - expand_aggr_vbase_init_1 (vbases, exp, - TREE_OPERAND (TREE_VALUE (tmp), 0), - init_list); - } - - /* Now initialize the baseclasses which don't have virtual baseclasses. */ - for (; result; result = TREE_CHAIN (result)) - /* Don't initialize twice. */ - if (BINFO_VBASE_INIT_MARKED (TREE_PURPOSE (result))) - { - my_friendly_abort (47); - expand_aggr_vbase_init_1 (TREE_PURPOSE (result), exp, - TREE_OPERAND (TREE_VALUE (result), 0), - init_list); - } - } -} - -/* Subroutine to perform parser actions for member initialization. - S_ID is the scoped identifier. - NAME is the name of the member. - INIT is the initializer, or `void_type_node' if none. */ -void -do_member_init (s_id, name, init) - tree s_id, name, init; -{ - tree binfo, base; - - if (current_class_type == NULL_TREE - || ! is_aggr_typedef (s_id, 1)) - return; - binfo = get_binfo (IDENTIFIER_TYPE_VALUE (s_id), - current_class_type, 1); - if (binfo == error_mark_node) - return; - if (binfo == 0) - { - error_not_base_type (IDENTIFIER_TYPE_VALUE (s_id), current_class_type); - return; - } - - base = convert_pointer_to (binfo, current_class_decl); - expand_member_init (build_indirect_ref (base, NULL_PTR), name, init); -} - -/* Function to give error message if member initialization specification - is erroneous. FIELD is the member we decided to initialize. - TYPE is the type for which the initialization is being performed. - FIELD must be a member of TYPE, or the base type from which FIELD - comes must not need a constructor. - - MEMBER_NAME is the name of the member. */ - -static int -member_init_ok_or_else (field, type, member_name) - tree field; - tree type; - char *member_name; -{ - if (field == error_mark_node) return 0; - if (field == NULL_TREE) - { - error_with_aggr_type (type, "class `%s' does not have any field named `%s'", - member_name); - return 0; - } - if (DECL_CONTEXT (field) != type - && TYPE_NEEDS_CONSTRUCTOR (DECL_CONTEXT (field))) - { - error ("member `%s' comes from base class needing constructor", member_name); - return 0; - } - return 1; -} - -/* If NAME is a viable field name for the aggregate DECL, - and PARMS is a viable parameter list, then expand an _EXPR - which describes this initialization. - - Note that we do not need to chase through the class's base classes - to look for NAME, because if it's in that list, it will be handled - by the constructor for that base class. - - We do not yet have a fixed-point finder to instantiate types - being fed to overloaded constructors. If there is a unique - constructor, then argument types can be got from that one. - - If INIT is non-NULL, then it the initialization should - be placed in `current_base_init_list', where it will be processed - by `emit_base_init'. */ -void -expand_member_init (exp, name, init) - tree exp, name, init; -{ - extern tree ptr_type_node; /* should be in tree.h */ - - tree basetype = NULL_TREE, field; - tree parm; - tree rval, type; - tree actual_name; - - if (exp == NULL_TREE) - return; /* complain about this later */ - - type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - - if (name == NULL_TREE && IS_AGGR_TYPE (type)) - switch (CLASSTYPE_N_BASECLASSES (type)) - { - case 0: - error ("base class initializer specified, but no base class to initialize"); - return; - case 1: - basetype = TYPE_BINFO_BASETYPE (type, 0); - break; - default: - error ("initializer for unnamed base class ambiguous"); - error_with_aggr_type (type, "(type `%s' uses multiple inheritance)"); - return; - } - - if (init) - { - /* The grammar should not allow fields which have names - that are TYPENAMEs. Therefore, if the field has - a non-NULL TREE_TYPE, we may assume that this is an - attempt to initialize a base class member of the current - type. Otherwise, it is an attempt to initialize a - member field. */ - - if (init == void_type_node) - init = NULL_TREE; - - if (name == NULL_TREE || IDENTIFIER_HAS_TYPE_VALUE (name)) - { - tree base_init; - - if (name == NULL_TREE) - if (basetype) - name = TYPE_IDENTIFIER (basetype); - else - { - error ("no base class to initialize"); - return; - } - else - { - basetype = IDENTIFIER_TYPE_VALUE (name); - if (basetype != type - && ! binfo_member (basetype, TYPE_BINFO (type)) - && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type))) - { - if (IDENTIFIER_CLASS_VALUE (name)) - goto try_member; - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - error ("type `%s' is not an immediate or virtual basetype for `%s'", - IDENTIFIER_POINTER (name), - TYPE_NAME_STRING (type)); - else - error ("type `%s' is not an immediate basetype for `%s'", - IDENTIFIER_POINTER (name), - TYPE_NAME_STRING (type)); - return; - } - } - - if (purpose_member (name, current_base_init_list)) - { - error ("base class `%s' already initialized", - IDENTIFIER_POINTER (name)); - return; - } - - base_init = build_tree_list (name, init); - TREE_TYPE (base_init) = basetype; - current_base_init_list = chainon (current_base_init_list, base_init); - } - else - { - tree member_init; - - try_member: - field = lookup_field (type, name, 1, 0); - - if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name))) - return; - - if (purpose_member (name, current_member_init_list)) - { - error ("field `%s' already initialized", IDENTIFIER_POINTER (name)); - return; - } - - member_init = build_tree_list (name, init); - TREE_TYPE (member_init) = TREE_TYPE (field); - current_member_init_list = chainon (current_member_init_list, member_init); - } - return; - } - else if (name == NULL_TREE) - { - compiler_error ("expand_member_init: name == NULL_TREE"); - return; - } - - basetype = type; - field = lookup_field (basetype, name, 0, 0); - - if (! member_init_ok_or_else (field, basetype, IDENTIFIER_POINTER (name))) - return; - - /* now see if there is a constructor for this type - which will take these args. */ - - if (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (field))) - { - tree parmtypes, fndecl; - - if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) - { - /* just know that we've seen something for this node */ - DECL_INITIAL (exp) = error_mark_node; - TREE_USED (exp) = 1; - } - type = TYPE_MAIN_VARIANT (TREE_TYPE (field)); - actual_name = TYPE_IDENTIFIER (type); - parm = build_component_ref (exp, name, 0, 0); - - /* Now get to the constructor. */ - fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0); - /* Get past destructor, if any. */ - if (TYPE_HAS_DESTRUCTOR (type)) - fndecl = DECL_CHAIN (fndecl); - - if (fndecl) - my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209); - - /* If the field is unique, we can use the parameter - types to guide possible type instantiation. */ - if (DECL_CHAIN (fndecl) == NULL_TREE) - { - /* There was a confusion here between - FIELD and FNDECL. The following code - should be correct, but abort is here - to make sure. */ - my_friendly_abort (48); - parmtypes = FUNCTION_ARG_CHAIN (fndecl); - } - else - { - parmtypes = NULL_TREE; - fndecl = NULL_TREE; - } - - init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL); - if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node) - rval = build_method_call (NULL_TREE, actual_name, init, NULL_TREE, LOOKUP_NORMAL); - else - return; - - if (rval != error_mark_node) - { - /* Now, fill in the first parm with our guy */ - TREE_VALUE (TREE_OPERAND (rval, 1)) - = build_unary_op (ADDR_EXPR, parm, 0); - TREE_TYPE (rval) = ptr_type_node; - TREE_SIDE_EFFECTS (rval) = 1; - } - } - else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) - { - parm = build_component_ref (exp, name, 0, 0); - expand_aggr_init (parm, NULL_TREE, 0); - rval = error_mark_node; - } - - /* Now initialize the member. It does not have to - be of aggregate type to receive initialization. */ - if (rval != error_mark_node) - expand_expr_stmt (rval); -} - -/* This is like `expand_member_init', only it stores one aggregate - value into another. - - INIT comes in two flavors: it is either a value which - is to be stored in EXP, or it is a parameter list - to go to a constructor, which will operate on EXP. - If `init' is a CONSTRUCTOR, then we emit a warning message, - explaining that such initializations are illegal. - - ALIAS_THIS is nonzero iff we are initializing something which is - essentially an alias for C_C_D. In this case, the base constructor - may move it on us, and we must keep track of such deviations. - - If INIT resolves to a CALL_EXPR which happens to return - something of the type we are looking for, then we know - that we can safely use that call to perform the - initialization. - - The virtual function table pointer cannot be set up here, because - we do not really know its type. - - Virtual baseclass pointers are also set up here. - - This never calls operator=(). - - When initializing, nothing is CONST. - - A default copy constructor may have to be used to perform the - initialization. - - A constructor or a conversion operator may have to be used to - perform the initialization, but not both, as it would be ambiguous. - */ - -void -expand_aggr_init (exp, init, alias_this) - tree exp, init; - int alias_this; -{ - tree type = TREE_TYPE (exp); - int was_const = TREE_READONLY (exp); - - if (init == error_mark_node) - return; - - TREE_READONLY (exp) = 0; - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Must arrange to initialize each element of EXP - from elements of INIT. */ - int was_const_elts = TYPE_READONLY (TREE_TYPE (type)); - tree itype = init ? TREE_TYPE (init) : NULL_TREE; - if (was_const_elts) - { - tree atype = build_cplus_array_type (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TYPE_DOMAIN (type)); - if (init && (TREE_TYPE (exp) == TREE_TYPE (init))) - TREE_TYPE (init) = atype; - TREE_TYPE (exp) = atype; - } - expand_vec_init (exp, exp, array_type_nelts (type), init, - init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1)); - TREE_READONLY (exp) = was_const; - TREE_TYPE (exp) = type; - if (init) TREE_TYPE (init) = itype; - return; - } - - if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) - /* just know that we've seen something for this node */ - TREE_USED (exp) = 1; - - /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the - constructor as parameters to an implicit GNU C++ constructor. */ - if (init && TREE_CODE (init) == CONSTRUCTOR - && TYPE_HAS_CONSTRUCTOR (type) - && TREE_TYPE (init) == type) - init = CONSTRUCTOR_ELTS (init); - expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, - init, alias_this, LOOKUP_NORMAL); - TREE_READONLY (exp) = was_const; -} - -static void -expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags) - tree binfo; - tree true_exp, exp; - tree type; - tree init; - int alias_this; - int flags; -{ - /* It fails because there may not be a constructor which takes - its own type as the first (or only parameter), but which does - take other types via a conversion. So, if the thing initializing - the expression is a unit element of type X, first try X(X&), - followed by initialization by X. If neither of these work - out, then look hard. */ - tree rval; - tree parms; - int xxref_init_possible; - - if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) - { - parms = init; - if (parms) init = TREE_VALUE (parms); - } - else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init)) - { - rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0); - expand_expr_stmt (rval); - return; - } - else parms = build_tree_list (NULL_TREE, init); - - if (TYPE_HAS_INIT_REF (type) - || init == NULL_TREE - || TREE_CHAIN (parms) != NULL_TREE) - xxref_init_possible = 0; - else - { - xxref_init_possible = LOOKUP_SPECULATIVELY; - flags &= ~LOOKUP_COMPLAIN; - } - - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - if (true_exp == exp) - parms = tree_cons (NULL_TREE, integer_one_node, parms); - else - parms = tree_cons (NULL_TREE, integer_zero_node, parms); - flags |= LOOKUP_HAS_IN_CHARGE; - } - - rval = build_method_call (exp, constructor_name (type), - parms, binfo, flags|xxref_init_possible); - if (rval == NULL_TREE && xxref_init_possible) - { - /* It is an error to implement a default copy constructor if - (see ARM 12.8 for details) ... one case being if another - copy constructor already exists. */ - tree init_type = TREE_TYPE (init); - if (TREE_CODE (init_type) == REFERENCE_TYPE) - init_type = TREE_TYPE (init_type); - if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type) - || (IS_AGGR_TYPE (init_type) - && UNIQUELY_DERIVED_FROM_P (type, init_type))) - { - if (type == BINFO_TYPE (binfo) - && TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - tree addr = build_unary_op (ADDR_EXPR, exp, 0); - expand_aggr_vbase_init (binfo, exp, addr, NULL_TREE); - - expand_expr_stmt (build_vbase_vtables_init (binfo, binfo, - exp, addr, 1)); - } - expand_expr_stmt (build_modify_expr (exp, INIT_EXPR, init)); - return; - } - else - rval = build_method_call (exp, constructor_name (type), parms, - binfo, flags); - } - - /* Private, protected, or otherwise unavailable. */ - if (rval == error_mark_node && (flags&LOOKUP_COMPLAIN)) - error_with_aggr_type (binfo, "in base initialization for class `%s'"); - /* A valid initialization using constructor. */ - else if (rval != error_mark_node && rval != NULL_TREE) - { - /* p. 222: if the base class assigns to `this', then that - value is used in the derived class. */ - if ((flag_this_is_variable & 1) && alias_this) - { - TREE_TYPE (rval) = TREE_TYPE (current_class_decl); - expand_assignment (current_class_decl, rval, 0, 0); - } - else - expand_expr_stmt (rval); - } - else if (parms && TREE_CHAIN (parms) == NULL_TREE) - { - /* If we are initializing one aggregate value - from another, and though there are constructors, - and none accept the initializer, just do a bitwise - copy. - - The above sounds wrong, ``If a class has any copy - constructor defined, the default copy constructor will - not be generated.'' 12.8 Copying Class Objects (mrs) - - @@ This should reject initializer which a constructor - @@ rejected on visibility gounds, but there is - @@ no way right now to recognize that case with - @@ just `error_mark_node'. */ - tree itype; - init = TREE_VALUE (parms); - itype = TREE_TYPE (init); - if (TREE_CODE (itype) == REFERENCE_TYPE) - { - init = convert_from_reference (init); - itype = TREE_TYPE (init); - } - itype = TYPE_MAIN_VARIANT (itype); - - /* This is currently how the default X(X&) constructor - is implemented. */ - if (comptypes (TYPE_MAIN_VARIANT (type), itype, 0)) - { -#if 0 - warning ("bitwise copy in initialization of type `%s'", - TYPE_NAME_STRING (type)); -#endif - rval = build (INIT_EXPR, type, exp, init); - expand_expr_stmt (rval); - } - else - { - error_with_aggr_type (binfo, "in base initialization for class `%s',"); - error_with_aggr_type (type, "invalid initializer to constructor for type `%s'"); - return; - } - } - else - { - if (init == NULL_TREE) - my_friendly_assert (parms == NULL_TREE, 210); - if (parms == NULL_TREE && TREE_VIA_VIRTUAL (binfo)) - error_with_aggr_type (binfo, "virtual baseclass `%s' does not have default initializer"); - else - { - error_with_aggr_type (binfo, "in base initialization for class `%s',"); - /* This will make an error message for us. */ - build_method_call (exp, constructor_name (type), parms, binfo, - (TYPE_USES_VIRTUAL_BASECLASSES (type) - ? LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE - : LOOKUP_NORMAL)); - } - return; - } - /* Constructor has been called, but vtables may be for TYPE - rather than for FOR_TYPE. */ -} - -/* This function is responsible for initializing EXP with INIT - (if any). - - BINFO is the binfo of the type for who we are performing the - initialization. For example, if W is a virtual base class of A and B, - and C : A, B. - If we are initializing B, then W must contain B's W vtable, whereas - were we initializing C, W must contain C's W vtable. - - TRUE_EXP is nonzero if it is the true expression being initialized. - In this case, it may be EXP, or may just contain EXP. The reason we - need this is because if EXP is a base element of TRUE_EXP, we - don't necessarily know by looking at EXP where its virtual - baseclass fields should really be pointing. But we do know - from TRUE_EXP. In constructors, we don't know anything about - the value being initialized. - - ALIAS_THIS serves the same purpose it serves for expand_aggr_init. - - FLAGS is just passes to `build_method_call'. See that function for - its description. */ - -static void -expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) - tree binfo; - tree true_exp, exp; - tree init; - int alias_this; - int flags; -{ - tree type = TREE_TYPE (exp); - tree init_type = NULL_TREE; - tree rval; - - my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); - - /* Use a function returning the desired type to initialize EXP for us. - If the function is a constructor, and its first argument is - NULL_TREE, know that it was meant for us--just slide exp on - in and expand the constructor. Constructors now come - as TARGET_EXPRs. */ - if (init) - { - tree init_list = NULL_TREE; - - if (TREE_CODE (init) == TREE_LIST) - { - init_list = init; - if (TREE_CHAIN (init) == NULL_TREE) - init = TREE_VALUE (init); - } - - init_type = TREE_TYPE (init); - - if (TREE_CODE (init) != TREE_LIST) - { - if (TREE_CODE (init_type) == ERROR_MARK) - return; - -#if 0 - /* These lines are found troublesome 5/11/89. */ - if (TREE_CODE (init_type) == REFERENCE_TYPE) - init_type = TREE_TYPE (init_type); -#endif - - /* This happens when we use C++'s functional cast notation. - If the types match, then just use the TARGET_EXPR - directly. Otherwise, we need to create the initializer - separately from the object being initialized. */ - if (TREE_CODE (init) == TARGET_EXPR) - { - if (init_type == type) - { - if (TREE_CODE (exp) == VAR_DECL - || TREE_CODE (exp) == RESULT_DECL) - /* Unify the initialization targets. */ - DECL_RTL (TREE_OPERAND (init, 0)) = DECL_RTL (exp); - else - DECL_RTL (TREE_OPERAND (init, 0)) = expand_expr (exp, NULL_RTX, 0, 0); - - expand_expr_stmt (init); - return; - } - else - { - init = TREE_OPERAND (init, 1); - init = build (CALL_EXPR, init_type, - TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0); - TREE_SIDE_EFFECTS (init) = 1; -#if 0 - TREE_RAISES (init) = ?? -#endif - if (init_list) - TREE_VALUE (init_list) = init; - } - } - - if (init_type == type && TREE_CODE (init) == CALL_EXPR -#if 0 - /* It is legal to directly initialize from a CALL_EXPR - without going through X(X&), apparently. */ - && ! TYPE_GETS_INIT_REF (type) -#endif - ) - { - /* A CALL_EXPR is a legitimate form of initialization, so - we should not print this warning message. */ -#if 0 - /* Should have gone away due to 5/11/89 change. */ - if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE) - init = convert_from_reference (init); -#endif - expand_assignment (exp, init, 0, 0); - if (exp == DECL_RESULT (current_function_decl)) - { - /* Failing this assertion means that the return value - from receives multiple initializations. */ - my_friendly_assert (DECL_INITIAL (exp) == NULL_TREE - || DECL_INITIAL (exp) == error_mark_node, - 212); - DECL_INITIAL (exp) = init; - } - return; - } - else if (init_type == type - && TREE_CODE (init) == COND_EXPR) - { - /* Push value to be initialized into the cond, where possible. - Avoid spurious warning messages when initializing the - result of this function. */ - TREE_OPERAND (init, 1) - = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 1)); - if (exp == DECL_RESULT (current_function_decl)) - DECL_INITIAL (exp) = NULL_TREE; - TREE_OPERAND (init, 2) - = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 2)); - if (exp == DECL_RESULT (current_function_decl)) - DECL_INITIAL (exp) = init; - expand_expr (init, const0_rtx, VOIDmode, 0); - free_temp_slots (); - return; - } - } - - /* We did not know what we were initializing before. Now we do. */ - if (TREE_CODE (init) == TARGET_EXPR) - { - tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1); - - if (TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR - && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node) - { - /* In order for this to work for RESULT_DECLs, if their - type has a constructor, then they must be BLKmode - so that they will be meaningfully addressable. */ - tree arg = build_unary_op (ADDR_EXPR, exp, 0); - init = TREE_OPERAND (init, 1); - init = build (CALL_EXPR, build_pointer_type (TREE_TYPE (init)), - TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0); - TREE_SIDE_EFFECTS (init) = 1; -#if 0 - TREE_RAISES (init) = ?? -#endif - TREE_VALUE (TREE_OPERAND (init, 1)) - = convert_pointer_to (TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))), arg); - - if (alias_this) - { - expand_assignment (current_function_decl, init, 0, 0); - return; - } - if (exp == DECL_RESULT (current_function_decl)) - { - if (DECL_INITIAL (DECL_RESULT (current_function_decl))) - fatal ("return value from function receives multiple initializations"); - DECL_INITIAL (exp) = init; - } - expand_expr_stmt (init); - return; - } - } - - /* Handle this case: when calling a constructor: xyzzy foo(bar); - which really means: xyzzy foo = bar; Ugh! - - We can also be called with an initializer for an object - which has virtual functions, but no constructors. In that - case, we perform the assignment first, then initialize - the virtual function table pointer fields. */ - - if (! TYPE_NEEDS_CONSTRUCTING (type)) - { - if (init_list && TREE_CHAIN (init_list)) - { - warning ("initializer list being treated as compound expression"); - init = convert (TREE_TYPE (exp), build_compound_expr (init_list)); - if (init == error_mark_node) - return; - } - if (TREE_CODE (exp) == VAR_DECL - && TREE_CODE (init) == CONSTRUCTOR - && TREE_HAS_CONSTRUCTOR (init) - && flag_pic == 0) - store_init_value (exp, init); - else - expand_assignment (exp, init, 0, 0); - - if (TYPE_VIRTUAL_P (type)) - expand_recursive_init (binfo, true_exp, exp, init, CLASSTYPE_BASE_INIT_LIST (type), alias_this); - return; - } - - /* See whether we can go through a type conversion operator. - This wins over going through a non-existent constructor. If - there is a constructor, it is ambiguous. */ - if (TREE_CODE (init) != TREE_LIST) - { - tree ttype = TREE_CODE (init_type) == REFERENCE_TYPE - ? TREE_TYPE (init_type) : init_type; - - if (ttype != type && IS_AGGR_TYPE (ttype)) - { - tree rval = build_type_conversion (CONVERT_EXPR, type, init, 0); - - if (rval) - { - /* See if there is a constructor for``type'' that takes a - ``ttype''-typed object. */ - tree parms = build_tree_list (NULL_TREE, init); - tree as_cons = NULL_TREE; - if (TYPE_HAS_CONSTRUCTOR (type)) - as_cons = build_method_call (exp, constructor_name (type), - parms, binfo, - LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION); - if (as_cons != NULL_TREE && as_cons != error_mark_node) - { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */ - error ("ambiguity between conversion to `%s' and constructor", - IDENTIFIER_POINTER (name)); - } - else - expand_assignment (exp, rval, 0, 0); - return; - } - } - } - } - - /* Handle default copy constructors here, does not matter if there is - a constructor or not. */ - if (type == init_type && IS_AGGR_TYPE (type) - && init && TREE_CODE (init) != TREE_LIST) - expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags); - /* Not sure why this is here... */ - else if (TYPE_HAS_CONSTRUCTOR (type)) - expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags); - else if (TREE_CODE (type) == ARRAY_TYPE) - { - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))) - expand_vec_init (exp, exp, array_type_nelts (type), init, 0); - else if (TYPE_VIRTUAL_P (TREE_TYPE (type))) - sorry ("arrays of objects with virtual functions but no constructors"); - } - else - expand_recursive_init (binfo, true_exp, exp, init, - CLASSTYPE_BASE_INIT_LIST (type), alias_this); -} - -/* A pointer which holds the initializer. First call to - expand_aggr_init gets this value pointed to, and sets it to init_null. */ -static tree *init_ptr, init_null; - -/* Subroutine of expand_recursive_init: - - ADDR is the address of the expression being initialized. - INIT_LIST is the cons-list of initializations to be performed. - ALIAS_THIS is its same, lovable self. */ -static void -expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this) - tree binfo, true_exp, addr; - tree init_list; - int alias_this; -{ - while (init_list) - { - if (TREE_PURPOSE (init_list)) - { - if (TREE_CODE (TREE_PURPOSE (init_list)) == FIELD_DECL) - { - tree member = TREE_PURPOSE (init_list); - tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), 0); - tree member_base = build (COMPONENT_REF, TREE_TYPE (member), subexp, member); - if (IS_AGGR_TYPE (TREE_TYPE (member))) - expand_aggr_init (member_base, DECL_INITIAL (member), 0); - else if (TREE_CODE (TREE_TYPE (member)) == ARRAY_TYPE - && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (member))) - { - member_base = save_expr (default_conversion (member_base)); - expand_vec_init (member, member_base, - array_type_nelts (TREE_TYPE (member)), - DECL_INITIAL (member), 0); - } - else expand_expr_stmt (build_modify_expr (member_base, INIT_EXPR, DECL_INITIAL (member))); - } - else if (TREE_CODE (TREE_PURPOSE (init_list)) == TREE_LIST) - { - expand_recursive_init_1 (binfo, true_exp, addr, TREE_PURPOSE (init_list), alias_this); - expand_recursive_init_1 (binfo, true_exp, addr, TREE_VALUE (init_list), alias_this); - } - else if (TREE_CODE (TREE_PURPOSE (init_list)) == ERROR_MARK) - { - /* Only initialize the virtual function tables if we - are initializing the ultimate users of those vtables. */ - if (TREE_VALUE (init_list)) - { - /* We have to ensure that the second argment to - build_virtual_init is in binfo's hierarchy. */ - expand_expr_stmt (build_virtual_init (binfo, - get_binfo (TREE_VALUE (init_list), binfo, 0), - addr)); - if (TREE_VALUE (init_list) == binfo - && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))) - expand_expr_stmt (build_vbase_vtables_init (binfo, binfo, true_exp, addr, 1)); - } - } - else my_friendly_abort (49); - } - else if (TREE_VALUE (init_list) - && TREE_CODE (TREE_VALUE (init_list)) == TREE_VEC) - { - tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), 0); - expand_aggr_init_1 (binfo, true_exp, subexp, *init_ptr, - alias_this && BINFO_OFFSET_ZEROP (TREE_VALUE (init_list)), - LOOKUP_PROTECTED_OK|LOOKUP_COMPLAIN); - - /* INIT_PTR is used up. */ - init_ptr = &init_null; - } - else - my_friendly_abort (50); - init_list = TREE_CHAIN (init_list); - } -} - -/* Initialize EXP with INIT. Type EXP does not have a constructor, - but it has a baseclass with a constructor or a virtual function - table which needs initializing. - - INIT_LIST is a cons-list describing what parts of EXP actually - need to be initialized. INIT is given to the *unique*, first - constructor within INIT_LIST. If there are multiple first - constructors, such as with multiple inheritance, INIT must - be zero or an ambiguity error is reported. - - ALIAS_THIS is passed from `expand_aggr_init'. See comments - there. */ - -static void -expand_recursive_init (binfo, true_exp, exp, init, init_list, alias_this) - tree binfo, true_exp, exp, init; - tree init_list; - int alias_this; -{ - tree *old_init_ptr = init_ptr; - tree addr = build_unary_op (ADDR_EXPR, exp, 0); - init_ptr = &init; - - if (true_exp == exp && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))) - { - expand_aggr_vbase_init (binfo, exp, addr, init_list); - expand_expr_stmt (build_vbase_vtables_init (binfo, binfo, true_exp, addr, 1)); - } - expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this); - - if (*init_ptr) - { - tree type = TREE_TYPE (exp); - - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - if (IS_AGGR_TYPE (type)) - error_with_aggr_type (type, "unexpected argument to constructor `%s'"); - else - error ("unexpected argument to constructor"); - } - init_ptr = old_init_ptr; -} - -/* Report an error if NAME is not the name of a user-defined, - aggregate type. If OR_ELSE is nonzero, give an error message. */ -int -is_aggr_typedef (name, or_else) - tree name; - int or_else; -{ - tree type; - - if (name == error_mark_node) - return 0; - - if (! IDENTIFIER_HAS_TYPE_VALUE (name)) - { - if (or_else) - error ("`%s' fails to be an aggregate typedef", - IDENTIFIER_POINTER (name)); - return 0; - } - type = IDENTIFIER_TYPE_VALUE (name); - if (! IS_AGGR_TYPE (type)) - { - if (or_else) - error ("type `%s' is of non-aggregate type", - IDENTIFIER_POINTER (name)); - return 0; - } - return 1; -} - -/* This code could just as well go in `cp-class.c', but is placed here for - modularity. */ - -/* For an expression of the form CNAME :: NAME (PARMLIST), build - the appropriate function call. */ -tree -build_member_call (cname, name, parmlist) - tree cname, name, parmlist; -{ - tree type, t; - tree method_name = name; - int dtor = 0; - int dont_use_this = 0; - tree basetype_path, decl; - - if (TREE_CODE (method_name) == BIT_NOT_EXPR) - { - method_name = TREE_OPERAND (method_name, 0); - dtor = 1; - } - - if (TREE_CODE (cname) == SCOPE_REF) - cname = resolve_scope_to_name (NULL_TREE, cname); - - if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1)) - return error_mark_node; - - /* An operator we did not like. */ - if (name == NULL_TREE) - return error_mark_node; - - if (dtor) - { - if (! TYPE_HAS_DESTRUCTOR (IDENTIFIER_TYPE_VALUE (cname))) - error ("type `%s' does not have a destructor", - IDENTIFIER_POINTER (cname)); - else - error ("destructor specification error"); - return error_mark_node; - } - - type = IDENTIFIER_TYPE_VALUE (cname); - - /* No object? Then just fake one up, and let build_method_call - figure out what to do. */ - if (current_class_type == 0 - || get_base_distance (type, current_class_type, 0, &basetype_path) == -1) - dont_use_this = 1; - - if (dont_use_this) - { - basetype_path = NULL_TREE; - decl = build1 (NOP_EXPR, TYPE_POINTER_TO (type), error_mark_node); - } - else if (current_class_decl == 0) - { - dont_use_this = 1; - decl = build1 (NOP_EXPR, TYPE_POINTER_TO (type), error_mark_node); - } - else - { - decl = current_class_decl; - if (TREE_TYPE (decl) != type) - decl = convert (TYPE_POINTER_TO (type), decl); - } - - if (t = lookup_fnfields (TYPE_BINFO (type), method_name, 0)) - return build_method_call (decl, method_name, parmlist, basetype_path, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); - if (TREE_CODE (name) == IDENTIFIER_NODE - && (t = lookup_field (TYPE_BINFO (type), name, 1, 0))) - { - if (t == error_mark_node) - return error_mark_node; - if (TREE_CODE (t) == FIELD_DECL) - { - if (dont_use_this) - { - error ("invalid use of non-static field `%s'", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t); - } - else if (TREE_CODE (t) == VAR_DECL) - decl = t; - else - { - error ("invalid use of member `%s::%s'", - IDENTIFIER_POINTER (cname), name); - return error_mark_node; - } - if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)) - && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl))) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE); - return build_function_call (decl, parmlist); - } - else - { - char *err_name; - if (TREE_CODE (name) == IDENTIFIER_NODE) - { - if (IDENTIFIER_OPNAME_P (name)) - { - char *op_name = operator_name_string (method_name); - err_name = (char *)alloca (13 + strlen (op_name)); - sprintf (err_name, "operator %s", op_name); - } - else - err_name = IDENTIFIER_POINTER (name); - } - else - my_friendly_abort (51); - - error ("no method `%s::%s'", IDENTIFIER_POINTER (cname), err_name); - return error_mark_node; - } -} - -/* Build a reference to a member of an aggregate. This is not a - C++ `&', but really something which can have its address taken, - and then act as a pointer to member, for example CNAME :: FIELD - can have its address taken by saying & CNAME :: FIELD. - - @@ Prints out lousy diagnostics for operator - @@ fields. - - @@ This function should be rewritten and placed in cp-search.c. */ -tree -build_offset_ref (cname, name) - tree cname, name; -{ - tree decl, type, fnfields, fields, t = error_mark_node; - tree basetypes = NULL_TREE; - int dtor = 0; - - if (TREE_CODE (cname) == SCOPE_REF) - cname = resolve_scope_to_name (NULL_TREE, cname); - - if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1)) - return error_mark_node; - - type = IDENTIFIER_TYPE_VALUE (cname); - - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - dtor = 1; - name = TREE_OPERAND (name, 0); - } - - if (TYPE_SIZE (type) == 0) - { - t = IDENTIFIER_CLASS_VALUE (name); - if (t == 0) - { - error_with_aggr_type (type, "incomplete type `%s' does not have member `%s'", IDENTIFIER_POINTER (name)); - return error_mark_node; - } - if (TREE_CODE (t) == TYPE_DECL) - { - error_with_decl (t, "member `%s' is just a type declaration"); - return error_mark_node; - } - if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) - { - TREE_USED (t) = 1; - return t; - } - if (TREE_CODE (t) == FIELD_DECL) - sorry ("use of member in incomplete aggregate type"); - else if (TREE_CODE (t) == FUNCTION_DECL) - sorry ("use of member function in incomplete aggregate type"); - else - my_friendly_abort (52); - return error_mark_node; - } - - if (TREE_CODE (name) == TYPE_EXPR) - /* Pass a TYPE_DECL to build_component_type_expr. */ - return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)), - name, NULL_TREE, 1); - - fnfields = lookup_fnfields (TYPE_BINFO (type), name, 1); - fields = lookup_field (type, name, 0, 0); - - if (fields == error_mark_node || fnfields == error_mark_node) - return error_mark_node; - - if (current_class_type == 0 - || get_base_distance (type, current_class_type, 0, &basetypes) == -1) - { - basetypes = TYPE_BINFO (type); - decl = build1 (NOP_EXPR, - IDENTIFIER_TYPE_VALUE (cname), - error_mark_node); - } - else if (current_class_decl == 0) - decl = build1 (NOP_EXPR, IDENTIFIER_TYPE_VALUE (cname), - error_mark_node); - else decl = C_C_D; - - /* A lot of this logic is now handled in lookup_field and - lookup_fnfield. */ - if (fnfields) - { - basetypes = TREE_PURPOSE (fnfields); - - /* Go from the TREE_BASELINK to the member function info. */ - t = TREE_VALUE (fnfields); - - if (fields) - { - if (DECL_FIELD_CONTEXT (fields) == DECL_FIELD_CONTEXT (t)) - { - error ("ambiguous member reference: member `%s' defined as both field and function", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (fields), DECL_FIELD_CONTEXT (t))) - ; - else if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (t), DECL_FIELD_CONTEXT (fields))) - t = fields; - else - { - error ("ambiguous member reference: member `%s' derives from distinct classes in multiple inheritance lattice"); - return error_mark_node; - } - } - - if (t == TREE_VALUE (fnfields)) - { - extern int flag_save_memoized_contexts; - - /* This does not handle visibility checking yet. */ - if (DECL_CHAIN (t) == NULL_TREE || dtor) - { - enum visibility_type visibility; - - /* unique functions are handled easily. */ - unique: - visibility = compute_visibility (basetypes, t); - if (visibility == visibility_protected) - { - error_with_decl (t, "member function `%s' is protected"); - error ("in this context"); - return error_mark_node; - } - if (visibility == visibility_private) - { - error_with_decl (t, "member function `%s' is private"); - error ("in this context"); - return error_mark_node; - } - assemble_external (t); - return build (OFFSET_REF, TREE_TYPE (t), decl, t); - } - - /* overloaded functions may need more work. */ - if (cname == name) - { - if (TYPE_HAS_DESTRUCTOR (type) - && DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE) - { - t = DECL_CHAIN (t); - goto unique; - } - } - /* FNFIELDS is most likely allocated on the search_obstack, - which will go away after this class scope. If we need - to save this value for later (either for memoization - or for use as an initializer for a static variable), then - do so here. - - ??? The smart thing to do for the case of saving initializers - is to resolve them before we're done with this scope. */ - if (!TREE_PERMANENT (fnfields) - && ((flag_save_memoized_contexts && global_bindings_p ()) - || ! allocation_temporary_p ())) - fnfields = copy_list (fnfields); - t = build_tree_list (error_mark_node, fnfields); - TREE_TYPE (t) = build_offset_type (type, unknown_type_node); - return t; - } - } - - /* Now that we know we are looking for a field, see if we - have access to that field. Lookup_field will give us the - error message. */ - - t = lookup_field (basetypes, name, 1, 0); - - if (t == error_mark_node) - return error_mark_node; - - if (t == NULL_TREE) - { - char *print_name, *non_operator = "<"; - - if (name == ansi_opname[(int) TYPE_EXPR]) - { - error ("type conversion operator not a member of type `%s'", - IDENTIFIER_POINTER (cname)); - return error_mark_node; - } - - if ((IDENTIFIER_POINTER (name))[0] == '_' - && (IDENTIFIER_POINTER (name))[1] == '_') - print_name = operator_name_string (name); - else - print_name = non_operator; - - /* First character of "". */ - if (print_name[0] == '<') - error ("field `%s' is not a member of type `%s'", - IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (cname)); - else - error ("operator `%s' is not a member of type `%s'", - print_name, IDENTIFIER_POINTER (cname)); - return error_mark_node; - } - - if (TREE_CODE (t) == TYPE_DECL) - { - error_with_decl (t, "member `%s' is just a type declaration"); - return error_mark_node; - } - /* static class members and class-specific enum - values can be returned without further ado. */ - if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) - { - assemble_external (t); - TREE_USED (t) = 1; - return t; - } - - /* static class functions too. */ - if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - my_friendly_abort (53); - - /* In member functions, the form `cname::name' is no longer - equivalent to `this->cname::name'. */ - return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t); -} - -/* Given an object EXP and a member function reference MEMBER, - return the address of the actual member function. */ -tree -get_member_function (exp_addr_ptr, exp, member) - tree *exp_addr_ptr; - tree exp, member; -{ - tree ctype = TREE_TYPE (exp); - tree function = save_expr (build_unary_op (ADDR_EXPR, member, 0)); - - if (TYPE_VIRTUAL_P (ctype) - || (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (ctype))) - { - tree e0, e1, e3; - tree exp_addr; - - /* Save away the unadulterated `this' pointer. */ - exp_addr = save_expr (*exp_addr_ptr); - - /* Cast function to signed integer. */ - e0 = build1 (NOP_EXPR, integer_type_node, function); - -#ifdef VTABLE_USES_MASK - /* If we are willing to limit the number of - virtual functions a class may have to some - *small* number, then if, for a function address, - we are passed some small number, we know that - it is a virtual function index, and work from there. */ - e1 = build (BIT_AND_EXPR, integer_type_node, e0, vtbl_mask); -#else - /* There is a hack here that takes advantage of - twos complement arithmetic, and the fact that - there are more than one UNITS to the WORD. - If the high bit is set for the `function', - then we pretend it is a virtual function, - and the array indexing will knock this bit - out the top, leaving a valid index. */ - if (UNITS_PER_WORD <= 1) - my_friendly_abort (54); - - e1 = build (GT_EXPR, integer_type_node, e0, integer_zero_node); - e1 = build_compound_expr (tree_cons (NULL_TREE, exp_addr, - build_tree_list (NULL_TREE, e1))); - e1 = save_expr (e1); -#endif - - if (TREE_SIDE_EFFECTS (*exp_addr_ptr)) - { - exp = build_indirect_ref (exp_addr, 0); - *exp_addr_ptr = exp_addr; - } - - /* This is really hairy: if the function pointer is a pointer - to a non-virtual member function, then we can't go mucking - with the `this' pointer (any more than we already have to - this point). If it is a pointer to a virtual member function, - then we have to adjust the `this' pointer according to - what the virtual function table tells us. */ - - e3 = build_vfn_ref (exp_addr_ptr, exp, e0); - my_friendly_assert (e3 != error_mark_node, 213); - - /* Change this pointer type from `void *' to the - type it is really supposed to be. */ - TREE_TYPE (e3) = TREE_TYPE (function); - - /* If non-virtual, use what we had originally. Otherwise, - use the value we get from the virtual function table. */ - *exp_addr_ptr = build_conditional_expr (e1, exp_addr, *exp_addr_ptr); - - function = build_conditional_expr (e1, function, e3); - } - return build_indirect_ref (function, 0); -} - -/* If a OFFSET_REF made it through to here, then it did - not have its address taken. */ - -tree -resolve_offset_ref (exp) - tree exp; -{ - tree type = TREE_TYPE (exp); - tree base = NULL_TREE; - tree member; - tree basetype, addr; - - if (TREE_CODE (exp) == TREE_LIST) - return build_unary_op (ADDR_EXPR, exp, 0); - - if (TREE_CODE (exp) != OFFSET_REF) - { - my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214); - if (TYPE_OFFSET_BASETYPE (type) != current_class_type) - { - error ("object missing in use of pointer-to-member construct"); - return error_mark_node; - } - member = exp; - type = TREE_TYPE (type); - base = C_C_D; - } - else - { - member = TREE_OPERAND (exp, 1); - base = TREE_OPERAND (exp, 0); - } - - if (TREE_CODE (member) == VAR_DECL - || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) - { - /* These were static members. */ - if (mark_addressable (member) == 0) - return error_mark_node; - return member; - } - - /* Syntax error can cause a member which should - have been seen as static to be grok'd as non-static. */ - if (TREE_CODE (member) == FIELD_DECL && C_C_D == NULL_TREE) - { - if (TREE_ADDRESSABLE (member) == 0) - { - error_with_decl (member, "member `%s' is non-static in static member function context"); - error ("at this point in file"); - TREE_ADDRESSABLE (member) = 1; - } - return error_mark_node; - } - - /* The first case is really just a reference to a member of `this'. */ - if (TREE_CODE (member) == FIELD_DECL - && (base == C_C_D - || (TREE_CODE (base) == NOP_EXPR - && TREE_OPERAND (base, 0) == error_mark_node))) - { - tree basetype_path; - enum visibility_type visibility; - - basetype = DECL_CONTEXT (member); - if (get_base_distance (basetype, current_class_type, 0, &basetype_path) < 0) - { - error_not_base_type (basetype, current_class_type); - return error_mark_node; - } - addr = convert_pointer_to (basetype, current_class_decl); - visibility = compute_visibility (basetype_path, member); - if (visibility == visibility_public) - return build (COMPONENT_REF, TREE_TYPE (member), - build_indirect_ref (addr, 0), member); - if (visibility == visibility_protected) - { - error_with_decl (member, "member `%s' is protected"); - error ("in this context"); - return error_mark_node; - } - if (visibility == visibility_private) - { - error_with_decl (member, "member `%s' is private"); - error ("in this context"); - return error_mark_node; - } - my_friendly_abort (55); - } - - /* If this is a reference to a member function, then return - the address of the member function (which may involve going - through the object's vtable), otherwise, return an expression - for the dereferenced pointer-to-member construct. */ - addr = build_unary_op (ADDR_EXPR, base, 0); - - if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) - { - basetype = DECL_CLASS_CONTEXT (member); - addr = convert_pointer_to (basetype, addr); - return build_unary_op (ADDR_EXPR, get_member_function (&addr, build_indirect_ref (addr, 0), member), 0); - } - else if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE) - { - basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); - addr = convert_pointer_to (basetype, addr); - member = convert (ptr_type_node, build_unary_op (ADDR_EXPR, member, 0)); - return build1 (INDIRECT_REF, type, - build (PLUS_EXPR, ptr_type_node, addr, member)); - } - my_friendly_abort (56); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Return either DECL or its known constant value (if it has one). */ - -tree -decl_constant_value (decl) - tree decl; -{ - if (! TREE_THIS_VOLATILE (decl) -#if 0 - /* These may be necessary for C, but they break C++. */ - ! TREE_PUBLIC (decl) - /* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. */ - && ! pedantic -#endif /* 0 */ - && DECL_INITIAL (decl) != 0 - && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK - /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ - && TREE_CONSTANT (DECL_INITIAL (decl)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR -#if 0 - /* We must allow this to work outside of functions so that - static constants can be used for array sizes. */ - && current_function_decl != 0 - && DECL_MODE (decl) != BLKmode -#endif - ) - return DECL_INITIAL (decl); - return decl; -} - -/* Friend handling routines. */ -/* Friend data structures: - - Friend lists come from TYPE_DECL nodes. Since all aggregate - types are automatically typedef'd, these node are guaranteed - to exist. - - The TREE_PURPOSE of a friend list is the name of the friend, - and its TREE_VALUE is another list. - - The TREE_PURPOSE of that list is a type, which allows - all functions of a given type to be friends. - The TREE_VALUE of that list is an individual function - which is a friend. - - Non-member friends will match only by their DECL. Their - member type is NULL_TREE, while the type of the inner - list will either be of aggregate type or error_mark_node. */ - -/* Tell if this function specified by DECL - can be a friend of type TYPE. - Return nonzero if friend, zero otherwise. - - DECL can be zero if we are calling a constructor or accessing a - member in global scope. */ -int -is_friend (type, decl) - tree type, decl; -{ - tree typedecl = TYPE_NAME (type); - tree ctype; - tree list; - tree name; - - if (decl == NULL_TREE) - return 0; - - ctype = DECL_CLASS_CONTEXT (decl); - if (ctype) - { - list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (typedecl)); - while (list) - { - if (ctype == TREE_VALUE (list)) - return 1; - list = TREE_CHAIN (list); - } - } - - list = DECL_FRIENDLIST (typedecl); - name = DECL_NAME (decl); - while (list) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - name = DECL_ASSEMBLER_NAME (decl); - while (friends) - { - if (ctype == TREE_PURPOSE (friends)) - return 1; - if (name == DECL_ASSEMBLER_NAME (TREE_VALUE (friends))) - return 1; - friends = TREE_CHAIN (friends); - } - return 0; - } - list = TREE_CHAIN (list); - } - return 0; -} - -/* Add a new friend to the friends of the aggregate type TYPE. - DECL is the FUNCTION_DECL of the friend being added. */ -static void -add_friend (type, decl) - tree type, decl; -{ - tree typedecl = TYPE_NAME (type); - tree list = DECL_FRIENDLIST (typedecl); - tree name = DECL_NAME (decl); - tree ctype = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE - ? DECL_CLASS_CONTEXT (decl) : error_mark_node; - - while (list) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - while (friends) - { - if (decl == TREE_VALUE (friends)) - { - warning_with_decl (decl, "`%s' is already a friend of class `%s'", IDENTIFIER_POINTER (DECL_NAME (typedecl))); - return; - } - friends = TREE_CHAIN (friends); - } - TREE_VALUE (list) = tree_cons (ctype, decl, TREE_VALUE (list)); - return; - } - list = TREE_CHAIN (list); - } - DECL_FRIENDLIST (typedecl) - = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), - DECL_FRIENDLIST (typedecl)); - if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - TYPE_GETS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - if (parmtypes && TREE_CHAIN (parmtypes)) - { - tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes)); - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl)) - { - TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; - TYPE_GETS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; - } - } - } -} - -/* Declare that every member function NAME in FRIEND_TYPE - (which may be NULL_TREE) is a friend of type TYPE. */ -static void -add_friends (type, name, friend_type) - tree type, name, friend_type; -{ - tree typedecl = TYPE_NAME (type); - tree list = DECL_FRIENDLIST (typedecl); - - while (list) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - while (friends && TREE_PURPOSE (friends) != friend_type) - friends = TREE_CHAIN (friends); - if (friends) - if (friend_type) - warning ("method `%s::%s' is already a friend of class", - TYPE_NAME_STRING (friend_type), - IDENTIFIER_POINTER (name)); - else - warning ("function `%s' is already a friend of class `%s'", - IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (DECL_NAME (typedecl))); - else - TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE, - TREE_VALUE (list)); - return; - } - list = TREE_CHAIN (list); - } - DECL_FRIENDLIST (typedecl) = - tree_cons (name, - build_tree_list (friend_type, NULL_TREE), - DECL_FRIENDLIST (typedecl)); - if (! strncmp (IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]), - strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR])))) - { - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - TYPE_GETS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists"); - } -} - -/* Set up a cross reference so that type TYPE will - make member function CTYPE::DECL a friend when CTYPE - is finally defined. */ -void -xref_friend (type, decl, ctype) - tree type, decl, ctype; -{ - tree typedecl = TYPE_NAME (type); - tree friend_decl = TYPE_NAME (ctype); - tree t = tree_cons (NULL_TREE, ctype, DECL_UNDEFINED_FRIENDS (typedecl)); - - DECL_UNDEFINED_FRIENDS (typedecl) = t; - SET_DECL_WAITING_FRIENDS (friend_decl, tree_cons (type, t, DECL_WAITING_FRIENDS (friend_decl))); - TREE_TYPE (DECL_WAITING_FRIENDS (friend_decl)) = decl; -} - -/* Set up a cross reference so that functions with name NAME and - type CTYPE know that they are friends of TYPE. */ -void -xref_friends (type, name, ctype) - tree type, name, ctype; -{ - tree typedecl = TYPE_NAME (type); - tree friend_decl = TYPE_NAME (ctype); - tree t = tree_cons (NULL_TREE, ctype, - DECL_UNDEFINED_FRIENDS (typedecl)); - - DECL_UNDEFINED_FRIENDS (typedecl) = t; - SET_DECL_WAITING_FRIENDS (friend_decl, tree_cons (type, t, DECL_WAITING_FRIENDS (friend_decl))); - TREE_TYPE (DECL_WAITING_FRIENDS (friend_decl)) = name; -} - -/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already - been defined, we make all of its member functions friends of - TYPE. If not, we make it a pending friend, which can later be added - when its definition is seen. If a type is defined, then its TYPE_DECL's - DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend - classes that are not defined. If a type has not yet been defined, - then the DECL_WAITING_FRIENDS contains a list of types - waiting to make it their friend. Note that these two can both - be in use at the same time! */ -void -make_friend_class (type, friend_type) - tree type, friend_type; -{ - tree classes; - - if (type == friend_type) - { - warning ("class `%s' is implicitly friends with itself", - TYPE_NAME_STRING (type)); - return; - } - - GNU_xref_hier (TYPE_NAME_STRING (type), - TYPE_NAME_STRING (friend_type), 0, 0, 1); - - classes = CLASSTYPE_FRIEND_CLASSES (type); - while (classes && TREE_VALUE (classes) != friend_type) - classes = TREE_CHAIN (classes); - if (classes) - warning ("class `%s' is already friends with class `%s'", - TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type)); - else - { - CLASSTYPE_FRIEND_CLASSES (type) - = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); - } -} - -/* Main friend processor. This is large, and for modularity purposes, - has been removed from grokdeclarator. It returns `void_type_node' - to indicate that something happened, though a FIELD_DECL is - not returned. - - CTYPE is the class this friend belongs to. - - DECLARATOR is the name of the friend. - - DECL is the FUNCTION_DECL that the friend is. - - In case we are parsing a friend which is part of an inline - definition, we will need to store PARM_DECL chain that comes - with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL. - - FLAGS is just used for `grokclassfn'. - - QUALS say what special qualifies should apply to the object - pointed to by `this'. */ -tree -do_friend (ctype, declarator, decl, parmdecls, flags, quals) - tree ctype, declarator, decl, parmdecls; - enum overload_flags flags; - tree quals; -{ - /* first, lets find out if what we are making a friend needs overloading */ - tree previous_decl; - int was_c_linkage = 0; - /* if we find something in scope, let see if it has extern "C" linkage */ - /* This code is pretty general and should be ripped out and reused - as a separate function. */ - if (DECL_NAME (decl)) - { - previous_decl=lookup_name (DECL_NAME (decl), 0); - if (previous_decl && TREE_CODE (previous_decl) == TREE_LIST) - { - do - { - if (TREE_TYPE (TREE_VALUE (previous_decl)) == TREE_TYPE (decl)) - { - previous_decl = TREE_VALUE (previous_decl); - break; - } - previous_decl = TREE_CHAIN (previous_decl); - } - while (previous_decl); - } - if (previous_decl && TREE_CODE (previous_decl) == FUNCTION_DECL) - if (TREE_TYPE (decl) == TREE_TYPE (previous_decl)) - if (DECL_LANGUAGE (previous_decl) == lang_c) - { - /* it did, so lets not overload this */ - was_c_linkage = 1; - } - } - - if (ctype) - { - tree cname = TYPE_NAME (ctype); - if (TREE_CODE (cname) == TYPE_DECL) - cname = DECL_NAME (cname); - - /* A method friend. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - if (flags == NO_SPECIAL && ctype && declarator == cname) - DECL_CONSTRUCTOR_P (decl) = 1; - - /* This will set up DECL_ARGUMENTS for us. */ - grokclassfn (ctype, cname, decl, flags, quals); - if (TYPE_SIZE (ctype) != 0) - check_classfn (ctype, cname, decl); - - if (TREE_TYPE (decl) != error_mark_node) - { - if (TYPE_SIZE (ctype)) - { - /* We don't call pushdecl here yet, or ever on this - actual FUNCTION_DECL. We must preserve its TREE_CHAIN - until the end. */ - make_decl_rtl (decl, NULL_PTR, 1); - add_friend (current_class_type, decl); - } - else - xref_friend (current_class_type, decl, ctype); - DECL_FRIEND_P (decl) = 1; - } - } - else - { - /* Possibly a bunch of method friends. */ - - /* Get the class they belong to. */ - tree ctype = IDENTIFIER_TYPE_VALUE (cname); - - /* This class is defined, use its methods now. */ - if (TYPE_SIZE (ctype)) - { - tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0); - if (fields) - add_friends (current_class_type, declarator, ctype); - else - error ("method `%s' is not a member of class `%s'", - IDENTIFIER_POINTER (declarator), - IDENTIFIER_POINTER (cname)); - } - else - xref_friends (current_class_type, declarator, ctype); - decl = void_type_node; - } - } - /* never overload C functions */ - else if (TREE_CODE (decl) == FUNCTION_DECL - && ((IDENTIFIER_LENGTH (declarator) == 4 - && IDENTIFIER_POINTER (declarator)[0] == 'm' - && ! strcmp (IDENTIFIER_POINTER (declarator), "main")) - || (IDENTIFIER_LENGTH (declarator) > 10 - && IDENTIFIER_POINTER (declarator)[0] == '_' - && IDENTIFIER_POINTER (declarator)[1] == '_' - && strncmp (IDENTIFIER_POINTER (declarator)+2, - "builtin_", 8) == 0) - || was_c_linkage)) - { - /* raw "main", and builtin functions never gets overloaded, - but they can become friends. */ - TREE_PUBLIC (decl) = 1; - add_friend (current_class_type, decl); - DECL_FRIEND_P (decl) = 1; - if (IDENTIFIER_POINTER (declarator)[0] == '_') - { - if (! strcmp (IDENTIFIER_POINTER (declarator)+10, "new")) - TREE_GETS_NEW (current_class_type) = 0; - else if (! strcmp (IDENTIFIER_POINTER (declarator)+10, "delete")) - TREE_GETS_DELETE (current_class_type) = 0; - } - decl = void_type_node; - } - /* A global friend. - @@ or possibly a friend from a base class ?!? */ - else if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Friends must all go through the overload machinery, - even though they may not technically be overloaded. - - Note that because classes all wind up being top-level - in their scope, their friend wind up in top-level scope as well. */ - DECL_ASSEMBLER_NAME (decl) - = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)), - TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); - DECL_ARGUMENTS (decl) = parmdecls; - - /* We can call pushdecl here, because the TREE_CHAIN of this - FUNCTION_DECL is not needed for other purposes. */ - decl = pushdecl_top_level (decl); - - make_decl_rtl (decl, NULL_PTR, 1); - add_friend (current_class_type, decl); - - if (! TREE_OVERLOADED (declarator) - && IDENTIFIER_GLOBAL_VALUE (declarator) - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (declarator)) == FUNCTION_DECL) - { - error ("friend `%s' implicitly overloaded", - IDENTIFIER_POINTER (declarator)); - error_with_decl (IDENTIFIER_GLOBAL_VALUE (declarator), - "after declaration of non-overloaded `%s'"); - } - DECL_FRIEND_P (decl) = 1; - DECL_OVERLOADED (decl) = 1; - TREE_OVERLOADED (declarator) = 1; - decl = push_overloaded_decl (decl, 1); - } - else - { - /* @@ Should be able to ingest later definitions of this function - before use. */ - tree decl = IDENTIFIER_GLOBAL_VALUE (declarator); - if (decl == NULL_TREE) - { - warning ("implicitly declaring `%s' as struct", - IDENTIFIER_POINTER (declarator)); - decl = xref_tag (record_type_node, declarator, NULL_TREE); - decl = TYPE_NAME (decl); - } - - /* Allow abbreviated declarations of overloaded functions, - but not if those functions are really class names. */ - if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl))) - { - warning ("`friend %s' archaic, use `friend class %s' instead", - IDENTIFIER_POINTER (declarator), - IDENTIFIER_POINTER (declarator)); - decl = TREE_TYPE (TREE_PURPOSE (decl)); - } - - if (TREE_CODE (decl) == TREE_LIST) - add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE); - else - make_friend_class (current_class_type, TREE_TYPE (decl)); - decl = void_type_node; - } - return decl; -} - -/* TYPE has now been defined. It may, however, have a number of things - waiting make make it their friend. We resolve these references - here. */ -void -embrace_waiting_friends (type) - tree type; -{ - tree decl = TYPE_NAME (type); - tree waiters; - - if (TREE_CODE (decl) != TYPE_DECL) - return; - - for (waiters = DECL_WAITING_FRIENDS (decl); waiters; - waiters = TREE_CHAIN (waiters)) - { - tree waiter = TREE_PURPOSE (waiters); - tree waiter_prev = TREE_VALUE (waiters); - tree decl = TREE_TYPE (waiters); - tree name = decl ? (TREE_CODE (decl) == IDENTIFIER_NODE - ? decl : DECL_NAME (decl)) : NULL_TREE; - if (name) - { - /* @@ There may be work to be done since we have not verified - @@ consistency between original and friend declarations - @@ of the functions waiting to become friends. */ - tree field = lookup_fnfields (TYPE_BINFO (type), name, 0); - if (field) - if (decl == name) - add_friends (waiter, name, type); - else - add_friend (waiter, decl); - else - error_with_file_and_line (DECL_SOURCE_FILE (TYPE_NAME (waiter)), - DECL_SOURCE_LINE (TYPE_NAME (waiter)), - "no method `%s' defined in class `%s' to be friend", - IDENTIFIER_POINTER (DECL_NAME (TREE_TYPE (waiters))), - TYPE_NAME_STRING (type)); - } - else - make_friend_class (type, waiter); - - if (TREE_CHAIN (waiter_prev)) - TREE_CHAIN (waiter_prev) = TREE_CHAIN (TREE_CHAIN (waiter_prev)); - else - DECL_UNDEFINED_FRIENDS (TYPE_NAME (waiter)) = NULL_TREE; - } -} - -/* Common subroutines of build_new and build_vec_delete. */ - -/* Common interface for calling "builtin" functions that are not - really builtin. */ - -tree -build_builtin_call (type, node, arglist) - tree type; - tree node; - tree arglist; -{ - tree rval = build (CALL_EXPR, type, node, arglist, 0); - TREE_SIDE_EFFECTS (rval) = 1; - assemble_external (TREE_OPERAND (node, 0)); - TREE_USED (TREE_OPERAND (node, 0)) = 1; - return rval; -} - -/* Generate a C++ "new" expression. DECL is either a TREE_LIST - (which needs to go through some sort of groktypename) or it - is the name of the class we are newing. INIT is an initialization value. - It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. - If INIT is void_type_node, it means do *not* call a constructor - for this instance. - - For types with constructors, the data returned is initialized - by the appropriate constructor. - - Whether the type has a constructor or not, if it has a pointer - to a virtual function table, then that pointer is set up - here. - - Unless I am mistaken, a call to new () will return initialized - data regardless of whether the constructor itself is private or - not. - - Note that build_new does nothing to assure that any special - alignment requirements of the type are met. Rather, it leaves - it up to malloc to do the right thing. Otherwise, folding to - the right alignment cal cause problems if the user tries to later - free the memory returned by `new'. - - PLACEMENT is the `placement' list for user-defined operator new (). */ - -tree -build_new (placement, decl, init, use_global_new) - tree placement; - tree decl, init; - int use_global_new; -{ - tree type, true_type, size, rval; - tree init1 = NULL_TREE, nelts; - int has_call = 0, has_array = 0; - - tree pending_sizes = NULL_TREE; - - if (decl == error_mark_node) - return error_mark_node; - - if (TREE_CODE (decl) == TREE_LIST) - { - tree absdcl = TREE_VALUE (decl); - tree last_absdcl = NULL_TREE; - int old_immediate_size_expand; - - if (current_function_decl - && DECL_CONSTRUCTOR_P (current_function_decl)) - { - old_immediate_size_expand = immediate_size_expand; - immediate_size_expand = 0; - } - - nelts = integer_one_node; - - if (absdcl && TREE_CODE (absdcl) == CALL_EXPR) - { - /* probably meant to be a call */ - has_call = 1; - init1 = TREE_OPERAND (absdcl, 1); - absdcl = TREE_OPERAND (absdcl, 0); - TREE_VALUE (decl) = absdcl; - } - while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF) - { - last_absdcl = absdcl; - absdcl = TREE_OPERAND (absdcl, 0); - } - - if (absdcl && TREE_CODE (absdcl) == ARRAY_REF) - { - /* probably meant to be a vec new */ - tree this_nelts; - - has_array = 1; - this_nelts = TREE_OPERAND (absdcl, 1); - if (this_nelts != error_mark_node) - { - if (this_nelts == NULL_TREE) - error ("new of array type fails to specify size"); - else - { - this_nelts = save_expr (this_nelts); - absdcl = TREE_OPERAND (absdcl, 0); - if (this_nelts == integer_zero_node) - { - warning ("zero size array reserves no space"); - nelts = integer_zero_node; - } - else - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); - } - } - else - nelts = integer_zero_node; - } - - if (last_absdcl) - TREE_OPERAND (last_absdcl, 0) = absdcl; - else - TREE_VALUE (decl) = absdcl; - - type = true_type = groktypename (decl); - if (! type || type == error_mark_node - || true_type == error_mark_node) - return error_mark_node; - - /* ``A reference cannot be created by the new operator. A reference - is not an object (8.2.2, 8.4.3), so a pointer to it could not be - returned by new.'' ARM 5.3.3 */ - if (TREE_CODE (type) == REFERENCE_TYPE) - error ("new cannot be applied to a reference type"); - - type = TYPE_MAIN_VARIANT (type); - if (type == void_type_node) - { - error ("invalid type: `void []'"); - return error_mark_node; - } - if (current_function_decl - && DECL_CONSTRUCTOR_P (current_function_decl)) - { - pending_sizes = get_pending_sizes (); - immediate_size_expand = old_immediate_size_expand; - } - } - else if (TREE_CODE (decl) == IDENTIFIER_NODE) - { - if (IDENTIFIER_HAS_TYPE_VALUE (decl)) - { - /* An aggregate type. */ - type = IDENTIFIER_TYPE_VALUE (decl); - decl = TYPE_NAME (type); - } - else - { - /* A builtin type. */ - decl = lookup_name (decl, 1); - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215); - type = TREE_TYPE (decl); - } - true_type = type; - } - else if (TREE_CODE (decl) == TYPE_DECL) - { - type = TREE_TYPE (decl); - true_type = type; - } - else - { - type = decl; - true_type = type; - decl = TYPE_NAME (type); - } - - if (TYPE_SIZE (type) == 0) - { - if (type == void_type_node) - error ("invalid type for new: `void'"); - else - incomplete_type_error (0, type); - return error_mark_node; - } - - if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - { - abstract_virtuals_error (NULL_TREE, type); - return error_mark_node; - } - - /* If our base type is an array, then make sure we know how many elements - it has. */ - while (TREE_CODE (type) == ARRAY_TYPE) - { - tree this_nelts = array_type_nelts_top (type); - if (nelts == integer_one_node) - { - has_array = 1; - nelts = this_nelts; - } - else - { - my_friendly_assert (has_array != 0, 216); - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); - } - type = TREE_TYPE (type); - } - if (has_array) - size = fold (build_binary_op (MULT_EXPR, size_in_bytes (type), nelts, 1)); - else - size = size_in_bytes (type); - - if (has_call) - init = init1; - - /* Get to the target type of TRUE_TYPE, so we can decide whether - any constructors need to be called or not. */ - type = true_type; - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - /* Get a little extra space to store a couple of things before the new'ed - array. */ - if (has_array && TYPE_NEEDS_DESTRUCTOR (true_type)) - { - tree extra = BI_header_size; - - size = size_binop (PLUS_EXPR, size, extra); - } - - /* Allocate the object. */ - if (TYPE_LANG_SPECIFIC (true_type) - && (TREE_GETS_NEW (true_type) && !use_global_new)) - rval = build_opfncall (NEW_EXPR, LOOKUP_NORMAL, - TYPE_POINTER_TO (true_type), size, placement); - else if (placement) - { - rval = build_opfncall (NEW_EXPR, LOOKUP_GLOBAL|LOOKUP_COMPLAIN, - ptr_type_node, size, placement); - rval = convert (TYPE_POINTER_TO (true_type), rval); - } - else if (flag_this_is_variable > 0 - && TYPE_HAS_CONSTRUCTOR (true_type) && init != void_type_node) - { - if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) - rval = NULL_TREE; - else - { - error ("constructors take parameter lists"); - return error_mark_node; - } - } - else - { - rval = build_builtin_call (build_pointer_type (true_type), - BIN, build_tree_list (NULL_TREE, size)); -#if 0 - /* See comment above as to why this is disabled. */ - if (alignment) - { - rval = build (PLUS_EXPR, TYPE_POINTER_TO (true_type), rval, - alignment); - rval = build (BIT_AND_EXPR, TYPE_POINTER_TO (true_type), - rval, build1 (BIT_NOT_EXPR, integer_type_node, - alignment)); - } -#endif - TREE_CALLS_NEW (rval) = 1; - TREE_SIDE_EFFECTS (rval) = 1; - } - - /* if rval is NULL_TREE I don't have to allocate it, but are we totally - sure we have some extra bytes in that case for the BI_header_size - cookies? And how does that interact with the code below? (mrs) */ - /* Finish up some magic for new'ed arrays */ - if (has_array && TYPE_NEEDS_DESTRUCTOR (true_type) && rval != NULL_TREE) - { - tree extra = BI_header_size; - tree cookie, exp1, exp2; - rval = convert (ptr_type_node, rval); /* convert to void * first */ - rval = convert (string_type_node, rval); /* lets not add void* and ints */ - rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1)); - /* Store header info. */ - cookie = build_indirect_ref (build (MINUS_EXPR, TYPE_POINTER_TO (BI_header_type), - rval, extra), 0); - exp1 = build (MODIFY_EXPR, void_type_node, - build_component_ref (cookie, get_identifier ("nelts"), 0, 0), - nelts); - TREE_SIDE_EFFECTS (exp1) = 1; - exp2 = build (MODIFY_EXPR, void_type_node, - build_component_ref (cookie, get_identifier ("ptr_2comp"), 0, 0), - build (MINUS_EXPR, ptr_type_node, integer_zero_node, rval)); - TREE_SIDE_EFFECTS (exp2) = 1; - rval = convert (build_pointer_type (true_type), rval); - TREE_CALLS_NEW (rval) = 1; - TREE_SIDE_EFFECTS (rval) = 1; - rval = build_compound_expr (tree_cons (NULL_TREE, exp1, - tree_cons (NULL_TREE, exp2, - build_tree_list (NULL_TREE, rval)))); - } - - /* We've figured out where the allocation is to go. - If we're not eliding constructors, then if a constructor - is defined, we must go through it. */ - if (!has_array && (rval == NULL_TREE || !flag_elide_constructors) - && TYPE_HAS_CONSTRUCTOR (true_type) && init != void_type_node) - { - tree newrval; - /* Constructors are never virtual. */ - int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL; - /* If a copy constructor might work, set things up so that we can - try that after this. */ - if (rval != NULL_TREE) - flags = ~LOOKUP_COMPLAIN & (flags|LOOKUP_SPECULATIVELY); - - if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type)) - { - init = tree_cons (NULL_TREE, integer_one_node, init); - flags |= LOOKUP_HAS_IN_CHARGE; - } - newrval = build_method_call (rval, constructor_name (true_type), - init, NULL_TREE, flags); - if (newrval) - { - rval = newrval; - TREE_HAS_CONSTRUCTOR (rval) = 1; - goto done; - } - /* Didn't find the constructor, maybe it is a call to a copy constructor - that we should implement. */ - } - - if (rval == error_mark_node) - return error_mark_node; - rval = save_expr (rval); - TREE_HAS_CONSTRUCTOR (rval) = 1; - - /* Don't call any constructors or do any initialization. */ - if (init == void_type_node) - goto done; - - if (TYPE_NEEDS_CONSTRUCTING (type) - || (has_call || init)) - { - extern tree static_aggregates; - - if (current_function_decl == NULL_TREE) - { - /* In case of static initialization, SAVE_EXPR is good enough. */ - init = copy_to_permanent (init); - rval = copy_to_permanent (rval); - static_aggregates = perm_tree_cons (init, rval, static_aggregates); - } - else - { - /* Have to wrap this in RTL_EXPR for two cases: - in base or member initialization and if we - are a branch of a ?: operator. Since we - can't easily know the latter, just do it always. */ - tree xval = make_node (RTL_EXPR); - - TREE_TYPE (xval) = TREE_TYPE (rval); - do_pending_stack_adjust (); - start_sequence (); - - /* As a matter of principle, `start_sequence' should do this. */ - emit_note (0, -1); - - if (has_array) - rval = expand_vec_init (decl, rval, - build_binary_op (MINUS_EXPR, nelts, integer_one_node, 1), - init, 0); - else - expand_aggr_init (build_indirect_ref (rval, 0), init, 0); - - do_pending_stack_adjust (); - - TREE_SIDE_EFFECTS (xval) = 1; - TREE_CALLS_NEW (xval) = 1; - RTL_EXPR_SEQUENCE (xval) = get_insns (); - end_sequence (); - - if (TREE_CODE (rval) == SAVE_EXPR) - { - /* Errors may cause this to not get evaluated. */ - if (SAVE_EXPR_RTL (rval) == 0) - SAVE_EXPR_RTL (rval) = const0_rtx; - RTL_EXPR_RTL (xval) = SAVE_EXPR_RTL (rval); - } - else - { - my_friendly_assert (TREE_CODE (rval) == VAR_DECL, 217); - RTL_EXPR_RTL (xval) = DECL_RTL (rval); - } - rval = xval; - } - } -#if 0 - /* It would seem that the above code handles this better than the code - below. (mrs) */ - else if (has_call || init) - { - if (IS_AGGR_TYPE (type)) - { - /* default copy constructor may be missing from the below. (mrs) */ - error_with_aggr_type (type, "no constructor for type `%s'"); - rval = error_mark_node; - } - else - { - /* New 2.0 interpretation: `new int (10)' means - allocate an int, and initialize it with 10. */ - - init = build_c_cast (type, init); - rval = build (COMPOUND_EXPR, TREE_TYPE (rval), - build_modify_expr (build_indirect_ref (rval, 0), - NOP_EXPR, init), - rval); - TREE_SIDE_EFFECTS (rval) = 1; - } - } -#endif - done: - if (pending_sizes) - rval = build_compound_expr (chainon (pending_sizes, - build_tree_list (NULL_TREE, rval))); - - if (flag_gc) - { - extern tree gc_visible; - tree objbits; - tree update_expr; - - rval = save_expr (rval); - /* We don't need a `headof' operation to do this because - we know where the object starts. */ - objbits = build1 (INDIRECT_REF, unsigned_type_node, - build (MINUS_EXPR, ptr_type_node, - rval, c_sizeof_nowarn (unsigned_type_node))); - update_expr = build_modify_expr (objbits, BIT_IOR_EXPR, gc_visible); - rval = build_compound_expr (tree_cons (NULL_TREE, rval, - tree_cons (NULL_TREE, update_expr, - build_tree_list (NULL_TREE, rval)))); - } - - return save_expr (rval); -} - -/* `expand_vec_init' performs initialization of a vector of aggregate - types. - - DECL is passed only for error reporting, and provides line number - and source file name information. - BASE is the space where the vector will be. - MAXINDEX is the maximum index of the array (one less than the - number of elements). - INIT is the (possibly NULL) initializer. - - FROM_ARRAY is 0 if we should init everything with INIT - (i.e., every element initialized from INIT). - FROM_ARRAY is 1 if we should index into INIT in parallel - with initialization of DECL. - FROM_ARRAY is 2 if we should index into INIT in parallel, - but use assignment instead of initialization. */ - -tree -expand_vec_init (decl, base, maxindex, init, from_array) - tree decl, base, maxindex, init; - int from_array; -{ - tree rval; - tree iterator, base2 = NULL_TREE; - tree type = TREE_TYPE (TREE_TYPE (base)); - tree size; - - maxindex = convert (integer_type_node, maxindex); - if (maxindex == error_mark_node) - return error_mark_node; - - if (current_function_decl == NULL_TREE) - { - rval = make_tree_vec (3); - TREE_VEC_ELT (rval, 0) = base; - TREE_VEC_ELT (rval, 1) = maxindex; - TREE_VEC_ELT (rval, 2) = init; - return rval; - } - - size = size_in_bytes (type); - - /* Set to zero in case size is <= 0. Optimizer will delete this if - it is not needed. */ - rval = get_temp_regvar (TYPE_POINTER_TO (type), convert (TYPE_POINTER_TO (type), - null_pointer_node)); - base = default_conversion (base); - base = convert (TYPE_POINTER_TO (type), base); - expand_assignment (rval, base, 0, 0); - base = get_temp_regvar (TYPE_POINTER_TO (type), base); - - if (init != NULL_TREE - && TREE_CODE (init) == CONSTRUCTOR - && TREE_TYPE (init) == TREE_TYPE (decl)) - { - /* Initialization of array from {...}. */ - tree elts = CONSTRUCTOR_ELTS (init); - tree baseref = build1 (INDIRECT_REF, type, base); - tree baseinc = build (PLUS_EXPR, TYPE_POINTER_TO (type), base, size); - int host_i = TREE_INT_CST_LOW (maxindex); - - if (IS_AGGR_TYPE (type)) - { - while (elts) - { - host_i -= 1; - expand_aggr_init (baseref, TREE_VALUE (elts), 0); - - expand_assignment (base, baseinc, 0, 0); - elts = TREE_CHAIN (elts); - } - /* Initialize any elements by default if possible. */ - if (host_i >= 0) - { - if (TYPE_NEEDS_CONSTRUCTING (type) == 0) - { - if (obey_regdecls) - use_variable (DECL_RTL (base)); - goto done_init; - } - - iterator = get_temp_regvar (integer_type_node, - build_int_2 (host_i, 0)); - init = NULL_TREE; - goto init_by_default; - } - } - else - while (elts) - { - expand_assignment (baseref, TREE_VALUE (elts), 0, 0); - - expand_assignment (base, baseinc, 0, 0); - elts = TREE_CHAIN (elts); - } - - if (obey_regdecls) - use_variable (DECL_RTL (base)); - } - else - { - iterator = get_temp_regvar (integer_type_node, maxindex); - - init_by_default: - - /* If initializing one array from another, - initialize element by element. */ - if (from_array) - { - if (decl == NULL_TREE - || (init && !comptypes (TREE_TYPE (init), TREE_TYPE (decl), 1))) - { - sorry ("initialization of array from dissimilar array type"); - return error_mark_node; - } - if (init) - { - base2 = default_conversion (init); - base2 = get_temp_regvar (TYPE_POINTER_TO (type), base2); - } - else if (TYPE_LANG_SPECIFIC (type) - && TYPE_NEEDS_CONSTRUCTING (type) - && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) - { - error ("initializer ends prematurely"); - return error_mark_node; - } - } - - expand_start_cond (build (GE_EXPR, integer_type_node, - iterator, integer_zero_node), 0); - expand_start_loop_continue_elsewhere (1); - - if (from_array) - { - tree to = build1 (INDIRECT_REF, type, base); - tree from; - - if (base2) - from = build1 (INDIRECT_REF, type, base2); - else - from = NULL_TREE; - - if (from_array == 2) - expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from)); - else if (TYPE_NEEDS_CONSTRUCTING (type)) - expand_aggr_init (to, from, 0); - else if (from) - expand_assignment (to, from, 0, 0); - else my_friendly_abort (57); - } - else if (TREE_CODE (type) == ARRAY_TYPE) - { - if (init != 0) - sorry ("cannot initialize multi-dimensional array with initializer"); - expand_vec_init (decl, build1 (NOP_EXPR, TYPE_POINTER_TO (TREE_TYPE (type)), base), - array_type_nelts (type), 0, 0); - } - else - expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0); - - expand_assignment (base, - build (PLUS_EXPR, TYPE_POINTER_TO (type), base, size), - 0, 0); - if (base2) - expand_assignment (base2, - build (PLUS_EXPR, TYPE_POINTER_TO (type), base2, size), 0, 0); - expand_loop_continue_here (); - expand_exit_loop_if_false (0, build (NE_EXPR, integer_type_node, - build (PREDECREMENT_EXPR, integer_type_node, iterator, integer_one_node), minus_one)); - - if (obey_regdecls) - { - use_variable (DECL_RTL (base)); - if (base2) - use_variable (DECL_RTL (base2)); - } - expand_end_loop (); - expand_end_cond (); - if (obey_regdecls) - use_variable (DECL_RTL (iterator)); - } - done_init: - - if (obey_regdecls) - use_variable (DECL_RTL (rval)); - return rval; -} - -/* Free up storage of type TYPE, at address ADDR. - - TYPE is a POINTER_TYPE and can be ptr_type_node for no special type - of pointer. - - VIRTUAL_SIZE is the ammount of storage that was allocated, and is - used as the second argument to operator delete. It can include - things like padding and magic size cookies. It has virtual in it, - because if you have a base pointer and you delete through a virtual - destructor, it should be the size of the dynamic object, not the - static object, see Free Store 12.5 ANSI C++ WP. - - This does not call any destructors. */ -tree -build_x_delete (type, addr, use_global_delete, virtual_size) - tree type, addr; - int use_global_delete; - tree virtual_size; -{ - tree rval; - - if (!use_global_delete - && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) - && TREE_GETS_DELETE (TREE_TYPE (type))) - rval = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE); - else - rval = build_builtin_call (void_type_node, BID, - tree_cons (NULL_TREE, addr, - build_tree_list (NULL_TREE, - virtual_size))); - return rval; -} - -/* Objects returned by `build_new' may point to just what the user - requested (in the case of `new X'), or they may have a cookie - consisting of a special value (the two's complement of the pointer - address) and the number of elements allocated (in the case of - `new X[N]'. In the latter case, we need to adjust the pointer - that's passed back to the storage allocator. */ - -static tree -maybe_adjust_addr_for_delete (addr) - tree addr; -{ - tree cookie_addr; - tree cookie; - tree adjusted_addr, ptr_2comp; - - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - - cookie_addr = build (MINUS_EXPR, TYPE_POINTER_TO (BI_header_type), - addr, BI_header_size); - cookie = build_indirect_ref (cookie_addr, 0); - - ptr_2comp = build_component_ref (cookie, get_identifier ("ptr_2comp"), 0, 0); - adjusted_addr = save_expr (build (MINUS_EXPR, TREE_TYPE (addr), addr, BI_header_size)); - - /* We must zero out the storage here because if the memory is freed, - then later reallocated, we might get a false positive when the - address is reused. */ - adjusted_addr = build_compound_expr (tree_cons (NULL_TREE, - build_modify_expr (ptr_2comp, NOP_EXPR, null_pointer_node), - build_tree_list (NULL_TREE, adjusted_addr))); - - addr = build (COND_EXPR, TREE_TYPE (addr), - build (TRUTH_ORIF_EXPR, integer_type_node, - build (EQ_EXPR, integer_type_node, - addr, integer_zero_node), - build (PLUS_EXPR, integer_type_node, - convert (ptr_type_node, addr), ptr_2comp)), - addr, - adjusted_addr); - return addr; -} - -/* Generate a call to a destructor. TYPE is the type to cast ADDR to. - ADDR is an expression which yields the store to be destroyed. - AUTO_DELETE is nonzero if a call to DELETE should be made or not. - If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the - virtual baseclasses. - If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate. - - FLAGS is the logical disjunction of zero or more LOOKUP_ - flags. See cp-tree.h for more info. - - MAYBE_ADJUST is nonzero iff we may need to adjust the address - of the object being deleted before calling `operator delete'. - This can happen when a user allocates an array with `operator new' - and simply calls delete. Ideally this is unnecessary, but there - is much code that does `p = new char[n]; ... delete p;' and this code - would crash otherwise. - - This function does not delete an object's virtual base classes. */ -tree -build_delete (type, addr, auto_delete, flags, use_global_delete, maybe_adjust) - tree type, addr; - tree auto_delete; - int flags; - int use_global_delete; - int maybe_adjust; -{ - tree function, parms; - tree member; - tree expr; - tree ref; - int ptr; - - if (addr == error_mark_node) - return error_mark_node; - - /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type - set to `error_mark_node' before it gets properly cleaned up. */ - if (type == error_mark_node) - return error_mark_node; - - type = TYPE_MAIN_VARIANT (type); - - if (TREE_CODE (type) == POINTER_TYPE) - { - type = TREE_TYPE (type); - if (TYPE_SIZE (type) == 0) - { - incomplete_type_error (0, type); - return error_mark_node; - } - if (TREE_CODE (type) == ARRAY_TYPE) - goto handle_array; - if (! IS_AGGR_TYPE (type)) - { - tree virtual_size; - - /* This is probably wrong. It should be the size of the virtual - object being deleted. */ - virtual_size = c_sizeof_nowarn (type); - - if (maybe_adjust) - addr = maybe_adjust_addr_for_delete (addr); - return build_builtin_call (void_type_node, BID, - tree_cons (NULL_TREE, addr, - build_tree_list (NULL_TREE, virtual_size))); - } - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - ref = build_indirect_ref (addr, 0); - ptr = 1; - } - else if (TREE_CODE (type) == ARRAY_TYPE) - { - handle_array: - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - return build_vec_delete (addr, array_type_nelts (type), - c_sizeof_nowarn (TREE_TYPE (type)), - NULL_TREE, auto_delete, integer_two_node); - } - else - { - /* Don't check PROTECT here; leave that decision to the - destructor. If the destructor is visible, call it, - else report error. */ - addr = build_unary_op (ADDR_EXPR, addr, 0); - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - - if (TREE_CONSTANT (addr)) - addr = convert_pointer_to (type, addr); - else - addr = convert_force (build_pointer_type (type), addr); - - if (TREE_CODE (addr) == NOP_EXPR - && TREE_OPERAND (addr, 0) == current_class_decl) - ref = C_C_D; - else - ref = build_indirect_ref (addr, 0); - ptr = 0; - } - - my_friendly_assert (IS_AGGR_TYPE (type), 220); - - if (! TYPE_NEEDS_DESTRUCTOR (type)) - { - tree virtual_size; - - /* This is probably wrong. It should be the size of the virtual object - being deleted. */ - virtual_size = c_sizeof_nowarn (type); - - if (auto_delete == integer_zero_node) - return void_zero_node; - if (maybe_adjust && addr != current_class_decl) - addr = maybe_adjust_addr_for_delete (addr); - if (TREE_GETS_DELETE (type) && !use_global_delete) - return build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE); - return build_builtin_call (void_type_node, BID, - tree_cons (NULL_TREE, addr, - build_tree_list (NULL_TREE, virtual_size))); - } - parms = build_tree_list (NULL_TREE, addr); - - /* Below, we will reverse the order in which these calls are made. - If we have a destructor, then that destructor will take care - of the base classes; otherwise, we must do that here. */ - if (TYPE_HAS_DESTRUCTOR (type)) - { - tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)); - tree basetypes = TYPE_BINFO (type); - - if (flags & LOOKUP_PROTECT) - { - enum visibility_type visibility = compute_visibility (basetypes, dtor); - - if (visibility == visibility_private) - { - if (flags & LOOKUP_COMPLAIN) - error_with_aggr_type (type, "destructor for type `%s' is private in this scope"); - return error_mark_node; - } - else if (visibility == visibility_protected - && (flags & LOOKUP_PROTECTED_OK) == 0) - { - if (flags & LOOKUP_COMPLAIN) - error_with_aggr_type (type, "destructor for type `%s' is protected in this scope"); - return error_mark_node; - } - } - - /* Once we are in a destructor, try not going through - the virtual function table to find the next destructor. */ - if (DECL_VINDEX (dtor) - && ! (flags & LOOKUP_NONVIRTUAL) - && TREE_CODE (auto_delete) != PARM_DECL - && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0))) - { - /* This destructor must be called via virtual function table. */ - dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 0); - expr = convert_pointer_to (DECL_CLASS_CONTEXT (dtor), TREE_VALUE (parms)); - if (expr != TREE_VALUE (parms)) - { - expr = fold (expr); - ref = build_indirect_ref (expr, 0); - TREE_VALUE (parms) = expr; - } - function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor)); - if (function == error_mark_node) - return error_mark_node; - TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor)); - TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete); - expr = build_function_call (function, parms); - if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0) - { - /* Handle the case where a virtual destructor is - being called on an item that is 0. - - @@ Does this really need to be done? */ - tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1); -#if 0 - if (TREE_CODE (ref) == VAR_DECL - || TREE_CODE (ref) == COMPONENT_REF) - warning ("losing in build_delete"); -#endif - expr = build (COND_EXPR, void_type_node, - ifexp, expr, void_zero_node); - } - } - else - { - tree ifexp; - - if ((flags & LOOKUP_DESTRUCTOR) - || TREE_CODE (ref) == VAR_DECL - || TREE_CODE (ref) == PARM_DECL - || TREE_CODE (ref) == COMPONENT_REF - || TREE_CODE (ref) == ARRAY_REF) - /* These can't be 0. */ - ifexp = integer_one_node; - else - /* Handle the case where a non-virtual destructor is - being called on an item that is 0. */ - ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1); - - /* Used to mean that this destructor was known to be empty, - but that's now obsolete. */ - my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221); - - TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete); - expr = build_function_call (dtor, parms); - - if (ifexp != integer_one_node) - expr = build (COND_EXPR, void_type_node, - ifexp, expr, void_zero_node); - } - return expr; - } - else - { - /* This can get visibilities wrong. */ - tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE; - tree exprstmt = NULL_TREE; - tree parent_auto_delete = auto_delete; - tree cond; - - /* If this type does not have a destructor, but does have - operator delete, call the parent parent destructor (if any), - but let this node do the deleting. Otherwise, it is ok - to let the parent destructor do the deleting. */ - if (TREE_GETS_DELETE (type) && !use_global_delete) - { - parent_auto_delete = integer_zero_node; - if (auto_delete == integer_zero_node) - cond = NULL_TREE; - else - { - tree virtual_size; - - /* This is probably wrong. It should be the size of the - virtual object being deleted. */ - virtual_size = c_sizeof_nowarn (type); - - expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr, - virtual_size, NULL_TREE); - if (expr == error_mark_node) - return error_mark_node; - if (auto_delete != integer_one_node) - cond = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, - auto_delete, integer_one_node), - expr, void_zero_node); - else cond = expr; - } - } - else if (base_binfo == NULL_TREE - || (TREE_VIA_VIRTUAL (base_binfo) == 0 - && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))) - { - tree virtual_size; - - /* This is probably wrong. It should be the size of the virtual - object being deleted. */ - virtual_size = c_sizeof_nowarn (type); - - cond = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), - build_builtin_call (void_type_node, BID, - tree_cons (NULL_TREE, addr, - build_tree_list (NULL_TREE, virtual_size))), - void_zero_node); - } - else cond = NULL_TREE; - - if (cond) - exprstmt = build_tree_list (NULL_TREE, cond); - - if (base_binfo - && ! TREE_VIA_VIRTUAL (base_binfo) - && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - tree this_auto_delete; - - if (BINFO_OFFSET_ZEROP (base_binfo)) - this_auto_delete = parent_auto_delete; - else - this_auto_delete = integer_zero_node; - - expr = build_delete (TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), addr, - this_auto_delete, flags|LOOKUP_PROTECTED_OK, 0, 0); - exprstmt = tree_cons (NULL_TREE, expr, exprstmt); - } - - /* Take care of the remaining baseclasses. */ - for (i = 1; i < n_baseclasses; i++) - { - base_binfo = TREE_VEC_ELT (binfos, i); - if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)) - || TREE_VIA_VIRTUAL (base_binfo)) - continue; - - /* May be zero offset if other baseclasses are virtual. */ - expr = fold (build (PLUS_EXPR, TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), - addr, BINFO_OFFSET (base_binfo))); - - expr = build_delete (TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), expr, - integer_zero_node, - flags|LOOKUP_PROTECTED_OK, 0, 0); - - exprstmt = tree_cons (NULL_TREE, expr, exprstmt); - } - - for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member)) - { - if (TREE_CODE (member) != FIELD_DECL) - continue; - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member))) - { - tree this_member = build_component_ref (ref, DECL_NAME (member), 0, 0); - tree this_type = TREE_TYPE (member); - expr = build_delete (this_type, this_member, integer_two_node, flags, 0, 0); - exprstmt = tree_cons (NULL_TREE, expr, exprstmt); - } - } - - if (exprstmt) - return build_compound_expr (exprstmt); - /* Virtual base classes make this function do nothing. */ - return void_zero_node; - } -} - -/* For type TYPE, delete the virtual baseclass objects of DECL. */ - -tree -build_vbase_delete (type, decl) - tree type, decl; -{ - tree vbases = CLASSTYPE_VBASECLASSES (type); - tree result = NULL_TREE; - tree addr = build_unary_op (ADDR_EXPR, decl, 0); - my_friendly_assert (addr != error_mark_node, 222); - while (vbases) - { - tree this_addr = convert_force (TYPE_POINTER_TO (BINFO_TYPE (vbases)), addr); - result = tree_cons (NULL_TREE, - build_delete (TREE_TYPE (this_addr), this_addr, - integer_zero_node, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0), - result); - vbases = TREE_CHAIN (vbases); - } - return build_compound_expr (nreverse (result)); -} - -/* Build a C++ vector delete expression. - MAXINDEX is the number of elements to be deleted. - ELT_SIZE is the nominal size of each element in the vector. - BASE is the expression that should yield the store to be deleted. - DTOR_DUMMY is a placeholder for a destructor. The library function - __builtin_vec_delete has a pointer to function in this position. - This function expands (or synthesizes) these calls itself. - AUTO_DELETE_VEC says whether the container (vector) should be deallocated. - AUTO_DELETE say whether each item in the container should be deallocated. - - This also calls delete for virtual baseclasses of elements of the vector. - - Update: MAXINDEX is no longer needed. The size can be extracted from the - start of the vector for pointers, and from the type for arrays. We still - use MAXINDEX for arrays because it happens to already have one of the - values we'd have to extract. (We could use MAXINDEX with pointers to - confirm the size, and trap if the numbers differ; not clear that it'd - be worth bothering.) */ -tree -build_vec_delete (base, maxindex, elt_size, dtor_dummy, auto_delete_vec, auto_delete) - tree base, maxindex, elt_size; - tree dtor_dummy; - tree auto_delete_vec, auto_delete; -{ - tree ptype = TREE_TYPE (base); - tree type; - tree virtual_size; - /* Temporary variables used by the loop. */ - tree tbase, size_exp, tbase_init; - - /* This is the body of the loop that implements the deletion of a - single element, and moves temp variables to next elements. */ - tree body; - - /* This is the LOOP_EXPR that governs the deletion of the elements. */ - tree loop; - - /* This is the thing that governs what to do after the loop has run. */ - tree deallocate_expr = 0; - - /* This is the BIND_EXPR which holds the outermost iterator of the - loop. It is convenient to set this variable up and test it before - executing any other code in the loop. - This is also the containing expression returned by this function. */ - tree controller = NULL_TREE; - - /* This is the BLOCK to record the symbol binding for debugging. */ - tree block; - - base = stabilize_reference (base); - - /* Since we can use base many times, save_epr it. */ - if (TREE_SIDE_EFFECTS (base)) - base = save_expr (base); - - if (TREE_CODE (ptype) == POINTER_TYPE) - { - /* Step back one from start of vector, and read dimension. */ - tree cookie_addr = build (MINUS_EXPR, TYPE_POINTER_TO (BI_header_type), - base, BI_header_size); - tree cookie = build_indirect_ref (cookie_addr, 0); - maxindex = build_component_ref (cookie, get_identifier ("nelts"), 0, 0); - do - ptype = TREE_TYPE (ptype); - while (TREE_CODE (ptype) == ARRAY_TYPE); - } - else if (TREE_CODE (ptype) == ARRAY_TYPE) - { - /* get the total number of things in the array, maxindex is a bad name */ - maxindex = array_type_nelts_total (ptype); - while (TREE_CODE (ptype) == ARRAY_TYPE) - ptype = TREE_TYPE (ptype); - base = build_unary_op (ADDR_EXPR, base, 1); - } - else - { - error ("type to vector delete is neither pointer or array type"); - return error_mark_node; - } - type = ptype; - ptype = TYPE_POINTER_TO (type); - - size_exp = size_in_bytes (type); - - if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type)) - { - loop = integer_zero_node; - goto no_destructor; - } - - /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); - - tbase = build_decl (VAR_DECL, NULL_TREE, ptype); - tbase_init = build_modify_expr (tbase, NOP_EXPR, - fold (build (PLUS_EXPR, ptype, - base, - virtual_size))); - DECL_REGISTER (tbase) = 1; - controller = build (BIND_EXPR, void_type_node, tbase, 0, 0); - TREE_SIDE_EFFECTS (controller) = 1; - block = build_block (tbase, 0, 0, 0, 0); - add_block_current_level (block); - - if (auto_delete != integer_zero_node - && auto_delete != integer_two_node) - { - tree base_tbd = convert (ptype, - build_binary_op (MINUS_EXPR, - convert (ptr_type_node, base), - BI_header_size, - 1)); - /* This is the real size */ - virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); - body = build_tree_list (NULL_TREE, - build_x_delete (ptr_type_node, base_tbd, 0, - virtual_size)); - body = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, - auto_delete, integer_one_node), - body, integer_zero_node); - } - else - body = NULL_TREE; - - body = tree_cons (NULL_TREE, - build_delete (ptype, tbase, auto_delete, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0, 0), - body); - - body = tree_cons (NULL_TREE, - build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)), - body); - - body = tree_cons (NULL_TREE, - build (EXIT_EXPR, void_type_node, - build (EQ_EXPR, integer_type_node, base, tbase)), - body); - - loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body)); - - loop = tree_cons (NULL_TREE, tbase_init, - tree_cons (NULL_TREE, loop, NULL_TREE)); - loop = build_compound_expr (loop); - - no_destructor: - /* If the delete flag is one, or anything else with the low bit set, - delete the storage. */ - if (auto_delete_vec == integer_zero_node - || auto_delete_vec == integer_two_node) - deallocate_expr = integer_zero_node; - else - { - tree base_tbd; - - /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); - - if (loop == integer_zero_node) - /* no header */ - base_tbd = base; - else - { - base_tbd = convert (ptype, - build_binary_op (MINUS_EXPR, - convert (string_type_node, base), - BI_header_size, - 1)); - /* True size with header. */ - virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); - } - deallocate_expr = build_x_delete (ptr_type_node, base_tbd, 1, - virtual_size); - if (auto_delete_vec != integer_one_node) - deallocate_expr = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, - auto_delete_vec, integer_one_node), - deallocate_expr, integer_zero_node); - } - - if (loop && deallocate_expr != integer_zero_node) - { - body = tree_cons (NULL_TREE, loop, - tree_cons (NULL_TREE, deallocate_expr, NULL_TREE)); - body = build_compound_expr (body); - } - else - body = loop; - - /* Outermost wrapper: If pointer is null, punt. */ - body = build (COND_EXPR, void_type_node, - build (NE_EXPR, integer_type_node, base, integer_zero_node), - body, integer_zero_node); - - if (controller) - { - TREE_OPERAND (controller, 1) = body; - return controller; - } - else - return convert (void_type_node, body); -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-input.c b/gnu/usr.bin/gcc2/cc1plus/cp-input.c deleted file mode 100644 index 155c10484b7..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-input.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Input handling for G++. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char input_rcsid[] = "$Id: cp-input.c,v 1.1.1.1 1995/10/18 08:39:32 deraadt Exp $"; -#endif /* not lint */ - -/* G++ needs to do enough saving and re-parsing of text that it is - necessary to abandon the simple FILE* model and use a mechanism where - we can pre-empt one input stream with another derived from saved text; - we may need to do this arbitrarily often, and cannot depend on having - the GNU library available, so FILE objects just don't cut it. - - This file is written as a separate module, but can be included by - cp-lex.c for very minor efficiency gains (primarily in function - inlining). */ - -#include -#include "obstack.h" - -extern FILE *finput; - -struct pending_input *save_pending_input (); -void restore_pending_input (); - -struct input_source { - /* saved string */ - char *str; - int length; - /* current position, when reading as input */ - int offset; - /* obstack to free this input string from when finished, if any */ - struct obstack *obstack; - /* linked list maintenance */ - struct input_source *next; - /* values to restore after reading all of current string */ - char *filename; - int lineno; - struct pending_input *input; - int putback_char; -}; - -static struct input_source *input, *free_inputs; - -extern char *input_filename; -extern int lineno; - -#ifdef __GNUC__ -#define inline __inline__ -#else -#define inline -#endif - -static inline struct input_source * -allocate_input () -{ - struct input_source *inp; - if (free_inputs) - { - inp = free_inputs; - free_inputs = inp->next; - inp->next = 0; - return inp; - } - inp = (struct input_source *) xmalloc (sizeof (struct input_source)); - inp->next = 0; - inp->obstack = 0; - return inp; -} - -static inline void -free_input (inp) - struct input_source *inp; -{ - if (inp->obstack) - obstack_free (inp->obstack, inp->str); - inp->obstack = 0; - inp->str = 0; - inp->length = 0; - inp->next = free_inputs; - free_inputs = inp; -} - -static int putback_char = -1; - -/* Some of these external functions are declared inline in case this file - is included in cp-lex.c. */ - -inline -void -feed_input (str, len, delete) - char *str; - int len; - struct obstack *delete; -{ - struct input_source *inp = allocate_input (); - - /* This shouldn't be necessary. */ - while (len && !str[len-1]) - len--; - - inp->str = str; - inp->length = len; - inp->obstack = delete; - inp->offset = 0; - inp->next = input; - inp->filename = input_filename; - inp->lineno = lineno; - inp->input = save_pending_input (); - inp->putback_char = putback_char; - putback_char = -1; - input = inp; -} - -struct pending_input *to_be_restored; /* XXX */ -extern int end_of_file; - -int -getch () -{ - if (putback_char != -1) - { - int ch = putback_char; - putback_char = -1; - return ch; - } - if (input) - { - if (input->offset == input->length) - { - struct input_source *inp = input; - my_friendly_assert (putback_char == -1, 223); - to_be_restored = inp->input; - input->offset++; - return EOF; - } - else if (input->offset > input->length) - { - struct input_source *inp = input; - - end_of_file = 0; - input = inp->next; - input_filename = inp->filename; - lineno = inp->lineno; - /* Get interface/implementation back in sync. */ - extract_interface_info (); - putback_char = inp->putback_char; - free_input (inp); - return getch (); - } - if (input) - return input->str[input->offset++]; - } - return getc (finput); -} - -inline -void -put_back (ch) - int ch; -{ - my_friendly_assert (putback_char == -1, 224); - putback_char = ch; -} - -inline -int -input_redirected () -{ - return input != 0; -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-lex.c b/gnu/usr.bin/gcc2/cc1plus/cp-lex.c deleted file mode 100644 index ca20fb25e07..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-lex.c +++ /dev/null @@ -1,4235 +0,0 @@ -/* Separate lexical analyzer for GNU C++. - Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - -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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-lex.c,v 1.1.1.1 1995/10/18 08:39:32 deraadt Exp $"; -#endif /* not lint */ - -/* This file is the lexical analyzer for GNU C++. */ - -#if defined(GATHER_STATISTICS) || defined(SPEW_DEBUG) -#undef YYDEBUG -#define YYDEBUG 1 -#endif - -#include -#include -#include -#include -#include "config.h" -#include "input.h" -#include "tree.h" -#include "cp-lex.h" -#include "cp-parse.h" -#include "cp-tree.h" -#include "flags.h" -#include "obstack.h" - -#ifdef MULTIBYTE_CHARS -#include -#include -#endif - -#ifndef errno -extern int errno; /* needed for VAX. */ -#endif -extern jmp_buf toplevel; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern struct obstack *expression_obstack, permanent_obstack; -extern struct obstack *current_obstack, *saveable_obstack; - -extern double atof (); - -extern char *get_directive_line (); /* In c-common.c */ - -/* Given a file name X, return the nondirectory portion. - Keep in mind that X can be computed more than once. */ -#ifndef FILE_NAME_NONDIRECTORY -#define FILE_NAME_NONDIRECTORY(X) \ - (rindex (X, '/') != 0 ? rindex (X, '/') + 1 : X) -#endif - -extern char *index (); -extern char *rindex (); - -void extract_interface_info (); -void yyerror (); - -/* This obstack is needed to hold text. It is not safe to use - TOKEN_BUFFER because `check_newline' calls `yylex'. */ -static struct obstack inline_text_obstack; -static char *inline_text_firstobj; - -int end_of_file; - -extern int first_token; -extern struct obstack token_obstack; - -/* ??? Don't really know where this goes yet. */ -#if 1 -#include "cp-input.c" -#else -extern void put_back (/* int */); -extern int input_redirected (); -extern void feed_input (/* char *, int, struct obstack * */); -#endif - -/* Holds translations from TREE_CODEs to operator name strings, - i.e., opname_tab[PLUS_EXPR] == "+". */ -char **opname_tab; -char **assignop_tab; - -extern int yychar; /* the lookahead symbol */ -extern YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#if 0 -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -tree lastiddecl; - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -tree ridpointers[(int) RID_MAX]; - -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static tree get_time_identifier (); -static tree filename_times; -static tree this_filename_time; - -/* For implementing #pragma unit. */ -tree current_unit_name; -tree current_unit_language; - -/* Array for holding counts of the numbers of tokens seen. */ -extern int *token_count; - -/* Textual definition used for default functions. */ -static char default_def[] = "{}"; - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - TYPE_QUALS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (type_quals, target) - tree type_quals, target; -{ - if (target && TREE_CODE (target) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (target)) - error ("type name expected before `*'"); - target = build_parse_node (INDIRECT_REF, target); - TREE_TYPE (target) = type_quals; - return target; -} - -/* Return something to represent absolute declarators containing a &. - TARGET is the absolute declarator that the & contains. - TYPE_QUALS is a list of modifiers such as const or volatile - to apply to the reference type, represented as identifiers. - - We return an ADDR_EXPR whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_reference_declarator (type_quals, target) - tree type_quals, target; -{ - if (target) - { - if (TREE_CODE (target) == ADDR_EXPR) - { - error ("cannot declare references to references"); - return target; - } - if (TREE_CODE (target) == INDIRECT_REF) - { - error ("cannot declare pointers to references"); - return target; - } - if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target)) - error ("type name expected before `&'"); - } - target = build_parse_node (ADDR_EXPR, target); - TREE_TYPE (target) = type_quals; - return target; -} - -/* Build names and nodes for overloaded operators. */ - -tree ansi_opname[LAST_CPLUS_TREE_CODE]; -tree ansi_assopname[LAST_CPLUS_TREE_CODE]; - -char * -operator_name_string (name) - tree name; -{ - char *opname = IDENTIFIER_POINTER (name) + 2; - tree *opname_table; - int i, assign; - - /* Works for builtin and user defined types. */ - if (IDENTIFIER_GLOBAL_VALUE (name) - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL) - return IDENTIFIER_POINTER (name); - - if (opname[0] == 'a' && opname[2] != '\0') - { - opname += 1; - assign = 1; - opname_table = ansi_assopname; - } - else - { - assign = 0; - opname_table = ansi_opname; - } - - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign] - && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign]) - break; - } - - if (i == LAST_CPLUS_TREE_CODE) - return ""; - - if (assign) - return assignop_tab[i]; - else - return opname_tab[i]; -} - -int interface_only; /* whether or not current file is only for - interface definitions. */ -int interface_unknown; /* whether or not we know this class - to behave according to #pragma interface. */ - -/* lexical analyzer */ - -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; - -#ifndef WCHAR_TYPE_SIZE -#ifdef INT_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#else -#define WCHAR_TYPE_SIZE BITS_PER_WORD -#endif -#endif - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. */ - -#include "cp-hash.h" - -int check_newline (); - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag = 0; - -static int skip_white_space (); - -static tree -get_time_identifier (name) - char *name; -{ - tree time_identifier; - int len = strlen (name); - char *buf = (char *)alloca (len + 6); - strcpy (buf, "file "); - bcopy (name, buf+5, len); - buf[len+5] = '\0'; - time_identifier = get_identifier (buf); - if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0); - IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1); - IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times; - filename_times = time_identifier; - pop_obstacks (); - } - return time_identifier; -} - -#ifdef __GNUC__ -__inline -#endif -static int -my_get_run_time () -{ - int old_quiet_flag = quiet_flag; - int this_time; - quiet_flag = 0; - this_time = get_run_time (); - quiet_flag = old_quiet_flag; - return this_time; -} - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See cp-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char *cplus_tree_code_type[] = { - "x", -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int cplus_tree_code_length[] = { - 0, -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *cplus_tree_code_name[] = { - "@@dummy", -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* toplev.c needs to call these. */ - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ - put_back (check_newline ()); - - if (flag_cadillac) - cadillac_start (); - if (flag_gnu_xref) GNU_xref_begin (input_filename); -} - -void -lang_finish () -{ - extern int errorcount, sorrycount; - if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount); -} - -char * -lang_identify () -{ - return "cplusplus"; -} - -void -init_filename_times () -{ - this_filename_time = get_time_identifier (""); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = my_get_run_time (); - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time; - } -} - -/* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989. - Stuck this hack in to get the files open correctly; this is called - in place of init_lex if we are an unexec'd binary. */ -void -reinit_lang_specific () -{ - init_filename_times (); - reinit_search_statistics (); -} - -void -init_lex () -{ - extern char *(*decl_printable_name) (); - - int i; - - /* Initialize the lookahead machinery. */ - init_spew (); - - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - decl_printable_name = lang_printable_name; - - init_cplus_expand (); - - tree_code_type - = (char **) realloc (tree_code_type, - sizeof (char *) * LAST_CPLUS_TREE_CODE); - tree_code_length - = (int *) realloc (tree_code_length, - sizeof (int) * LAST_CPLUS_TREE_CODE); - tree_code_name - = (char **) realloc (tree_code_name, - sizeof (char *) * LAST_CPLUS_TREE_CODE); - bcopy ((char *)cplus_tree_code_type, - (char *)(tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); - bcopy ((char *)cplus_tree_code_length, - (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int)); - bcopy ((char *)cplus_tree_code_name, - (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); - - opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - - ansi_opname[0] = get_identifier (""); - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - ansi_opname[i] = ansi_opname[0]; - ansi_assopname[i] = ansi_opname[0]; - } - - ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1; - ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR]; - ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1; - ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR]; - ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1; - ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR]; - ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1; - ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR]; - ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1; - ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1; - ansi_opname[(int) NE_EXPR] = get_identifier ("__ne"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1; - ansi_opname[(int) GT_EXPR] = get_identifier ("__gt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1; - ansi_opname[(int) GE_EXPR] = get_identifier ("__ge"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1; - ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1; - ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1; - ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1; - ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1; - ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR]; - ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1; - ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR]; - ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1; - ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1; - ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1; - ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl"); - ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1; - ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1; - ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR]; - ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR]; - ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1; - ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1; - ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1; - ansi_opname[(int) LT_EXPR] = get_identifier ("__lt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1; - ansi_opname[(int) LE_EXPR] = get_identifier ("__le"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1; - ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1; - ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1; - ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR]; - ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR]; - ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1; - ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1; - ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1; - ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1; - ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR]; - ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1; - ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1; - ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1; - ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1; - ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1; - ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1; - ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; - - /* This is not true: these operators are not defined in ANSI, - but we need them anyway. */ - ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1; - ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1; - ansi_opname[(int) COND_EXPR] = get_identifier ("__cn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1; - ansi_opname[(int) METHOD_CALL_EXPR] = get_identifier ("__wr"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) METHOD_CALL_EXPR]) = 1; - - init_method (); - gcc_obstack_init (&inline_text_obstack); - inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - current_function_decl = NULL; - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers[(int) RID_INT] = get_identifier ("int"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INT])); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR])); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID])); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT])); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE])); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT])); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG], - build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG])); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED])); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED])); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE])); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST])); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE])); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO], - build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO])); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN])); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF])); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], - build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); - - /* C++ extensions. These are probably not correctly named. */ - ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR])); - class_type_node = build_int_2 (class_type, 0); - TREE_TYPE (class_type_node) = class_type_node; - ridpointers[(int) RID_CLASS] = class_type_node; - - record_type_node = build_int_2 (record_type, 0); - TREE_TYPE (record_type_node) = record_type_node; - ridpointers[(int) RID_RECORD] = record_type_node; - - union_type_node = build_int_2 (union_type, 0); - TREE_TYPE (union_type_node) = union_type_node; - ridpointers[(int) RID_UNION] = union_type_node; - - enum_type_node = build_int_2 (enum_type, 0); - TREE_TYPE (enum_type_node) = enum_type_node; - ridpointers[(int) RID_ENUM] = enum_type_node; - - ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); - ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); - - ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC])); - ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE])); - ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); - - /* Exception handling extensions. */ - exception_type_node = build_int_2 (exception_type, 0); - TREE_TYPE (exception_type_node) = exception_type_node; - ridpointers[(int) RID_EXCEPTION] = exception_type_node; - - opname_tab[(int) COMPONENT_REF] = "->"; - opname_tab[(int) MEMBER_REF] = "->*"; - opname_tab[(int) METHOD_CALL_EXPR] = "->()"; - opname_tab[(int) INDIRECT_REF] = "(unary *)"; - opname_tab[(int) ARRAY_REF] = "[]"; - opname_tab[(int) MODIFY_EXPR] = "="; - opname_tab[(int) NEW_EXPR] = "new"; - opname_tab[(int) DELETE_EXPR] = "delete"; - opname_tab[(int) COND_EXPR] = "... ? ... : ..."; - opname_tab[(int) CALL_EXPR] = "()"; - opname_tab[(int) PLUS_EXPR] = "+"; - opname_tab[(int) MINUS_EXPR] = "-"; - opname_tab[(int) MULT_EXPR] = "*"; - opname_tab[(int) TRUNC_DIV_EXPR] = "/"; - opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)"; - opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)"; - opname_tab[(int) ROUND_DIV_EXPR] = "(round /)"; - opname_tab[(int) TRUNC_MOD_EXPR] = "%"; - opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; - opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; - opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; - opname_tab[(int) NEGATE_EXPR] = "-"; - opname_tab[(int) MIN_EXPR] = "?"; - opname_tab[(int) ABS_EXPR] = "abs"; - opname_tab[(int) FFS_EXPR] = "ffs"; - opname_tab[(int) LSHIFT_EXPR] = "<<"; - opname_tab[(int) RSHIFT_EXPR] = ">>"; - opname_tab[(int) BIT_IOR_EXPR] = "|"; - opname_tab[(int) BIT_XOR_EXPR] = "^"; - opname_tab[(int) BIT_AND_EXPR] = "&"; - opname_tab[(int) BIT_ANDTC_EXPR] = "&~"; - opname_tab[(int) BIT_NOT_EXPR] = "~"; - opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&"; - opname_tab[(int) TRUTH_ORIF_EXPR] = "||"; - opname_tab[(int) TRUTH_AND_EXPR] = "strict &&"; - opname_tab[(int) TRUTH_OR_EXPR] = "strict ||"; - opname_tab[(int) TRUTH_NOT_EXPR] = "!"; - opname_tab[(int) LT_EXPR] = "<"; - opname_tab[(int) LE_EXPR] = "<="; - opname_tab[(int) GT_EXPR] = ">"; - opname_tab[(int) GE_EXPR] = ">="; - opname_tab[(int) EQ_EXPR] = "=="; - opname_tab[(int) NE_EXPR] = "!="; - opname_tab[(int) IN_EXPR] = "in"; - opname_tab[(int) RANGE_EXPR] = ".."; - opname_tab[(int) CONVERT_EXPR] = "(unary +)"; - opname_tab[(int) ADDR_EXPR] = "(unary &)"; - opname_tab[(int) PREDECREMENT_EXPR] = "--"; - opname_tab[(int) PREINCREMENT_EXPR] = "++"; - opname_tab[(int) POSTDECREMENT_EXPR] = "--"; - opname_tab[(int) POSTINCREMENT_EXPR] = "++"; - opname_tab[(int) COMPOUND_EXPR] = ","; - - assignop_tab[(int) NOP_EXPR] = "="; - assignop_tab[(int) PLUS_EXPR] = "+="; - assignop_tab[(int) CONVERT_EXPR] = "+="; - assignop_tab[(int) MINUS_EXPR] = "-="; - assignop_tab[(int) NEGATE_EXPR] = "-="; - assignop_tab[(int) MULT_EXPR] = "*="; - assignop_tab[(int) INDIRECT_REF] = "*="; - assignop_tab[(int) TRUNC_DIV_EXPR] = "/="; - assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)"; - assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)"; - assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)"; - assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)"; - assignop_tab[(int) TRUNC_MOD_EXPR] = "%="; - assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)"; - assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)"; - assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)"; - assignop_tab[(int) MIN_EXPR] = "?="; - assignop_tab[(int) LSHIFT_EXPR] = "<<="; - assignop_tab[(int) RSHIFT_EXPR] = ">>="; - assignop_tab[(int) BIT_IOR_EXPR] = "|="; - assignop_tab[(int) BIT_XOR_EXPR] = "^="; - assignop_tab[(int) BIT_AND_EXPR] = "&="; - assignop_tab[(int) ADDR_EXPR] = "&="; - - init_filename_times (); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - - if (flag_ansi_exceptions) - flag_handle_exceptions = 2; - - if (!flag_ansi_exceptions) - { - UNSET_RESERVED_WORD ("catch"); - } - - if (! flag_handle_exceptions) - { - /* Easiest way to not recognize exception - handling extensions... */ - UNSET_RESERVED_WORD ("all"); - UNSET_RESERVED_WORD ("except"); - UNSET_RESERVED_WORD ("exception"); - UNSET_RESERVED_WORD ("raise"); - UNSET_RESERVED_WORD ("raises"); - UNSET_RESERVED_WORD ("reraise"); - UNSET_RESERVED_WORD ("try"); - UNSET_RESERVED_WORD ("throw"); - } - else if (flag_ansi_exceptions) - { - /* Easiest way to not recognize exception - handling extensions... */ - UNSET_RESERVED_WORD ("exception"); - UNSET_RESERVED_WORD ("all"); - UNSET_RESERVED_WORD ("except"); - UNSET_RESERVED_WORD ("raise"); - UNSET_RESERVED_WORD ("raises"); - UNSET_RESERVED_WORD ("reraise"); - is_reserved_word ("try", sizeof ("try") - 1)->token = ANSI_TRY; - is_reserved_word ("throw", sizeof ("throw") - 1)->token = ANSI_THROW; - } - if (! (flag_gc || flag_dossier)) - { - UNSET_RESERVED_WORD ("classof"); - UNSET_RESERVED_WORD ("headof"); - } - if (flag_no_asm) - UNSET_RESERVED_WORD ("asm"); - if (flag_no_asm || flag_traditional) - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("dynamic"); - - token_count = init_parse (); - interface_unknown = 1; -} - -void -reinit_parse_for_function () -{ - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; -} - -#ifdef __GNUC__ -__inline -#endif -void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; -{ - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case TYPESPEC: - case PTYPENAME: - case IDENTIFIER_DEFN: - case TYPENAME_DEFN: - case PTYPENAME_DEFN: - case TYPENAME_COLON: - case TYPENAME_ELLIPSIS: - case SCOPED_TYPENAME: - case SCSPEC: - t = yylval.ttype; - print_id: - my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224); - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - case AGGR: - if (yylval.ttype == class_type_node) - fprintf (file, " `class'"); - else if (yylval.ttype == record_type_node) - fprintf (file, " `struct'"); - else if (yylval.ttype == union_type_node) - fprintf (file, " `union'"); - else if (yylval.ttype == enum_type_node) - fprintf (file, " `enum'"); - else - my_friendly_abort (80); - break; - case PRE_PARSED_CLASS_DECL: - t = yylval.ttype; - my_friendly_assert (TREE_CODE (t) == TREE_LIST, 225); - t = TREE_VALUE (t); - goto print_id; - } -} - -static int *reduce_count; -int *token_count; - -#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) -#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) - -int * -init_parse () -{ -#ifdef GATHER_STATISTICS - reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1)); - bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1)); - reduce_count += 1; - token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1)); - bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1)); - token_count += 1; -#endif - return token_count; -} - -#ifdef GATHER_STATISTICS -void -yyhook (yyn) - int yyn; -{ - reduce_count[yyn] += 1; -} -#endif - -static int -reduce_cmp (p, q) - int *p, *q; -{ - return reduce_count[*q] - reduce_count[*p]; -} - -static int -token_cmp (p, q) - int *p, *q; -{ - return token_count[*q] - token_count[*p]; -} - -void -print_parse_statistics () -{ -#ifdef GATHER_STATISTICS -#if YYDEBUG != 0 - int i; - int maxlen = REDUCE_LENGTH; - unsigned *sorted; - - if (reduce_count[-1] == 0) - return; - - if (TOKEN_LENGTH > REDUCE_LENGTH) - maxlen = TOKEN_LENGTH; - sorted = (unsigned *) alloca (sizeof (int) * maxlen); - - for (i = 0; i < TOKEN_LENGTH; i++) - sorted[i] = i; - qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp); - for (i = 0; i < TOKEN_LENGTH; i++) - { - int index = sorted[i]; - if (token_count[index] == 0) - break; - if (token_count[index] < token_count[-1]) - break; - fprintf (stderr, "token %d, `%s', count = %d\n", - index, yytname[YYTRANSLATE (index)], token_count[index]); - } - fprintf (stderr, "\n"); - for (i = 0; i < REDUCE_LENGTH; i++) - sorted[i] = i; - qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp); - for (i = 0; i < REDUCE_LENGTH; i++) - { - int index = sorted[i]; - if (reduce_count[index] == 0) - break; - if (reduce_count[index] < reduce_count[-1]) - break; - fprintf (stderr, "rule %d, line %d, count = %d\n", - index, yyrline[index], reduce_count[index]); - } - fprintf (stderr, "\n"); -#endif -#endif -} - -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ -void -set_yydebug (value) - int value; -{ -#if YYDEBUG != 0 - extern int yydebug; - yydebug = value; -#else - warning ("YYDEBUG not defined."); -#endif -} - -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} - -#endif - -/* Functions and data structures for #pragma interface. - - `#pragma implementation' means that the main file being compiled - is considered to implement (provide) the classes that appear in - its main body. I.e., if this is file "foo.cc", and class `bar' - is defined in "foo.cc", then we say that "foo.cc implements bar". - - All main input files "implement" themselves automagically. - - `#pragma interface' means that unless this file (of the form "foo.h" - is not presently being included by file "foo.cc", the - CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none - of the vtables nor any of the inline functions defined in foo.h - will ever be output. - - There are cases when we want to link files such as "defs.h" and - "main.cc". In this case, we give "defs.h" a `#pragma interface', - and "main.cc" has `#pragma implementation "defs.h"'. */ - -struct impl_files -{ - char *filename; - struct impl_files *next; -}; - -static struct impl_files *impl_file_chain; - -/* Helper function to load global variables with interface - information. */ -void -extract_interface_info () -{ - tree fileinfo = get_time_identifier (input_filename); - fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo); - interface_only = TREE_INT_CST_LOW (fileinfo); - interface_unknown = TREE_INT_CST_HIGH (fileinfo); -} - -/* Return nonzero if S and T are not considered part of an - INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ -static int -interface_strcmp (s) - char *s; -{ - /* Set the interface/implementation bits for this scope. */ - struct impl_files *ifiles; - char *s1; - - s = FILE_NAME_NONDIRECTORY (s); - - for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) - { - char *t1 = ifiles->filename; - s1 = s; - - if (*s1 != *t1 || *s1 == 0) - continue; - - while (*s1 == *t1 && *s1 != 0) - s1++, t1++; - - /* A match. */ - if (*s1 == *t1) - return 0; - - /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ - if (index (s1, '.') || index (t1, '.')) - continue; - - if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') - continue; - - /* A match. */ - return 0; - } - - /* No matches. */ - return 1; -} - -void -set_typedecl_interface_info (prev, vars) - tree prev, vars; -{ - tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); - tree fileinfo = IDENTIFIER_CLASS_VALUE (id); - tree type = TREE_TYPE (vars); - - CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) - = interface_strcmp (DECL_SOURCE_FILE (vars)); -} - -void -set_vardecl_interface_info (prev, vars) - tree prev, vars; -{ - tree type = DECL_CONTEXT (vars); - - if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0) - { - if (CLASSTYPE_INTERFACE_ONLY (type)) - set_typedecl_interface_info (prev, TYPE_NAME (type)); - else - CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; - DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); - TREE_PUBLIC (vars) = 1; - } -} - -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. */ -void -do_pending_inlines () -{ - struct pending_inline *prev = 0, *tail; - struct pending_inline *t; - - /* Reverse the pending inline functions, since - they were cons'd instead of appended. */ - - for (t = pending_inlines; t; t = tail) - { - t->deja_vu = 1; - tail = t->next; - t->next = prev; - prev = t; - } - /* Reset to zero so that if the inline functions we are currently - processing define inline functions of their own, that is handled - correctly. ??? This hasn't been checked in a while. */ - pending_inlines = 0; - - /* Now start processing the first inline function. */ - t = prev; - my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE), - 226); - if (t->parm_vec) - push_template_decls (t->parm_vec, t->bindings, 0); - if (t->len > 0) - { - feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0); - lineno = t->lineno; -#if 0 - if (input_filename != t->filename) - { - input_filename = t->filename; - /* Get interface/implementation back in sync. */ - extract_interface_info (); - } -#else - input_filename = t->filename; - interface_unknown = t->interface == 1; - interface_only = t->interface == 0; -#endif - yychar = PRE_PARSED_FUNCTION_DECL; - } - /* Pass back a handle on the rest of the inline functions, so that they - can be processed later. */ - yylval.ttype = build_tree_list ((tree) t, t->fndecl); - if (flag_default_inline && t->fndecl - /* If we're working from a template, don't change - the `inline' state. */ - && t->parm_vec == NULL_TREE) - DECL_INLINE (t->fndecl) = 1; - DECL_PENDING_INLINE_INFO (t->fndecl) = 0; -} - -extern struct pending_input *to_be_restored; -static int nextchar = -1; - -void -process_next_inline (t) - tree t; -{ - struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); - my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), - 227); - if (i->parm_vec) - pop_template_decls (i->parm_vec, i->bindings, 0); - i = i->next; - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - /* restore_pending_input will abort unless yychar is either - * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - * hosed, feed back YYEMPTY. - * We also need to discard nextchar, since that may have gotten - * set as well. - */ - nextchar = -1; - } - yychar = YYEMPTY; - if (to_be_restored == 0) - my_friendly_abort (123); - restore_pending_input (to_be_restored); - to_be_restored = 0; - if (i && i->fndecl != NULL_TREE) - { - my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), - 228); - if (i->parm_vec) - push_template_decls (i->parm_vec, i->bindings, 0); - feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0); - lineno = i->lineno; - input_filename = i->filename; - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.ttype = build_tree_list ((tree) i, i->fndecl); - if (flag_default_inline - /* If we're working from a template, don't change - the `inline' state. */ - && i->parm_vec == NULL_TREE) - DECL_INLINE (i->fndecl) = 1; - DECL_PENDING_INLINE_INFO (i->fndecl) = 0; - } - if (i) - { - interface_unknown = i->interface == 1; - interface_only = i->interface == 0; - } - else - extract_interface_info (); -} - -/* Since inline methods can refer to text which has not yet been seen, - we store the text of the method in a structure which is placed in the - DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. - After parsing the body of the class definition, the FUNCTION_DECL's are - scanned to see which ones have this field set. Those are then digested - one at a time. - - This function's FUNCTION_DECL will have a bit set in its common so - that we know to watch out for it. */ - -void -consume_string (this_obstack) - register struct obstack *this_obstack; -{ - register char c; - do - { - c = getch (); - if (c == '\\') - { - obstack_1grow (this_obstack, c); - c = getch (); - obstack_1grow (this_obstack, c); - continue; - } - if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } - obstack_1grow (this_obstack, c); - } - while (c != '\"'); -} - -static int nextyychar = YYEMPTY; -static YYSTYPE nextyylval; - -struct pending_input { - int nextchar, yychar, nextyychar, eof; - YYSTYPE yylval, nextyylval; - struct obstack token_obstack; - int first_token; -}; - -struct pending_input * -save_pending_input () -{ - struct pending_input *p; - p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); - p->nextchar = nextchar; - p->yychar = yychar; - p->nextyychar = nextyychar; - p->yylval = yylval; - p->nextyylval = nextyylval; - p->eof = end_of_file; - yychar = nextyychar = YYEMPTY; - nextchar = -1; - p->first_token = first_token; - p->token_obstack = token_obstack; - - first_token = 0; - gcc_obstack_init (&token_obstack); - end_of_file = 0; - return p; -} - -void -restore_pending_input (p) - struct pending_input *p; -{ - my_friendly_assert (nextchar == -1, 229); - nextchar = p->nextchar; - my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); - yychar = p->yychar; - my_friendly_assert (nextyychar == YYEMPTY, 231); - nextyychar = p->nextyychar; - yylval = p->yylval; - nextyylval = p->nextyylval; - first_token = p->first_token; - obstack_free (&token_obstack, (char *) 0); - token_obstack = p->token_obstack; - end_of_file = p->eof; - free (p); -} - -/* Return next non-whitespace input character, which may come - from `finput', or from `nextchar'. */ -static int -yynextch () -{ - int c; - - if (nextchar >= 0) - { - c = nextchar; - nextchar = -1; - } - else c = getch (); - return skip_white_space (c); -} - -/* Unget character CH from the input stream. - If RESCAN is non-zero, then we want to `see' this - character as the next input token. */ -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - if (nextchar >= 0) - put_back (nextchar); - nextchar = ch; - } - else - { - my_friendly_assert (nextyychar == YYEMPTY, 232); - nextyychar = yychar; - nextyylval = yylval; - yychar = ch; - } -} - -/* This function stores away the text for an inline function that should - be processed later. It decides how much later, and may need to move - the info between obstacks; therefore, the caller should not refer to - the T parameter after calling this function. - - This function also stores the list of template-parameter bindings that - will be needed for expanding the template, if any. */ - -static void -store_pending_inline (decl, t) - tree decl; - struct pending_inline *t; -{ - extern int processing_template_defn; - int delay_to_eof = 0; - struct pending_inline **inlines; - - t->fndecl = decl; - /* Default: compile right away, and no extra bindings are needed. */ - t->parm_vec = t->bindings = 0; - if (processing_template_defn) - { - tree type = current_class_type; - /* Assumption: In this (possibly) nested class sequence, only - one name will have template parms. */ - while (type && TREE_CODE_CLASS (TREE_CODE (type)) == 't') - { - tree decl = TYPE_NAME (type); - tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl)); - if (tmpl) - { - t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec; - t->bindings = TREE_VALUE (tmpl); - } - type = DECL_CONTEXT (decl); - } - if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE - || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) - { - if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - my_friendly_assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type, - 233); - - /* Inline functions can be compiled immediately. Other functions - will be output separately, so if we're in interface-only mode, - punt them now, or output them now if we're doing implementations - and we know no overrides will exist. Otherwise, we delay until - end-of-file, to see if the definition is really required. */ - if (DECL_INLINE (decl)) - /* delay_to_eof == 0 */; - else if (current_class_type && !interface_unknown) - { - if (interface_only) - { -#if 0 - print_node_brief (stderr, "\ndiscarding text for ", decl, 0); -#endif - if (t->can_free) - obstack_free (&inline_text_obstack, t->buf); - DECL_PENDING_INLINE_INFO (decl) = 0; - return; - } - } - /* Don't delay the processing of virtual functions. */ - else if (DECL_VINDEX (decl) == NULL_TREE) - delay_to_eof = 1; - } - else - my_friendly_abort (58); - } - - if (delay_to_eof) - { - extern struct pending_inline *pending_template_expansions; - - if (t->can_free) - { - char *free_to = t->buf; - t->buf = (char *) obstack_copy (&permanent_obstack, t->buf, - t->len + 1); - t = (struct pending_inline *) obstack_copy (&permanent_obstack, - (char *)t, sizeof (*t)); - obstack_free (&inline_text_obstack, free_to); - } - inlines = &pending_template_expansions; - t->can_free = 0; - } - else - { - inlines = &pending_inlines; - DECL_PENDING_INLINE_INFO (decl) = t; - } - - /* Because we use obstacks, we must process these in precise order. */ - t->next = *inlines; - *inlines = t; -} - -void reinit_parse_for_block (); - -void -reinit_parse_for_method (yychar, decl) - int yychar; - tree decl; -{ - int len; - int starting_lineno = lineno; - char *starting_filename = input_filename; - - reinit_parse_for_block (yychar, &inline_text_obstack, 0); - - len = obstack_object_size (&inline_text_obstack); - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - if (decl == void_type_node - || (current_class_type && TYPE_REDEFINED (current_class_type))) - { - /* Happens when we get two declarations of the same - function in the same scope. */ - char *buf = obstack_finish (&inline_text_obstack); - obstack_free (&inline_text_obstack, buf); - return; - } - else - { - struct pending_inline *t; - char *buf = obstack_finish (&inline_text_obstack); - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->buf = buf; - t->len = len; - t->lineno = starting_lineno; - t->filename = starting_filename; - t->token = YYEMPTY; - t->can_free = 1; - t->deja_vu = 0; - t->interface = ((interface_unknown || processing_template_defn) - ? 1 - : (interface_only ? 0 : 2)); - store_pending_inline (decl, t); - } -} - -/* Consume a block -- actually, a method or template definition beginning - with `:' or `{' -- and save it away on the specified obstack. - - Argument IS_TEMPLATE indicates which set of error messages should be - output if something goes wrong. This should really be cleaned up somehow, - without loss of clarity. */ -void -reinit_parse_for_block (yychar, obstackp, is_template) - int yychar; - struct obstack *obstackp; - int is_template; -{ - register int c = 0; - int blev = 1; - int starting_lineno = lineno; - char *starting_filename = input_filename; - int len; - int look_for_semicolon = 0; - - if (yychar == '{') - obstack_1grow (obstackp, '{'); - else if (yychar == '=') - { - look_for_semicolon = 1; - } - else - { - if (yychar != ':' && (yychar != RETURN || is_template)) - { - yyerror (is_template - ? "parse error in template specification" - : "parse error in method specification"); - yychar = '{'; - } - obstack_1grow (obstackp, yychar); - while (c >= 0) - { - int this_lineno = lineno; - - c = yynextch (); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10 /* + strlen (input_filename) */) - { - int i; - for (i = lineno - this_lineno; i > 0; i--) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - /* strings must be read differently than text. */ - if (c == '\"') - { - obstack_1grow (obstackp, c); - consume_string (obstackp); - c = yynextch (); - } - while (c > ' ') /* ASCII dependent! */ - { - obstack_1grow (obstackp, c); - if (c == '{') - goto main_loop; - if (c == '\"') - consume_string (obstackp); - if (c == ';') - { - error (is_template - ? "template body missing" - : "function body for constructor missing"); - obstack_1grow (obstackp, '{'); - obstack_1grow (obstackp, '}'); - len += 2; - goto done; - } - c = getch (); - } - if (c == '\n') - lineno++; - obstack_1grow (obstackp, c); - } - if (c == EOF) - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - } - - main_loop: - while (c >= 0) - { - int this_lineno = lineno; - - c = skip_white_space (getch ()); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno - this_lineno) - { - if (lineno - this_lineno == 1) - obstack_1grow (obstackp, '\n'); - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - } - - while (c > ' ') - { - obstack_1grow (obstackp, c); - if (c == '{') blev++; - else if (c == '}') - { - blev--; - if (blev == 0 && !look_for_semicolon) - goto done; - } - else if (c == '\"') - consume_string (obstackp); - else if (c == ';' && look_for_semicolon && blev == 0) - goto done; - c = getch (); - } - if (c == '\n') - lineno++; - obstack_1grow (obstackp, c); - } - done: - obstack_1grow (obstackp, '\0'); -} - -/* Build a default function named NAME for type TYPE. - KIND says what to build. - - When KIND == 0, build default destructor. - When KIND == 1, build virtual destructor. - When KIND == 2, build default constructor. - When KIND == 3, build default X(const X&) constructor. - When KIND == 4, build default X(X&) constructor. */ - -tree -cons_up_default_function (type, name, kind) - tree type, name; - int kind; -{ - extern tree void_list_node; - int len; - tree declspecs = NULL_TREE; - tree fn, args; - tree argtype; - - name = constructor_name (name); - switch (kind) - { - /* Destructors. */ - case 1: - declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]); - /* Fall through... */ - case 0: - name = build_parse_node (BIT_NOT_EXPR, name); - /* Fall through... */ - case 2: - /* Default constructor. */ - args = void_list_node; - break; - - case 3: - type = build_type_variant (type, 1, 0); - /* Fall through... */ - case 4: - argtype = build_reference_type (type); - args = tree_cons (NULL_TREE, - build_tree_list (hash_tree_chain (argtype, NULL_TREE), - get_identifier ("arg")), - void_list_node); - break; - - default: - my_friendly_abort (59); - } - - fn = start_method (declspecs, - build_parse_node (CALL_EXPR, name, args, NULL_TREE), - NULL_TREE); - if (fn == void_type_node) - return fn; - - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - - len = 3; - - { - struct pending_inline *t; - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->buf = default_def; - t->len = len; - t->lineno = lineno; - t->filename = input_filename; - t->token = YYEMPTY; - t->can_free = 0; - t->deja_vu = 0; - t->interface = ((interface_unknown || processing_template_defn) - ? 1 - : (interface_only ? 0 : 2)); - store_pending_inline (fn, t); - /* We make this declaration private (static in the C sense). */ - TREE_PUBLIC (fn) = 0; - } - finish_method (fn); - DECL_CLASS_CONTEXT (fn) = type; - /* Show that this function was generated by the compiler. */ - DECL_SOURCE_LINE (fn) = 0; - return fn; -} - -/* Heuristic to tell whether the user is missing a semicolon - after a struct or enum declaration. Emit an error message - if we know the user has blown it. */ -void -check_for_missing_semicolon (type) - tree type; -{ - if (yychar < 0) - yychar = yylex (); - - if (yychar > 255 - && yychar != IDENTIFIER - && yychar != TYPENAME) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - error ("semicolon missing after %s declaration", - TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); - else - error ("semicolon missing after declaration of `%s'", - TYPE_NAME_STRING (type)); - shadow_tag (build_tree_list (0, type)); - } - /* Could probably also hack cases where class { ... } f (); appears. */ - clear_anon_tags (); -} - -void -note_got_semicolon (type) - tree type; -{ - if (TREE_CODE_CLASS (TREE_CODE (type)) != 't') - my_friendly_abort (60); - if (IS_AGGR_TYPE (type)) - CLASSTYPE_GOT_SEMICOLON (type) = 1; -} - -void -note_list_got_semicolon (declspecs) - tree declspecs; -{ - tree link; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - tree type = TREE_VALUE (link); - if (TREE_CODE_CLASS (TREE_CODE (type)) == 't') - note_got_semicolon (type); - } - clear_anon_tags (); -} - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - for (;;) - { - switch (c) - { - case '\n': - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\r': - case '\v': - case '\b': - do - c = getch (); - while (c == ' ' || c == '\t'); - break; - - case '\\': - c = getch (); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = getch (); - break; - - default: - return (c); - } - } -} - - - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static char * -extend_token_buffer (p) - char *p; -{ - int offset = p - token_buffer; - - maxtoken = maxtoken * 2 + 10; - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); - - return token_buffer + offset; -} - -static int -get_last_nonwhite_on_line () -{ - register int c; - - /* Is this the last nonwhite stuff on the line? */ - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - while (c == ' ' || c == '\t') - c = getch (); - return c; -} - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. */ - -int -check_newline () -{ - register int c; - register int token; - - lineno++; - - /* Read first nonwhite char on the line. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - if (c != '#') - { - /* If not #, return it so caller will use it. */ - return c; - } - - /* Read first nonwhite char after the `#'. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma'. */ - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (c == 'p') - { - if (getch () == 'r' - && getch () == 'a' - && getch () == 'g' - && getch () == 'm' - && getch () == 'a') - { - /* Read first nonwhite char after the `#pragma'. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - if (c == 'v' - && getch () == 't' - && getch () == 'a' - && getch () == 'b' - && getch () == 'l' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { - extern tree pending_vtables; - - /* More follows: it must be a string constant (class name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma vtable"); - goto skipline; - } - if (write_virtuals != 2) - { - warning ("use `+e2' option to enable #pragma vtable"); - goto skipline; - } - pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables); - if (nextchar < 0) - nextchar = getch (); - c = nextchar; - if (c != '\n') - warning ("trailing characters ignored"); - } - else if (c == 'u' - && getch () == 'n' - && getch () == 'i' - && getch () == 't' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { - /* More follows: it must be a string constant (unit name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma unit"); - goto skipline; - } - current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype)); - current_unit_language = current_lang_name; - if (nextchar < 0) - nextchar = getch (); - c = nextchar; - if (c != '\n') - warning ("trailing characters ignored"); - } - else if (c == 'i') - { - tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); - c = getch (); - - if (c == 'n' - && getch () == 't' - && getch () == 'e' - && getch () == 'r' - && getch () == 'f' - && getch () == 'a' - && getch () == 'c' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { - /* read to newline. */ - while (c != '\n') - c = getch (); - - write_virtuals = 3; - - if (impl_file_chain == 0) - { - char *filename; - tree fi; - - /* If this is zero at this point, then we are - auto-implementing. */ - if (main_input_filename == 0) - main_input_filename = input_filename; - - filename = FILE_NAME_NONDIRECTORY (main_input_filename); - fi = get_time_identifier (filename); - fi = IDENTIFIER_CLASS_VALUE (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = filename; - impl_file_chain->next = 0; - } - - interface_only = interface_strcmp (input_filename); - interface_unknown = 0; - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - } - else if (c == 'm' - && getch () == 'p' - && getch () == 'l' - && getch () == 'e' - && getch () == 'm' - && getch () == 'e' - && getch () == 'n' - && getch () == 't' - && getch () == 'a' - && getch () == 't' - && getch () == 'i' - && getch () == 'o' - && getch () == 'n' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { - char *main_filename = main_input_filename ? main_input_filename : input_filename; - - while (c == ' ' || c == '\t') - c = getch (); - if (c != '\n') - { - put_back (c); - token = real_yylex (); - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma implementation'"); - goto skipline; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - } - main_filename = FILE_NAME_NONDIRECTORY (main_filename); - - /* read to newline. */ - while (c != '\n') - c = getch (); - - if (write_virtuals == 3) - { - struct impl_files *ifiles = impl_file_chain; - while (ifiles) - { - if (! strcmp (ifiles->filename, main_filename)) - break; - ifiles = ifiles->next; - } - if (ifiles == 0) - { - ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files)); - ifiles->filename = main_filename; - ifiles->next = impl_file_chain; - impl_file_chain = ifiles; - } - } - else if ((main_input_filename != 0 - && ! strcmp (main_input_filename, input_filename)) - || ! strcmp (input_filename, main_filename)) - { - write_virtuals = 3; - if (impl_file_chain == 0) - { - impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = main_filename; - impl_file_chain->next = 0; - } - } - else - error ("`#pragma implementation' can only appear at top-level"); - interface_only = 0; - /* We make this non-zero so that we infer decl linkage - in the impl file only for variables first declared - in the interface file. */ - interface_unknown = 1; - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - } - } - } - goto skipline; - } - else if (c == 'd') - { - if (getch () == 'e' - && getch () == 'f' - && getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'u') - { - if (getch () == 'n' - && getch () == 'd' - && getch () == 'e' - && getch () == 'f' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) - { -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, get_directive_line (finput)); -#endif /* DWARF_DEBUGGING_INFO */ - goto skipline; - } - } - else if (c == 'l') - { - if (getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t')) - goto linenum; - } - else if (c == 'i') - { - if (getch () == 'd' - && getch () == 'e' - && getch () == 'n' - && getch () == 't' - && ((c = getch ()) == ' ' || c == '\t')) - { -#ifdef ASM_OUTPUT_IDENT - extern FILE *asm_out_file; -#endif - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - while (c == ' ' || c == '\t') - c = getch (); - - /* If no argument, ignore the line. */ - if (c == '\n') - return c; - - put_back (c); - token = real_yylex (); - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (! flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - else if (c == 'n') - { - if (getch () == 'e' - && getch () == 'w' - && getch () == 'w' - && getch () == 'o' - && getch () == 'r' - && getch () == 'l' - && getch () == 'd' - && ((c = getch ()) == ' ' || c == '\t')) - { - /* Used to test incremental compilation. */ - sorry ("#pragma newworld"); - goto skipline; - } - } - error ("undefined or invalid # directive"); - goto skipline; - } - -linenum: - /* Here we have either `#line' or `# '. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = getch (); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == '\n') - return c; - - /* Something follows the #; read a token. */ - - put_back (c); - token = real_yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - int old_lineno = lineno; - int used_up = 0; - /* subtract one, because it is the following line that - gets the specified number */ - - int l = TREE_INT_CST_LOW (yylval.ttype) - 1; - c = get_last_nonwhite_on_line (); - if (c == '\n') - { - /* No more: store the line number and check following line. */ - lineno = l; - return c; - } - put_back (c); - - /* More follows: it must be a string constant (filename). */ - - /* Read the string constant, but don't treat \ as special. */ - ignore_escape_flag = 1; - token = real_yylex (); - ignore_escape_flag = 0; - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back - at 0. */ - if (flag_detailed_statistics) - { - int this_time = my_get_run_time (); - tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); - header_time += this_time - body_time; - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) - += this_time - body_time; - this_filename_time = time_identifier; - body_time = this_time; - } - - if (flag_cadillac) - cadillac_note_source (); - - input_filename - = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); - strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); - lineno = l; - GNU_xref_file (input_filename); - - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; - - if (main_input_filename == 0) - { - struct impl_files *ifiles = impl_file_chain; - - if (ifiles) - { - while (ifiles->next) - ifiles = ifiles->next; - ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename); - } - - main_input_filename = input_filename; - if (write_virtuals == 3) - walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); - } - - extract_interface_info (); - - c = get_last_nonwhite_on_line (); - if (c == '\n') - { - if (flag_cadillac) - cadillac_switch_source (-1); - return c; - } - put_back (c); - - token = real_yylex (); - used_up = 0; - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - if (TREE_INT_CST_LOW (yylval.ttype) == 1) - { - /* Pushing to a new file. */ - struct file_stack *p - = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ - - used_up = 1; - if (flag_cadillac) - cadillac_push_source (); - } - else if (TREE_INT_CST_LOW (yylval.ttype) == 2) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - struct file_stack *p = input_file_stack; - - if (flag_cadillac) - cadillac_pop_source (); - - input_file_stack = p->next; - free (p); - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ - } - else - error ("#-lines for entering and leaving files don't match"); - - used_up = 1; - } - } - else if (flag_cadillac) - cadillac_switch_source (-1); - - /* If we have handled a `1' or a `2', - see if there is another number to read. */ - if (used_up) - { - c = get_last_nonwhite_on_line (); - if (c == '\n') - { - if (flag_cadillac) - cadillac_switch_source (-1); - return c; - } - put_back (c); - - token = real_yylex (); - used_up = 0; - } - - /* `3' after file name means this is a system header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 3) - in_system_header = 1; - - /* If NEXTCHAR is not end of line, we don't care what it is. */ - if (nextchar == '\n') - return '\n'; - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - if (c == '\n') - return c; - while ((c = getch ()) != EOF && c != '\n'); - return c; -} - -#if 0 -#define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0) -#define isdigit(char) (char >= '0' && char <= '9') -#else -#include -#endif - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getch (); - register int code; - register unsigned count; - unsigned firstdig; - int nonnull; - - switch (c) - { - case 'x': - if (warn_traditional) - warning ("the meaning of `\\x' varies with -traditional"); - - if (flag_traditional) - return c; - - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getch (); - if (! isxdigit (c)) - { - put_back (c); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= firstdig))) - warning ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getch (); - } - put_back (c); - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - if (warn_traditional) - warning ("the meaning of `\\a' varies with -traditional"); - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; - } - if (c >= 040 && c < 0177) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -/* Value is 1 if we should try to make the next identifier look like a - typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. - Value is -1 if we must not see a type name. */ -int looking_for_typename = 0; - -void -dont_see_typename () -{ - looking_for_typename = -1; - if (yychar == TYPENAME || yychar == PTYPENAME) - { - yychar = IDENTIFIER; - lastiddecl = 0; - } -} - -#ifdef __GNUC__ -extern __inline int identifier_type (); -__inline -#endif -int -identifier_type (decl) - tree decl; -{ - if (TREE_CODE (decl) == TEMPLATE_DECL - && DECL_TEMPLATE_IS_CLASS (decl)) - return PTYPENAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - return TYPENAME; -} - -void -see_typename () -{ - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -1); - if (lastiddecl == 0) - { - if (flag_labels_ok) - lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); - } - else - yychar = identifier_type (lastiddecl); - } -} - -tree -do_identifier (token) - register tree token; -{ - register tree id = lastiddecl; - - if (yychar == YYEMPTY) - yychar = yylex (); - /* Scope class declarations before global - declarations. */ - if (id == IDENTIFIER_GLOBAL_VALUE (token) - && current_class_type != 0 - && TYPE_SIZE (current_class_type) == 0 - && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE) - { - /* Could be from one of the base classes. */ - tree field = lookup_field (current_class_type, token, 1, 0); - if (field == 0) - ; - else if (field == error_mark_node) - /* We have already generated the error message. - But we still want to return this value. */ - id = lookup_field (current_class_type, token, 0, 0); - else if (TREE_CODE (field) == VAR_DECL - || TREE_CODE (field) == CONST_DECL) - id = field; - else if (TREE_CODE (field) != FIELD_DECL) - my_friendly_abort (61); - else - { - error_with_decl (field, "invalid use of member `%s' from base class `%s'", - TYPE_NAME_STRING (DECL_FIELD_CONTEXT (field))); - id = error_mark_node; - return id; - } - } - - if (!id || id == error_mark_node) - { - if (id == error_mark_node && current_class_type != NULL_TREE) - { - id = lookup_nested_field (token, 1); - /* In lookup_nested_field(), we marked this so we can gracefully - leave this whole mess. */ - if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) - return id; - } - if (yychar == '(' || yychar == LEFT_RIGHT) - { - id = implicitly_declare (token); - } - else if (current_function_decl == 0) - { - error ("`%s' was not declared in this scope", - IDENTIFIER_POINTER (token)); - id = error_mark_node; - } - else - { - if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) - { - static int undeclared_variable_notice; - - error ("`%s' undeclared (first use this function)", - IDENTIFIER_POINTER (token)); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - id = error_mark_node; - /* Prevent repeated error messages. */ - IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node; - SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); - } - } - /* TREE_USED is set in `hack_identifier'. */ - if (TREE_CODE (id) == CONST_DECL) - { - if (IDENTIFIER_CLASS_VALUE (token) == id) - { - /* Check visibility. */ - enum visibility_type visibility - = compute_visibility (TYPE_BINFO (current_class_type), id); - if (visibility == visibility_private) - error_with_decl (id, "enum `%s' is private"); - /* protected is OK, since it's an enum of `this'. */ - } - id = DECL_INITIAL (id); - } - else - id = hack_identifier (id, token, yychar); - return id; -} - -tree -identifier_typedecl_value (node) - tree node; -{ - tree t, type; - type = IDENTIFIER_TYPE_VALUE (node); - if (type == NULL_TREE) - return NULL_TREE; -#define do(X) \ - { \ - t = (X); \ - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \ - return t; \ - } - do (IDENTIFIER_LOCAL_VALUE (node)); - do (IDENTIFIER_CLASS_VALUE (node)); - do (IDENTIFIER_GLOBAL_VALUE (node)); -#undef do - /* Will this one ever happen? */ - if (TYPE_NAME (type)) - return TYPE_NAME (type); - - /* We used to do an internal error of 62 here, but instead we will - handle the return of a null appropriately in the callers. */ - return NULL_TREE; -} - -struct try_type -{ - tree *node_var; - char unsigned_flag; - char long_flag; - char long_long_flag; -}; - -struct try_type type_sequence[] = -{ - { &integer_type_node, 0, 0, 0}, - { &unsigned_type_node, 1, 0, 0}, - { &long_integer_type_node, 0, 1, 0}, - { &long_unsigned_type_node, 1, 1, 0}, - { &long_long_integer_type_node, 0, 1, 1}, - { &long_long_unsigned_type_node, 1, 1, 1} -}; - -int -real_yylex () -{ - tree tmp; - register int c; - register int value; - int wide_flag = 0; - int dollar_seen = 0; - int i; - - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getch (); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - token_buffer[0] = '\0'; - end_of_file = 1; - if (input_redirected ()) - value = END_OF_SAVED_INPUT; - else if (do_pending_expansions ()) - /* this will set yychar for us */ - return yychar; - else - value = ENDFILE; - break; - - case '$': - if (dollars_in_ident) - { - dollar_seen = 1; - goto letter; - } - value = '$'; - goto done; - - case 'L': - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = getch (); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - put_back (c); - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '_': - letter: - { - register char *p; - - p = token_buffer; - if (input == 0) - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. - We may have to read the value in `putback_char', so call - `getch' once. */ - *p++ = c; - c = getch (); - - /* Make this run fast. We know that we are reading straight - from FINPUT in this case (since identifiers cannot straddle - input sources. */ - while (isalnum (c) || (c == '_') || c == '$') - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - if (c == '$' && ! dollars_in_ident) - break; - - *p++ = c; - c = getc (finput); - } - } - else - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. */ - *p++ = c; - c = getch (); - - while (isalnum (c) || (c == '_') || c == '$') - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - if (c == '$' && ! dollars_in_ident) - break; - - *p++ = c; - c = getch (); - } - } - - *p = 0; - nextchar = c; - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if (ptr = is_reserved_word (token_buffer, p - token_buffer)) - { - if (ptr->rid) - { - tree old_ttype = ridpointers[(int) ptr->rid]; - - /* If this provides a type for us, then revert lexical - state to standard state. */ - if (TREE_CODE (old_ttype) == IDENTIFIER_NODE - && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0 - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL) - looking_for_typename = 0; - else if (ptr->token == AGGR || ptr->token == ENUM) - looking_for_typename = 1; - - /* Check if this is a language-type declaration. - Just glimpse the next non-white character. */ - nextchar = skip_white_space (nextchar); - if (nextchar == '"') - { - /* We are looking at a string. Complain - if the token before the string is no `extern'. - - Could cheat some memory by placing this string - on the temporary_, instead of the saveable_ - obstack. */ - - if (ptr->rid != RID_EXTERN) - error ("invalid modifier `%s' for language string", - ptr->name); - real_yylex (); - value = EXTERN_LANG_STRING; - yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype)); - break; - } - if (ptr->token == VISSPEC) - { - switch (ptr->rid) - { - case RID_PUBLIC: - yylval.itype = visibility_public; - break; - case RID_PRIVATE: - yylval.itype = visibility_private; - break; - case RID_PROTECTED: - yylval.itype = visibility_protected; - break; - default: - my_friendly_abort (63); - } - } - else - yylval.ttype = old_ttype; - } - value = (int) ptr->token; - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER || value == TYPESPEC) - GNU_xref_ref (current_function_decl, token_buffer); - - if (value == IDENTIFIER) - { - tmp = get_identifier (token_buffer); - -#if !defined(VMS) && defined(JOINER) - /* Make sure that user does not collide with our internal - naming scheme. */ - if (JOINER == '$' - && dollar_seen - && (THIS_NAME_P (tmp) - || VPTR_NAME_P (tmp) - || DESTRUCTOR_NAME_P (tmp) - || VTABLE_NAME_P (tmp) - || TEMP_NAME_P (tmp) - || ANON_AGGRNAME_P (tmp) - || ANON_PARMNAME_P (tmp))) - warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", - token_buffer); -#endif - - yylval.ttype = tmp; - -#if 0 - /* This can not be done this way in C++ because - lookup_name can find ambiguous names, and yield an - error. Because this routine can be called at token - scan time, this is unacceptable. (mrs) */ - - /* A user-invisible read-only initialized variable - should be replaced by its value. We only handle strings - since that's the only case used in C (and C++). */ - tmp = lookup_name (yylval.ttype, 0); - if (tmp != NULL_TREE && TREE_CODE (tmp) == VAR_DECL - && DECL_IGNORED_P (tmp) - && TREE_READONLY (tmp) - && DECL_INITIAL (tmp) != NULL_TREE - && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST) - { - yylval.ttype = DECL_INITIAL (tmp); - value = STRING; - } -#endif - } - if (value == NEW && ! global_bindings_p ()) - { - looking_for_typename = 1; - value = NEW; - goto done; - } - } - break; - - case '.': - { - register int c1 = getch (); - token_buffer[0] = c; - token_buffer[1] = c1; - if (c1 == '*') - { - value = DOT_STAR; - token_buffer[2] = 0; - goto done; - } - if (c1 == '.') - { - c1 = getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - nextchar = c1; - token_buffer[2] = '\0'; - value = RANGE; - goto done; - } - if (isdigit (c1)) - { - put_back (c1); - goto resume_numerical_scan; - } - nextchar = c1; - value = '.'; - token_buffer[1] = 0; - goto done; - } - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int c1 = getch (); - if (! isalnum (c1) && c1 != '.') - { - /* Terminate string. */ - token_buffer[0] = c; - token_buffer[1] = 0; - if (c == '0') - yylval.ttype = integer_zero_node; - else - yylval.ttype = integer_one_node; - nextchar = c1; - value = CONSTANT; - goto done; - } - put_back (c1); - } - /* fall through... */ - case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - resume_numerical_scan: - { - register char *p; - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - /* for multi-precision arithmetic, - we store only 8 live bits in each short. */ - short shorts[MAX_SHORTS]; - int overflow = 0; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; - - p = token_buffer; - *p++ = c; - - for (count = 0; count < MAX_SHORTS; count++) - shorts[count] = 0; - - if (c == '0') - { - *p++ = (c = getch ()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = getch ()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (isalnum (c) && (c != 'l') && (c != 'L') - && (c != 'u') && (c != 'U') - && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) - { - if (c == '.') - { - if (base == 16) - error ("floating constant may not be in radix 16"); - if (floatflag == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - } - else - floatflag = AFTER_POINT; - - base = 10; - *p++ = c = getch (); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. - Otherwise, unread the following non-digit - and use the '.' as a structural token. */ - if (p == token_buffer + 2 && !isdigit (c)) - { - if (c == '.') - { - c = getch (); - if (c == '.') - { - *p++ = '.'; - *p = '\0'; - value = ELLIPSIS; - goto done; - } - nextchar = c; - token_buffer[2] = '\0'; - value = RANGE; - goto done; - } - nextchar = c; - token_buffer[1] = '\0'; - value = '.'; - goto done; - } - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (isdigit (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_POINT; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < MAX_SHORTS; count++) - { - shorts[count] *= base; - if (count) - { - shorts[count] += (shorts[count-1] >> 8); - shorts[count-1] &= (1<<8)-1; - } - else shorts[0] += c; - } - - if (shorts[MAX_SHORTS - 1] >= 1<<8 - || shorts[MAX_SHORTS - 1] < - (1 << 8)) - overflow = TRUE; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = getch ()); - } - } - - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the string */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type = double_type_node; - char f_seen = 0; - char l_seen = 0; - int garbage_chars = 0, exceeds_double = 0; - REAL_VALUE_TYPE value; - jmp_buf handler; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((c == 'e') || (c == 'E')) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = getch (); - } - if (! isdigit (c)) - error ("floating constant exponent has no digits"); - while (isdigit (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - } - - *p = 0; - errno = 0; - - /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) - { - error ("floating constant out of range"); - value = dconst0; - } - else - { - set_float_handler (handler); - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result of - decimal-to-binary conversion. */ - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - type = float_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `float'"); - garbage_chars = -1; - break; - - case 'l': case 'L': - type = long_double_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - pedwarn ( - "floating point number exceeds range of `long double'"); - garbage_chars = -1; - break; - - default: - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `double'"); - } - set_float_handler (NULL); - } -#ifdef ERANGE - if (errno == ERANGE && !flag_traditional && pedantic) - { - char *p1 = token_buffer; - /* Check for "0.0" and variants; - SunOS 4 spuriously returns ERANGE for them. */ - while (*p1 == '0') p1++; - if (*p1 == '.') - { - p1++; - while (*p1 == '0') p1++; - } - if (*p1 == 'e' || *p1 == 'E') - { - /* with significand==0, ignore the exponent */ - p1++; - while (*p1 != 0) p1++; - } - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1)) - { - pedwarn ("floating point number exceeds range of `double'"); - exceeds_double = 1; - } - } -#endif - /* Note: garbage_chars is -1 if first char is *not* garbage. */ - while (isalnum (c)) - { - if (c == 'f' || c == 'F') - { - if (f_seen) - error ("two `f's in floating constant"); - f_seen = 1; - } - if (c == 'l' || c == 'L') - { - if (l_seen) - error ("two `l's in floating constant"); - l_seen = 1; - } - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - garbage_chars++; - } - - if (garbage_chars > 0) - error ("garbage at end of number"); - - /* Create a node with determined type and value. */ - yylval.ttype = build_real (type, value); - - put_back (c); - *p = 0; - } - else - { - tree type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else - { - if (isalnum (c)) - { - error ("garbage at end of number"); - while (isalnum (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - } - break; - } - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - - put_back (c); - - /* ??? This code assumes that everything but long long is 32-bits. - Probably this code needs to be replaced with code similar - to that in c-lex.c, but I don't want to do it. -- RK. */ - - if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4]) - && !spec_long_long) - warning ("integer constant out of range"); - - /* If it won't fit in a signed long long, make it unsigned. - We can't distinguish based on the tree node because - any integer constant fits any long long type. */ - if (shorts[7] >= (1<<8)) - spec_unsigned = 1; - - /* This is simplified by the fact that our constant - is always positive. */ - high = low = 0; - - for (i = 0; i < MAX_SHORTS / 2; i++) - { - high |= (HOST_WIDE_INT) shorts[i + MAX_SHORTS / 2] << (i * 8); - low |= (HOST_WIDE_INT) shorts[i] << (i * 8); - } - - yylval.ttype = build_int_2 (low, high); - -#if 0 - /* Find the first allowable type that the value fits in. */ - type = 0; - for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); - i++) - if (!(spec_long && !type_sequence[i].long_flag) - && !(spec_long_long && !type_sequence[i].long_long_flag) - && !(spec_unsigned && !type_sequence[i].unsigned_flag) - /* A hex or octal constant traditionally is unsigned. */ - && !(base != 10 && flag_traditional - && !type_sequence[i].unsigned_flag) - /* A decimal constant can't be unsigned int - unless explicitly specified. */ - && !(base == 10 && !spec_unsigned - && *type_sequence[i].node_var == unsigned_type_node)) - if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) - { - type = *type_sequence[i].node_var; - break; - } - if (flag_traditional && type == long_unsigned_type_node - && !spec_unsigned) - type = long_integer_type_node; - - if (type == 0) - { - type = long_long_integer_type_node; - warning ("integer constant out of range"); - } - - /* Warn about some cases where the type of a given constant - changes from traditional C to ANSI C. */ - if (warn_traditional) - { - tree other_type = 0; - - /* This computation is the same as the previous one - except that flag_traditional is used backwards. */ - for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); - i++) - if (!(spec_long && !type_sequence[i].long_flag) - && !(spec_long_long && !type_sequence[i].long_long_flag) - && !(spec_unsigned && !type_sequence[i].unsigned_flag) - /* A hex or octal constant traditionally is unsigned. */ - && !(base != 10 && !flag_traditional - && !type_sequence[i].unsigned_flag) - /* A decimal constant can't be unsigned int - unless explicitly specified. */ - && !(base == 10 && !spec_unsigned - && *type_sequence[i].node_var == unsigned_type_node)) - if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) - { - other_type = *type_sequence[i].node_var; - break; - } - if (!flag_traditional && type == long_unsigned_type_node - && !spec_unsigned) - type = long_integer_type_node; - - if (other_type != 0 && other_type != type) - { - if (flag_traditional) - warning ("type of integer constant would be different without -traditional"); - else - warning ("type of integer constant would be different with -traditional"); - } - } - -#else /* 1 */ - if (!spec_long && !spec_unsigned - && !(flag_traditional && base != 10) - && int_fits_type_p (yylval.ttype, integer_type_node)) - { -#if 0 - if (warn_traditional && base != 10) - warning ("small nondecimal constant becomes signed in ANSI C++"); -#endif - type = integer_type_node; - } - else if (!spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - { - /* Nondecimal constants try unsigned even in traditional C. */ - type = unsigned_type_node; - } - - else if (!spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - type = long_integer_type_node; - - else if (! spec_long_long - && int_fits_type_p (yylval.ttype, - long_unsigned_type_node)) - { -#if 0 - if (warn_traditional && !spec_unsigned) - warning ("large integer constant becomes unsigned in ANSI C++"); -#endif - if (flag_traditional && !spec_unsigned) - type = long_integer_type_node; - else - type = long_unsigned_type_node; - } - - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - type = long_long_integer_type_node; - - else if (int_fits_type_p (yylval.ttype, - long_long_unsigned_type_node)) - { -#if 0 - if (warn_traditional && !spec_unsigned) - warning ("large nondecimal constant is unsigned in ANSI C++"); -#endif - - if (flag_traditional && !spec_unsigned) - type = long_long_integer_type_node; - else - type = long_long_unsigned_type_node; - } - - else - { - type = long_long_integer_type_node; - warning ("integer constant out of range"); - } -#endif - - TREE_TYPE (yylval.ttype) = type; - *p = 0; - } - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; - - if (wide_flag) - { - width = WCHAR_TYPE_SIZE; -#ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; -#endif - } - else - max_chars = TYPE_PRECISION (integer_type_node) / width; - - while (1) - { - tryagain: - - c = getch (); - - if (c == '\'' || c == EOF) - break; - - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (isprint (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in character constant"); - lineno++; - } -#ifdef MAP_CHARACTER - else - c = MAP_CHARACTER (c); -#endif - - num_chars++; - if (num_chars > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[num_chars] = c; - - /* Merge character into result; ignore excess chars. */ - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } - } - - token_buffer[num_chars + 1] = '\''; - token_buffer[num_chars + 2] = 0; - - if (c != '\'') - error ("malformatted character constant"); - else if (num_chars == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (num_chars != 1 && ! flag_traditional) - warning ("multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 - >> (HOST_BITS_PER_INT - num_bits)), - -1); - if (num_chars<=1) - TREE_TYPE (yylval.ttype) = char_type_node; - else - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[1] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL, NULL, 0); - if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) - result = wc; - else - warning ("Ignoring invalid multibyte character"); - } -#endif - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - register char *p; - - c = getch (); - p = token_buffer + 1; - - while (c != '"' && c >= 0) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node))) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } - - if (p == token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - - skipnewline: - c = getch (); - if (c == EOF) { - error("Unterminated string"); - break; - } - } - *p = 0; - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - if (wide_flag) - { - /* If this is a L"..." wide-string, convert the multibyte string - to a wide character string. */ - char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); - int len; - -#ifdef MULTIBYTE_CHARS - len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); - if (len < 0 || len >= (p - token_buffer)) - { - warning ("Ignoring invalid multibyte string"); - len = 0; - } - bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); -#else - { - union { long l; char c[sizeof (long)]; } u; - int big_endian; - char *wp, *cp; - - /* Determine whether host is little or big endian. */ - u.l = 1; - big_endian = u.c[sizeof (long) - 1]; - wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0); - - bzero (widep, (p - token_buffer) * WCHAR_BYTES); - for (cp = token_buffer + 1; cp < p; cp++) - *wp = *cp, wp += WCHAR_BYTES; - len = p - token_buffer - 1; - } -#endif - yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - } - else - { - yylval.ttype = build_string (p - token_buffer, token_buffer + 1); - TREE_TYPE (yylval.ttype) = char_array_type_node; - } - - *p++ = '"'; - *p = 0; - - value = STRING; break; - } - - case '+': - case '-': - case '&': - case '|': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = getch (); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else if ((c == '-') && (c1 == '>')) - { - nextchar = skip_white_space (getch ()); - if (nextchar == '(') - { - int next_c = skip_white_space (getch ()); - if (next_c == ')') - { - nextchar = -1; - value = POINTSAT_LEFT_RIGHT; - goto done; - } - put_back (next_c); - } - if (nextchar == '*') - { - nextchar = -1; - value = POINTSAT_STAR; - } - else - value = POINTSAT; - goto done; - } - else if (c1 == '?' && (c == '<' || c == '>')) - { - token_buffer[3] = 0; - - c1 = getch (); - yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); - if (c1 == '=') - { - /* ?= expression. */ - token_buffer[2] = c1; - value = ASSIGN; - } - else - { - value = MIN_MAX; - nextchar = c1; - } - if (pedantic) - error ("use of `operator %s' is not standard C++", - token_buffer); - goto done; - } - - nextchar = c1; - token_buffer[1] = 0; - - value = c; - goto done; - } - - case ':': - c = getch (); - if (c == ':') - { - token_buffer[1] = ':'; - token_buffer[2] = '\0'; - value = SCOPE; - yylval.itype = 1; - } - else - { - nextchar = c; - value = ':'; - } - break; - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - case '(': - /* try, weakly, to handle casts to pointers to functions. */ - nextchar = skip_white_space (getch ()); - if (nextchar == '*') - { - int next_c = skip_white_space (getch ()); - if (next_c == ')') - { - nextchar = -1; - yylval.ttype = build1 (INDIRECT_REF, 0, 0); - value = PAREN_STAR_PAREN; - } - else - { - put_back (next_c); - value = c; - } - } - else if (nextchar == ')') - { - nextchar = -1; - yylval.ttype = NULL_TREE; - value = LEFT_RIGHT; - } - else value = c; - break; - - default: - value = c; - } - -done: -/* yylloc.last_line = lineno; */ -#ifdef GATHER_STATISTICS - token_count[value] += 1; -#endif - - return value; -} - -typedef enum -{ - d_kind, t_kind, s_kind, r_kind, e_kind, c_kind, - id_kind, op_id_kind, perm_list_kind, temp_list_kind, - vec_kind, x_kind, lang_decl, lang_type, all_kinds -} tree_node_kind; -extern int tree_node_counts[]; -extern int tree_node_sizes[]; -extern char *tree_node_kind_names[]; - -/* Place to save freed lang_decls which were allocated on the - permanent_obstack. @@ Not currently used. */ -tree free_lang_decl_chain; - -tree -build_lang_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - register tree t = build_decl (code, name, type); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl) / sizeof (int); - register int *pi; - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - /* Could be that saveable is permanent and current is not. */ - obstack = &permanent_obstack; - - if (free_lang_decl_chain && obstack == &permanent_obstack) - { - pi = (int *)free_lang_decl_chain; - free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain); - } - else - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); - - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - LANG_DECL_PERMANENT ((struct lang_decl *) pi) - = obstack == &permanent_obstack; - my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi) - == TREE_PERMANENT (t), 234); - DECL_MAIN_VARIANT (t) = t; - if (current_lang_name == lang_name_cplusplus) - { - DECL_LANGUAGE (t) = lang_cplusplus; -#ifndef NO_AUTO_OVERLOAD - if (code == FUNCTION_DECL && name != 0 - && ! (IDENTIFIER_LENGTH (name) == 4 - && IDENTIFIER_POINTER (name)[0] == 'm' - && strcmp (IDENTIFIER_POINTER (name), "main") == 0) - && ! (IDENTIFIER_LENGTH (name) > 10 - && IDENTIFIER_POINTER (name)[0] == '_' - && IDENTIFIER_POINTER (name)[1] == '_' - && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0)) - TREE_OVERLOADED (name) = 1; -#endif - } - else if (current_lang_name == lang_name_c) - DECL_LANGUAGE (t) = lang_c; - else my_friendly_abort (64); - -#if 0 /* not yet, should get fixed properly later */ - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } - -#endif -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_decl] += 1; - tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); -#endif - - return t; -} - -tree -build_lang_field_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = build_decl (code, name, type); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl_flags) / sizeof (int); - register int *pi; -#if 0 /* not yet, should get fixed properly later */ - - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } -#endif - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 235); - - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags)); - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - return t; -} - -void -copy_lang_decl (node) - tree node; -{ - int size; - int *pi; - - if (TREE_CODE (node) == FIELD_DECL) - size = sizeof (struct lang_decl_flags); - else - size = sizeof (struct lang_decl); - pi = (int *)obstack_alloc (&permanent_obstack, size); - bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size); - DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi; -} - -tree -make_lang_type (code) - enum tree_code code; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = make_node (code); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_type) / sizeof (int); - register int *pi; - - /* Set up some flags that give proper default behavior. */ - IS_AGGR_TYPE (t) = 1; - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 236); - - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type)); - while (i > 0) - pi[--i] = 0; - - TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi; - CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t); - CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown; - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, 0, 0, 0); - CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - /* Make sure this is laid out, for ease of use later. - In the presence of parse errors, the normal was of assuring - this might not ever get executed, so we lay it out *immediately*. */ - build_pointer_type (t); - -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof(struct lang_type); -#endif - - return t; -} - -void -copy_decl_lang_specific (decl) - tree decl; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register int *old = (int *)DECL_LANG_SPECIFIC (decl); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl) / sizeof (int); - register int *pi; - - if (! TREE_PERMANENT (decl)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 237); - - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); - while (i-- > 0) - pi[i] = old[i]; - - DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi; - -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_decl] += 1; - tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); -#endif -} - -void -dump_time_statistics () -{ - register tree prev = 0, decl, next; - int this_time = my_get_run_time (); - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) - += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double)header_time / (double)(this_time - body_time)); - fprintf (stderr, "\n******\n"); - - for (decl = filename_times; decl; decl = next) - { - next = IDENTIFIER_GLOBAL_VALUE (decl); - IDENTIFIER_GLOBAL_VALUE (decl) = prev; - prev = decl; - } - - for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) - print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl))); -} - -void -compiler_error (s, v, v2) - char *s; - HOST_WIDE_INT v, v2; /* @@also used as pointer */ -{ - char buf[1024]; - sprintf (buf, s, v, v2); - error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); -} - -void -compiler_error_with_decl (decl, s) - tree decl; - char *s; -{ - char *name; - count_error (0); - - report_error_function (0); - - if (TREE_CODE (decl) == PARM_DECL) - fprintf (stderr, "%s:%d: ", - DECL_SOURCE_FILE (DECL_CONTEXT (decl)), - DECL_SOURCE_LINE (DECL_CONTEXT (decl))); - else - fprintf (stderr, "%s:%d: ", - DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - - name = lang_printable_name (decl); - if (name) - fprintf (stderr, s, name); - else - fprintf (stderr, s, "((anonymous))"); - fprintf (stderr, " (compiler error)\n"); -} - -void -yyerror (string) - char *string; -{ - extern int end_of_file; - char buf[200]; - - strcpy (buf, string); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - strcat (buf, input_redirected () - ? " at end of saved text" - : " at end of input"); - else if (token_buffer[0] == 0) - strcat (buf, " at null character"); - else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); - else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); - else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); - else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); -} diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-lex.h b/gnu/usr.bin/gcc2/cc1plus/cp-lex.h deleted file mode 100644 index ec662cd2ef4..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-lex.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Define constants and variables for communication with cp-parse.y. - Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - and by Brendan Kehoe (brendan@cygnus.com). - -This file is part of GNU CC. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU CC General Public -License for full details. - -Everyone is granted permission to copy, modify and redistribute -GNU CC, but only under the conditions described in the -GNU CC General Public License. A copy of this license is -supposed to have been given to you along with GNU CC so you -can know your rights and responsibilities. It should be in a -file named COPYING. Among other things, the copyright notice -and this notice must be preserved on all copies. - - $Id: cp-lex.h,v 1.1.1.1 1995/10/18 08:39:32 deraadt Exp $ -*/ - -enum rid -{ - RID_UNUSED, - RID_INT, - RID_CHAR, - RID_WCHAR, - RID_FLOAT, - RID_DOUBLE, - RID_VOID, - - /* C++ extension */ - RID_CLASS, - RID_RECORD, - RID_UNION, - RID_ENUM, - RID_LONGLONG, - - /* This is where grokdeclarator starts its search when setting the specbits. - The first seven are in the order of most frequently used, as found - building libg++. */ - - RID_EXTERN, - RID_CONST, - RID_LONG, - RID_TYPEDEF, - RID_UNSIGNED, - RID_SHORT, - RID_INLINE, - - RID_STATIC, - - RID_REGISTER, - RID_VOLATILE, - RID_FRIEND, - RID_VIRTUAL, - RID_PUBLIC, - RID_PRIVATE, - RID_PROTECTED, - RID_SIGNED, - RID_EXCEPTION, - RID_RAISES, - RID_AUTO, - - /* Note this is 31, and is unusable in shifts where ints are 32 bits. - As soon as a new rid has to be added to this enum, you have to - stop and come up with a better way to do all of this than by - doing `specbits & (1 << (int) RID_FOO)', since you'll end up - with an integer overflow. */ - RID_UNUSED1, - - RID_MAX -}; - -#define NORID RID_UNUSED - -#define RID_FIRST_MODIFIER RID_EXTERN - -/* The integral type that can represent all values of RIDBIT. */ -typedef unsigned long RID_BIT_TYPE; - -/* A bit that represents the given RID_... value. */ -#define RIDBIT(N) ((RID_BIT_TYPE) 1 << (int) (N)) - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -extern tree ridpointers[(int) RID_MAX]; - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -extern tree lastiddecl; - -extern char *token_buffer; /* Pointer to token buffer. */ - -/* Back-door communication channel to the lexer. */ -extern int looking_for_typename; - -extern tree make_pointer_declarator (), make_reference_declarator (); -extern void reinit_parse_for_function (); -extern void reinit_parse_for_method (); -extern int yylex (); diff --git a/gnu/usr.bin/gcc2/cc1plus/cp-method.c b/gnu/usr.bin/gcc2/cc1plus/cp-method.c deleted file mode 100644 index ead707afa1f..00000000000 --- a/gnu/usr.bin/gcc2/cc1plus/cp-method.c +++ /dev/null @@ -1,2682 +0,0 @@ -/* Handle the hair of processing (but not expanding) inline functions. - Also manage function and variable name overloading. - Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) - - 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: cp-method.c,v 1.1.1.1 1995/10/18 08:39:32 deraadt Exp $"; -#endif /* not lint */ - -#ifndef PARM_CAN_BE_ARRAY_TYPE -#define PARM_CAN_BE_ARRAY_TYPE 1 -#endif - -/* Handle method declarations. */ -#include -#include "config.h" -#include "tree.h" -#include "cp-tree.h" -#include "obstack.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* TREE_LIST of the current inline functions that need to be - processed. */ -struct pending_inline *pending_inlines; - -/* Obstack where we build text strings for overloading, etc. */ -static struct obstack scratch_obstack; -static char *scratch_firstobj; - -# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) -# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) -# define OB_PUTC2(C1,C2) \ - (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) -# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) -# define OB_PUTID(ID) \ - (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ - IDENTIFIER_LENGTH (ID))) -# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) -# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) - -/* Counter to help build parameter names in case they were omitted. */ -static int dummy_name; -static int in_parmlist; - -/* This points to a safe place to resume processing in case an expression - generates an error while we're trying to format it. */ -static int scratch_error_offset; - -static void dump_type (), dump_decl (); -static void dump_init (), dump_unary_op (), dump_binary_op (); - -#ifdef NO_AUTO_OVERLOAD -int is_overloaded (); -#endif - -void -init_method () -{ - gcc_obstack_init (&scratch_obstack); - scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); -} - -tree -make_anon_parm_name () -{ - char buf[32]; - - sprintf (buf, ANON_PARMNAME_FORMAT, dummy_name++); - return get_identifier (buf); -} - -void -clear_anon_parm_name () -{ - /* recycle these names. */ - dummy_name = 0; -} - -static void -dump_readonly_or_volatile (t) - tree t; -{ - if (TYPE_READONLY (t)) - OB_PUTS ("const "); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile "); -} - -static void -dump_aggr_type (t) - tree t; -{ - tree name; - char *aggr_string; - char *context_string = 0; - - if (TYPE_READONLY (t)) - OB_PUTS ("const "); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile "); - if (TREE_CODE (t) == ENUMERAL_TYPE) - aggr_string = "enum"; - else if (TREE_CODE (t) == UNION_TYPE) - aggr_string = "union"; - else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) - aggr_string = "class"; - else - aggr_string = "struct"; - - name = TYPE_NAME (t); - - if (TREE_CODE (name) == TYPE_DECL) - { -#if 0 /* not yet, should get fixed properly later */ - if (DECL_CONTEXT (name)) - context_string = TYPE_NAME_STRING (DECL_CONTEXT (name)); -#else - if (DECL_LANG_SPECIFIC (name) && DECL_CLASS_CONTEXT (name)) - context_string = TYPE_NAME_STRING (DECL_CLASS_CONTEXT (name)); -#endif - name = DECL_NAME (name); - } - - obstack_grow (&scratch_obstack, aggr_string, strlen (aggr_string)); - OB_PUTC (' '); - if (context_string) - { - obstack_grow (&scratch_obstack, context_string, strlen (context_string)); - OB_PUTC2 (':', ':'); - } - OB_PUTID (name); -} - -/* This must be large enough to hold any anonymous parm name. */ -static char anon_buffer[sizeof (ANON_PARMNAME_FORMAT) + 20]; -/* This must be large enough to hold any printed integer or floatingpoint value. */ -static char digit_buffer[128]; - -static void -dump_type_prefix (t, p) - tree t; - int *p; -{ - int old_p = 0; - - if (t == NULL_TREE) - return; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); - OB_PUTCP (anon_buffer); - break; - - case UNKNOWN_TYPE: - OB_PUTS (""); - return; - - case TREE_LIST: - dump_type (TREE_VALUE (t), &old_p); - if (TREE_CHAIN (t)) - { - if (TREE_CHAIN (t) != void_list_node) - { - OB_PUTC (','); - dump_type (TREE_CHAIN (t), &old_p); - } - } - else OB_PUTS ("..."); - return; - - case POINTER_TYPE: - *p += 1; - dump_type_prefix (TREE_TYPE (t), p); - while (*p) - { - OB_PUTC ('*'); - *p -= 1; - } - if (TYPE_READONLY (t)) - OB_PUTS ("const "); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile "); - return; - - case OFFSET_TYPE: - { - tree type = TREE_TYPE (t); - if (TREE_CODE (type) == FUNCTION_TYPE) - { - type = TREE_TYPE (type); - if (in_parmlist) - OB_PUTS ("auto "); - } - - dump_type_prefix (type, &old_p); - - OB_PUTC ('('); - dump_type (TYPE_OFFSET_BASETYPE (t), &old_p); - OB_PUTC2 (':', ':'); - while (*p) - { - OB_PUTC ('*'); - *p -= 1; - } - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - return; - } - - case METHOD_TYPE: - { - tree type = TREE_TYPE (t); - if (in_parmlist) - OB_PUTS ("auto "); - - dump_type_prefix (type, &old_p); - - OB_PUTC ('('); - dump_type (TYPE_METHOD_BASETYPE (t), &old_p); - OB_PUTC2 (':', ':'); - while (*p) - { - OB_PUTC ('*'); - *p -= 1; - } - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - return; - } - - case REFERENCE_TYPE: - dump_type_prefix (TREE_TYPE (t), p); - OB_PUTC ('&'); - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - return; - - case ARRAY_TYPE: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - dump_type_prefix (TREE_TYPE (t), p); - return; - - case FUNCTION_TYPE: - if (in_parmlist) - OB_PUTS ("auto "); - dump_type_prefix (TREE_TYPE (t), &old_p); - OB_PUTC ('('); - while (*p) - { - OB_PUTC ('*'); - *p -= 1; - } - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - return; - - case IDENTIFIER_NODE: - OB_PUTID (t); - OB_PUTC (' '); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - dump_aggr_type (t); - break; - - case TYPE_DECL: - if (TYPE_READONLY (t)) - OB_PUTS ("const "); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile "); - OB_PUTID (DECL_NAME (t)); - OB_PUTC (' '); - break; - - case INTEGER_TYPE: -#if 0 - /* Normally, `unsigned' is part of the deal. Not so if it comes - with `const' or `volatile'. */ - if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t)) - && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) - OB_PUTS ("unsigned "); -#endif - /* fall through. */ - case REAL_TYPE: - case VOID_TYPE: - if (TYPE_READONLY (t)) - OB_PUTS ("const "); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile "); - OB_PUTID (TYPE_IDENTIFIER (t)); - OB_PUTC (' '); - break; - - default: - my_friendly_abort (65); - } -} - -static void -dump_type_suffix (t, p) - tree t; - int *p; -{ - int old_p = 0; - - if (t == NULL_TREE) - return; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); - OB_PUTCP (anon_buffer); - break; - - case UNKNOWN_TYPE: - return; - - case POINTER_TYPE: - dump_type_suffix (TREE_TYPE (t), p); - return; - - case OFFSET_TYPE: - { - tree type = TREE_TYPE (t); - - OB_PUTC (')'); - if (TREE_CODE (type) == FUNCTION_TYPE) - { -#if 0 - tree next_arg = TREE_CHAIN (TYPE_ARG_TYPES (type)); - OB_PUTC ('('); - if (next_arg) - { - if (next_arg != void_list_node) - { - in_parmlist++; - dump_type (next_arg, &old_p); - in_parmlist--; - } - } - else OB_PUTS ("..."); - OB_PUTC (')'); - dump_type_suffix (TREE_TYPE (type), p); -#else - my_friendly_abort (66); -#endif - } - return; - } - - case METHOD_TYPE: - { - tree next_arg; - OB_PUTC (')'); - next_arg = TREE_CHAIN (TYPE_ARG_TYPES (t)); - OB_PUTC ('('); - if (next_arg) - { - if (next_arg != void_list_node) - { - in_parmlist++; - dump_type (next_arg, &old_p); - in_parmlist--; - } - } - else OB_PUTS ("..."); - OB_PUTC (')'); - dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); - dump_type_suffix (TREE_TYPE (t), p); - return; - } - - case REFERENCE_TYPE: - dump_type_suffix (TREE_TYPE (t), p); - return; - - case ARRAY_TYPE: - dump_type_suffix (TREE_TYPE (t), p); - OB_PUTC2 ('[', ']'); - return; - - case FUNCTION_TYPE: - OB_PUTC2 (')', '('); - if (TYPE_ARG_TYPES (t) && TYPE_ARG_TYPES (t) != void_list_node) - { - in_parmlist++; - dump_type (TYPE_ARG_TYPES (t), &old_p); - in_parmlist--; - } - OB_PUTC (')'); - dump_type_suffix (TREE_TYPE (t), p); - return; - - case IDENTIFIER_NODE: - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - case TYPE_DECL: - case INTEGER_TYPE: - case REAL_TYPE: - case VOID_TYPE: - return; - - default: - my_friendly_abort (67); - } -} - -static void -dump_type (t, p) - tree t; - int *p; -{ - int old_p = 0; - - if (t == NULL_TREE) - return; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); - OB_PUTCP (anon_buffer); - break; - - case UNKNOWN_TYPE: - OB_PUTS (""); - return; - - case TREE_LIST: - dump_type (TREE_VALUE (t), &old_p); - if (TREE_CHAIN (t)) - { - if (TREE_CHAIN (t) != void_list_node) - { - OB_PUTC (','); - dump_type (TREE_CHAIN (t), &old_p); - } - } - else OB_PUTS ("..."); - return; - - case POINTER_TYPE: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - *p += 1; - dump_type (TREE_TYPE (t), p); - while (*p) - { - OB_PUTC ('*'); - *p -= 1; - } - return; - - case REFERENCE_TYPE: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - dump_type (TREE_TYPE (t), p); - OB_PUTC ('&'); - return; - - case ARRAY_TYPE: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - dump_type (TREE_TYPE (t), p); - OB_PUTC2 ('[', ']'); - return; - - case OFFSET_TYPE: - case METHOD_TYPE: - case FUNCTION_TYPE: - dump_type_prefix (t, p); - dump_type_suffix (t, p); - return; - - case IDENTIFIER_NODE: - OB_PUTID (t); - OB_PUTC (' '); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - dump_aggr_type (t); - break; - - case TYPE_DECL: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - OB_PUTID (DECL_NAME (t)); - OB_PUTC (' '); - break; - - case INTEGER_TYPE: - /* Normally, `unsigned' is part of the deal. Not so if it comes - with `const' or `volatile'. */ - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); -#if 0 - if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t)) - && (TYPE_READONLY (t) | TYPE_VOLATILE (t))) - OB_PUTS ("unsigned "); -#endif - OB_PUTID (TYPE_IDENTIFIER (t)); - OB_PUTC (' '); - break; - - case REAL_TYPE: - case VOID_TYPE: - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t); - OB_PUTID (TYPE_IDENTIFIER (t)); - OB_PUTC (' '); - break; - - case TEMPLATE_TYPE_PARM: - OB_PUTS ("