118334Speter/* Declarations for interface to insn recognizer and insn-output.c.
2169689Skan   Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
390075Sobrien   Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2252284Sobrien/* Random number that should be large enough for all purposes.  */
2352284Sobrien#define MAX_RECOG_ALTERNATIVES 30
2418334Speter
2552284Sobrien/* Types of operands.  */
2652284Sobrienenum op_type {
2752284Sobrien  OP_IN,
2852284Sobrien  OP_OUT,
2952284Sobrien  OP_INOUT
3052284Sobrien};
3152284Sobrien
3252284Sobrienstruct operand_alternative
3352284Sobrien{
3452284Sobrien  /* Pointer to the beginning of the constraint string for this alternative,
3552284Sobrien     for easier access by alternative number.  */
3652284Sobrien  const char *constraint;
3752284Sobrien
3852284Sobrien  /* The register class valid for this alternative (possibly NO_REGS).  */
39169689Skan  enum reg_class cl;
4052284Sobrien
4152284Sobrien  /* "Badness" of this alternative, computed from number of '?' and '!'
4252284Sobrien     characters in the constraint string.  */
4352284Sobrien  unsigned int reject;
4452284Sobrien
4552284Sobrien  /* -1 if no matching constraint was found, or an operand number.  */
4652284Sobrien  int matches;
4752284Sobrien  /* The same information, but reversed: -1 if this operand is not
4852284Sobrien     matched by any other, or the operand number of the operand that
4952284Sobrien     matches this one.  */
5052284Sobrien  int matched;
5152284Sobrien
5252284Sobrien  /* Nonzero if '&' was found in the constraint string.  */
5352284Sobrien  unsigned int earlyclobber:1;
5452284Sobrien  /* Nonzero if 'm' was found in the constraint string.  */
55132718Skan  unsigned int memory_ok:1;
5652284Sobrien  /* Nonzero if 'o' was found in the constraint string.  */
57132718Skan  unsigned int offmem_ok:1;
5852284Sobrien  /* Nonzero if 'V' was found in the constraint string.  */
5952284Sobrien  unsigned int nonoffmem_ok:1;
6052284Sobrien  /* Nonzero if '<' was found in the constraint string.  */
6152284Sobrien  unsigned int decmem_ok:1;
6252284Sobrien  /* Nonzero if '>' was found in the constraint string.  */
6352284Sobrien  unsigned int incmem_ok:1;
6490075Sobrien  /* Nonzero if 'p' was found in the constraint string.  */
6590075Sobrien  unsigned int is_address:1;
6652284Sobrien  /* Nonzero if 'X' was found in the constraint string, or if the constraint
6752284Sobrien     string for this alternative was empty.  */
6852284Sobrien  unsigned int anything_ok:1;
6952284Sobrien};
7052284Sobrien
7152284Sobrien
72132718Skanextern void init_recog (void);
73132718Skanextern void init_recog_no_volatile (void);
74132718Skanextern int check_asm_operands (rtx);
75132718Skanextern int asm_operand_ok (rtx, const char *);
76132718Skanextern int validate_change (rtx, rtx *, rtx, int);
77132718Skanextern int insn_invalid_p (rtx);
78169689Skanextern int verify_changes (int);
79169689Skanextern void confirm_change_group (void);
80132718Skanextern int apply_change_group (void);
81132718Skanextern int num_validated_changes (void);
82132718Skanextern void cancel_changes (int);
83132718Skanextern int constrain_operands (int);
84132718Skanextern int constrain_operands_cached (int);
85132718Skanextern int memory_address_p (enum machine_mode, rtx);
86132718Skanextern int strict_memory_address_p (enum machine_mode, rtx);
87132718Skanextern int validate_replace_rtx (rtx, rtx, rtx);
88132718Skanextern void validate_replace_rtx_group (rtx, rtx, rtx);
89132718Skanextern void validate_replace_src_group (rtx, rtx, rtx);
90169689Skanextern bool validate_simplify_insn (rtx insn);
91132718Skanextern int num_changes_pending (void);
9252284Sobrien#ifdef HAVE_cc0
93132718Skanextern int next_insn_tests_no_inequality (rtx);
9452284Sobrien#endif
95132718Skanextern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode);
96132718Skanextern rtx *find_single_use (rtx, rtx, rtx *);
9718334Speter
98132718Skanextern int offsettable_memref_p (rtx);
99132718Skanextern int offsettable_nonstrict_memref_p (rtx);
100132718Skanextern int offsettable_address_p (int, enum machine_mode, rtx);
101132718Skanextern int mode_dependent_address_p (rtx);
10218334Speter
103132718Skanextern int recog (rtx, rtx, int *);
104169689Skan#ifndef GENERATOR_FILE
105169689Skanstatic inline int recog_memoized (rtx insn);
106169689Skan#endif
107132718Skanextern void add_clobbers (rtx, int);
108132718Skanextern int added_clobbers_hard_reg_p (int);
109132718Skanextern void insn_extract (rtx);
110132718Skanextern void extract_insn (rtx);
111132718Skanextern void extract_constrain_insn_cached (rtx);
112132718Skanextern void extract_insn_cached (rtx);
113132718Skanextern void preprocess_constraints (void);
114132718Skanextern rtx peep2_next_insn (int);
115132718Skanextern int peep2_regno_dead_p (int, int);
116132718Skanextern int peep2_reg_dead_p (int, rtx);
11790075Sobrien#ifdef CLEAR_HARD_REG_SET
118132718Skanextern rtx peep2_find_free_register (int, int, const char *,
119132718Skan				     enum machine_mode, HARD_REG_SET *);
12090075Sobrien#endif
121132718Skanextern rtx peephole2_insns (rtx, rtx, int *);
12218334Speter
123132718Skanextern int store_data_bypass_p (rtx, rtx);
124132718Skanextern int if_test_bypass_p (rtx, rtx);
125117395Skan
126169689Skan#ifndef GENERATOR_FILE
127169689Skan/* Try recognizing the instruction INSN,
128169689Skan   and return the code number that results.
129169689Skan   Remember the code so that repeated calls do not
130169689Skan   need to spend the time for actual rerecognition.
131169689Skan
132169689Skan   This function is the normal interface to instruction recognition.
133169689Skan   The automatically-generated function `recog' is normally called
134169689Skan   through this one.  */
135169689Skan
136169689Skanstatic inline int
137169689Skanrecog_memoized (rtx insn)
138169689Skan{
139169689Skan  if (INSN_CODE (insn) < 0)
140169689Skan    INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
141169689Skan  return INSN_CODE (insn);
142169689Skan}
143169689Skan#endif
144169689Skan
14518334Speter/* Nonzero means volatile operands are recognized.  */
14618334Speterextern int volatile_ok;
14718334Speter
14852284Sobrien/* Set by constrain_operands to the number of the alternative that
14952284Sobrien   matched.  */
15052284Sobrienextern int which_alternative;
15152284Sobrien
15218334Speter/* The following vectors hold the results from insn_extract.  */
15318334Speter
15490075Sobrienstruct recog_data
15590075Sobrien{
15690075Sobrien  /* It is very tempting to make the 5 operand related arrays into a
15790075Sobrien     structure and index on that.  However, to be source compatible
15890075Sobrien     with all of the existing md file insn constraints and output
15990075Sobrien     templates, we need `operand' as a flat array.  Without that
16090075Sobrien     member, making an array for the rest seems pointless.  */
16118334Speter
16290075Sobrien  /* Gives value of operand N.  */
16390075Sobrien  rtx operand[MAX_RECOG_OPERANDS];
16418334Speter
16590075Sobrien  /* Gives location where operand N was found.  */
16690075Sobrien  rtx *operand_loc[MAX_RECOG_OPERANDS];
16718334Speter
16890075Sobrien  /* Gives the constraint string for operand N.  */
16990075Sobrien  const char *constraints[MAX_RECOG_OPERANDS];
17018334Speter
17190075Sobrien  /* Gives the mode of operand N.  */
17290075Sobrien  enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
17352284Sobrien
17490075Sobrien  /* Gives the type (in, out, inout) for operand N.  */
17590075Sobrien  enum op_type operand_type[MAX_RECOG_OPERANDS];
17652284Sobrien
17790075Sobrien  /* Gives location where the Nth duplicate-appearance of an operand
17890075Sobrien     was found.  This is something that matched MATCH_DUP.  */
17990075Sobrien  rtx *dup_loc[MAX_DUP_OPERANDS];
18052284Sobrien
18190075Sobrien  /* Gives the operand number that was duplicated in the Nth
18290075Sobrien     duplicate-appearance of an operand.  */
18390075Sobrien  char dup_num[MAX_DUP_OPERANDS];
18452284Sobrien
18590075Sobrien  /* ??? Note that these are `char' instead of `unsigned char' to (try to)
186132718Skan     avoid certain lossage from K&R C, wherein `unsigned char' default
18790075Sobrien     promotes to `unsigned int' instead of `int' as in ISO C.  As of 1999,
18890075Sobrien     the most common places to bootstrap from K&R C are SunOS and HPUX,
18990075Sobrien     both of which have signed characters by default.  The only other
19090075Sobrien     supported natives that have both K&R C and unsigned characters are
19190075Sobrien     ROMP and Irix 3, and neither have been seen for a while, but do
19290075Sobrien     continue to consider unsignedness when performing arithmetic inside
19390075Sobrien     a comparison.  */
19452284Sobrien
19590075Sobrien  /* The number of operands of the insn.  */
19690075Sobrien  char n_operands;
19752284Sobrien
19890075Sobrien  /* The number of MATCH_DUPs in the insn.  */
19990075Sobrien  char n_dups;
20052284Sobrien
20190075Sobrien  /* The number of alternatives in the constraints for the insn.  */
20290075Sobrien  char n_alternatives;
20352284Sobrien
20490075Sobrien  /* In case we are caching, hold insn data was generated for.  */
20590075Sobrien  rtx insn;
20690075Sobrien};
20790075Sobrien
20890075Sobrienextern struct recog_data recog_data;
20990075Sobrien
21052284Sobrien/* Contains a vector of operand_alternative structures for every operand.
21152284Sobrien   Set up by preprocess_constraints.  */
21252284Sobrienextern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
21352284Sobrien
21490075Sobrien/* A table defined in insn-output.c that give information about
21518334Speter   each insn-code value.  */
21618334Speter
217132718Skantypedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
218132718Skantypedef const char * (*insn_output_fn) (rtx *, rtx);
219132718Skantypedef rtx (*insn_gen_fn) (rtx, ...);
22018334Speter
22190075Sobrienstruct insn_operand_data
22290075Sobrien{
22390075Sobrien  const insn_operand_predicate_fn predicate;
22418334Speter
22590075Sobrien  const char *const constraint;
22618334Speter
227132718Skan  ENUM_BITFIELD(machine_mode) const mode : 16;
22818334Speter
22990075Sobrien  const char strict_low;
23018334Speter
23190075Sobrien  const char eliminable;
23290075Sobrien};
23318334Speter
23490075Sobrien/* Legal values for insn_data.output_format.  Indicate what type of data
23590075Sobrien   is stored in insn_data.output.  */
23690075Sobrien#define INSN_OUTPUT_FORMAT_NONE		0	/* abort */
23790075Sobrien#define INSN_OUTPUT_FORMAT_SINGLE	1	/* const char * */
23890075Sobrien#define INSN_OUTPUT_FORMAT_MULTI	2	/* const char * const * */
23990075Sobrien#define INSN_OUTPUT_FORMAT_FUNCTION	3	/* const char * (*)(...) */
24018334Speter
24190075Sobrienstruct insn_data
24290075Sobrien{
24390075Sobrien  const char *const name;
244132718Skan#if HAVE_DESIGNATED_INITIALIZERS
245132718Skan  union {
246132718Skan    const char *single;
247132718Skan    const char *const *multi;
248132718Skan    insn_output_fn function;
249132718Skan  } output;
250132718Skan#else
251132718Skan  struct {
252132718Skan    const char *single;
253132718Skan    const char *const *multi;
254132718Skan    insn_output_fn function;
255132718Skan  } output;
256132718Skan#endif
25790075Sobrien  const insn_gen_fn genfun;
25890075Sobrien  const struct insn_operand_data *const operand;
25918334Speter
26090075Sobrien  const char n_operands;
26190075Sobrien  const char n_dups;
26290075Sobrien  const char n_alternatives;
26390075Sobrien  const char output_format;
26490075Sobrien};
26518334Speter
26690075Sobrienextern const struct insn_data insn_data[];
267169689Skanextern int peep2_current_count;
268