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