Home | History | Annotate | Line # | Download | only in gcc
final.cc revision 1.1
      1  1.1  mrg /* Convert RTL to assembler code and output it, for GNU compiler.
      2  1.1  mrg    Copyright (C) 1987-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg the terms of the GNU General Public License as published by the Free
      8  1.1  mrg Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg /* This is the final pass of the compiler.
     21  1.1  mrg    It looks at the rtl code for a function and outputs assembler code.
     22  1.1  mrg 
     23  1.1  mrg    Call `final_start_function' to output the assembler code for function entry,
     24  1.1  mrg    `final' to output assembler code for some RTL code,
     25  1.1  mrg    `final_end_function' to output assembler code for function exit.
     26  1.1  mrg    If a function is compiled in several pieces, each piece is
     27  1.1  mrg    output separately with `final'.
     28  1.1  mrg 
     29  1.1  mrg    Some optimizations are also done at this level.
     30  1.1  mrg    Move instructions that were made unnecessary by good register allocation
     31  1.1  mrg    are detected and omitted from the output.  (Though most of these
     32  1.1  mrg    are removed by the last jump pass.)
     33  1.1  mrg 
     34  1.1  mrg    Instructions to set the condition codes are omitted when it can be
     35  1.1  mrg    seen that the condition codes already had the desired values.
     36  1.1  mrg 
     37  1.1  mrg    In some cases it is sufficient if the inherited condition codes
     38  1.1  mrg    have related values, but this may require the following insn
     39  1.1  mrg    (the one that tests the condition codes) to be modified.
     40  1.1  mrg 
     41  1.1  mrg    The code for the function prologue and epilogue are generated
     42  1.1  mrg    directly in assembler by the target functions function_prologue and
     43  1.1  mrg    function_epilogue.  Those instructions never exist as rtl.  */
     44  1.1  mrg 
     45  1.1  mrg #include "config.h"
     46  1.1  mrg #define INCLUDE_ALGORITHM /* reverse */
     47  1.1  mrg #include "system.h"
     48  1.1  mrg #include "coretypes.h"
     49  1.1  mrg #include "backend.h"
     50  1.1  mrg #include "target.h"
     51  1.1  mrg #include "rtl.h"
     52  1.1  mrg #include "tree.h"
     53  1.1  mrg #include "cfghooks.h"
     54  1.1  mrg #include "df.h"
     55  1.1  mrg #include "memmodel.h"
     56  1.1  mrg #include "tm_p.h"
     57  1.1  mrg #include "insn-config.h"
     58  1.1  mrg #include "regs.h"
     59  1.1  mrg #include "emit-rtl.h"
     60  1.1  mrg #include "recog.h"
     61  1.1  mrg #include "cgraph.h"
     62  1.1  mrg #include "tree-pretty-print.h" /* for dump_function_header */
     63  1.1  mrg #include "varasm.h"
     64  1.1  mrg #include "insn-attr.h"
     65  1.1  mrg #include "conditions.h"
     66  1.1  mrg #include "flags.h"
     67  1.1  mrg #include "output.h"
     68  1.1  mrg #include "except.h"
     69  1.1  mrg #include "rtl-error.h"
     70  1.1  mrg #include "toplev.h" /* exact_log2, floor_log2 */
     71  1.1  mrg #include "reload.h"
     72  1.1  mrg #include "intl.h"
     73  1.1  mrg #include "cfgrtl.h"
     74  1.1  mrg #include "debug.h"
     75  1.1  mrg #include "tree-pass.h"
     76  1.1  mrg #include "tree-ssa.h"
     77  1.1  mrg #include "cfgloop.h"
     78  1.1  mrg #include "stringpool.h"
     79  1.1  mrg #include "attribs.h"
     80  1.1  mrg #include "asan.h"
     81  1.1  mrg #include "rtl-iter.h"
     82  1.1  mrg #include "print-rtl.h"
     83  1.1  mrg #include "function-abi.h"
     84  1.1  mrg #include "common/common-target.h"
     85  1.1  mrg 
     86  1.1  mrg #ifdef XCOFF_DEBUGGING_INFO
     87  1.1  mrg #include "xcoffout.h"		/* Needed for external data declarations.  */
     88  1.1  mrg #endif
     89  1.1  mrg 
     90  1.1  mrg #include "dwarf2out.h"
     91  1.1  mrg 
     92  1.1  mrg #ifdef DBX_DEBUGGING_INFO
     93  1.1  mrg #include "dbxout.h"
     94  1.1  mrg #endif
     95  1.1  mrg 
     96  1.1  mrg /* Most ports don't need to define CC_STATUS_INIT.
     97  1.1  mrg    So define a null default for it to save conditionalization later.  */
     98  1.1  mrg #ifndef CC_STATUS_INIT
     99  1.1  mrg #define CC_STATUS_INIT
    100  1.1  mrg #endif
    101  1.1  mrg 
    102  1.1  mrg /* Is the given character a logical line separator for the assembler?  */
    103  1.1  mrg #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
    104  1.1  mrg #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
    105  1.1  mrg #endif
    106  1.1  mrg 
    107  1.1  mrg #ifndef JUMP_TABLES_IN_TEXT_SECTION
    108  1.1  mrg #define JUMP_TABLES_IN_TEXT_SECTION 0
    109  1.1  mrg #endif
    110  1.1  mrg 
    111  1.1  mrg /* Bitflags used by final_scan_insn.  */
    112  1.1  mrg #define SEEN_NOTE	1
    113  1.1  mrg #define SEEN_EMITTED	2
    114  1.1  mrg #define SEEN_NEXT_VIEW	4
    115  1.1  mrg 
    116  1.1  mrg /* Last insn processed by final_scan_insn.  */
    117  1.1  mrg static rtx_insn *debug_insn;
    118  1.1  mrg rtx_insn *current_output_insn;
    119  1.1  mrg 
    120  1.1  mrg /* Line number of last NOTE.  */
    121  1.1  mrg static int last_linenum;
    122  1.1  mrg 
    123  1.1  mrg /* Column number of last NOTE.  */
    124  1.1  mrg static int last_columnnum;
    125  1.1  mrg 
    126  1.1  mrg /* Discriminator written to assembly.  */
    127  1.1  mrg static int last_discriminator;
    128  1.1  mrg 
    129  1.1  mrg /* Discriminator to be written to assembly for current instruction.
    130  1.1  mrg    Note: actual usage depends on loc_discriminator_kind setting.  */
    131  1.1  mrg static int discriminator;
    132  1.1  mrg static inline int compute_discriminator (location_t loc);
    133  1.1  mrg 
    134  1.1  mrg /* Discriminator identifying current basic block among others sharing
    135  1.1  mrg    the same locus.  */
    136  1.1  mrg static int bb_discriminator;
    137  1.1  mrg 
    138  1.1  mrg /* Basic block discriminator for previous instruction.  */
    139  1.1  mrg static int last_bb_discriminator;
    140  1.1  mrg 
    141  1.1  mrg /* Highest line number in current block.  */
    142  1.1  mrg static int high_block_linenum;
    143  1.1  mrg 
    144  1.1  mrg /* Likewise for function.  */
    145  1.1  mrg static int high_function_linenum;
    146  1.1  mrg 
    147  1.1  mrg /* Filename of last NOTE.  */
    148  1.1  mrg static const char *last_filename;
    149  1.1  mrg 
    150  1.1  mrg /* Override filename, line and column number.  */
    151  1.1  mrg static const char *override_filename;
    152  1.1  mrg static int override_linenum;
    153  1.1  mrg static int override_columnnum;
    154  1.1  mrg static int override_discriminator;
    155  1.1  mrg 
    156  1.1  mrg /* Whether to force emission of a line note before the next insn.  */
    157  1.1  mrg static bool force_source_line = false;
    158  1.1  mrg 
    159  1.1  mrg extern const int length_unit_log; /* This is defined in insn-attrtab.cc.  */
    160  1.1  mrg 
    161  1.1  mrg /* Nonzero while outputting an `asm' with operands.
    162  1.1  mrg    This means that inconsistencies are the user's fault, so don't die.
    163  1.1  mrg    The precise value is the insn being output, to pass to error_for_asm.  */
    164  1.1  mrg const rtx_insn *this_is_asm_operands;
    165  1.1  mrg 
    166  1.1  mrg /* Number of operands of this insn, for an `asm' with operands.  */
    167  1.1  mrg static unsigned int insn_noperands;
    168  1.1  mrg 
    169  1.1  mrg /* Compare optimization flag.  */
    170  1.1  mrg 
    171  1.1  mrg static rtx last_ignored_compare = 0;
    172  1.1  mrg 
    173  1.1  mrg /* Assign a unique number to each insn that is output.
    174  1.1  mrg    This can be used to generate unique local labels.  */
    175  1.1  mrg 
    176  1.1  mrg static int insn_counter = 0;
    177  1.1  mrg 
    178  1.1  mrg /* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen.  */
    179  1.1  mrg 
    180  1.1  mrg static int block_depth;
    181  1.1  mrg 
    182  1.1  mrg /* Nonzero if have enabled APP processing of our assembler output.  */
    183  1.1  mrg 
    184  1.1  mrg static int app_on;
    185  1.1  mrg 
    186  1.1  mrg /* If we are outputting an insn sequence, this contains the sequence rtx.
    187  1.1  mrg    Zero otherwise.  */
    188  1.1  mrg 
    189  1.1  mrg rtx_sequence *final_sequence;
    190  1.1  mrg 
    191  1.1  mrg #ifdef ASSEMBLER_DIALECT
    192  1.1  mrg 
    193  1.1  mrg /* Number of the assembler dialect to use, starting at 0.  */
    194  1.1  mrg static int dialect_number;
    195  1.1  mrg #endif
    196  1.1  mrg 
    197  1.1  mrg /* Nonnull if the insn currently being emitted was a COND_EXEC pattern.  */
    198  1.1  mrg rtx current_insn_predicate;
    199  1.1  mrg 
    200  1.1  mrg /* True if printing into -fdump-final-insns= dump.  */
    201  1.1  mrg bool final_insns_dump_p;
    202  1.1  mrg 
    203  1.1  mrg /* True if profile_function should be called, but hasn't been called yet.  */
    204  1.1  mrg static bool need_profile_function;
    205  1.1  mrg 
    206  1.1  mrg static int asm_insn_count (rtx);
    207  1.1  mrg static void profile_function (FILE *);
    208  1.1  mrg static void profile_after_prologue (FILE *);
    209  1.1  mrg static bool notice_source_line (rtx_insn *, bool *);
    210  1.1  mrg static rtx walk_alter_subreg (rtx *, bool *);
    211  1.1  mrg static void output_asm_name (void);
    212  1.1  mrg static void output_alternate_entry_point (FILE *, rtx_insn *);
    213  1.1  mrg static tree get_mem_expr_from_op (rtx, int *);
    214  1.1  mrg static void output_asm_operand_names (rtx *, int *, int);
    215  1.1  mrg #ifdef LEAF_REGISTERS
    216  1.1  mrg static void leaf_renumber_regs (rtx_insn *);
    217  1.1  mrg #endif
    218  1.1  mrg static int align_fuzz (rtx, rtx, int, unsigned);
    219  1.1  mrg static void collect_fn_hard_reg_usage (void);
    220  1.1  mrg 
    221  1.1  mrg /* Initialize data in final at the beginning of a compilation.  */
    223  1.1  mrg 
    224  1.1  mrg void
    225  1.1  mrg init_final (const char *filename ATTRIBUTE_UNUSED)
    226  1.1  mrg {
    227  1.1  mrg   app_on = 0;
    228  1.1  mrg   final_sequence = 0;
    229  1.1  mrg 
    230  1.1  mrg #ifdef ASSEMBLER_DIALECT
    231  1.1  mrg   dialect_number = ASSEMBLER_DIALECT;
    232  1.1  mrg #endif
    233  1.1  mrg }
    234  1.1  mrg 
    235  1.1  mrg /* Default target function prologue and epilogue assembler output.
    236  1.1  mrg 
    237  1.1  mrg    If not overridden for epilogue code, then the function body itself
    238  1.1  mrg    contains return instructions wherever needed.  */
    239  1.1  mrg void
    240  1.1  mrg default_function_pro_epilogue (FILE *)
    241  1.1  mrg {
    242  1.1  mrg }
    243  1.1  mrg 
    244  1.1  mrg void
    245  1.1  mrg default_function_switched_text_sections (FILE *file ATTRIBUTE_UNUSED,
    246  1.1  mrg 					 tree decl ATTRIBUTE_UNUSED,
    247  1.1  mrg 					 bool new_is_cold ATTRIBUTE_UNUSED)
    248  1.1  mrg {
    249  1.1  mrg }
    250  1.1  mrg 
    251  1.1  mrg /* Default target hook that outputs nothing to a stream.  */
    252  1.1  mrg void
    253  1.1  mrg no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED)
    254  1.1  mrg {
    255  1.1  mrg }
    256  1.1  mrg 
    257  1.1  mrg /* Enable APP processing of subsequent output.
    258  1.1  mrg    Used before the output from an `asm' statement.  */
    259  1.1  mrg 
    260  1.1  mrg void
    261  1.1  mrg app_enable (void)
    262  1.1  mrg {
    263  1.1  mrg   if (! app_on)
    264  1.1  mrg     {
    265  1.1  mrg       fputs (ASM_APP_ON, asm_out_file);
    266  1.1  mrg       app_on = 1;
    267  1.1  mrg     }
    268  1.1  mrg }
    269  1.1  mrg 
    270  1.1  mrg /* Disable APP processing of subsequent output.
    271  1.1  mrg    Called from varasm.cc before most kinds of output.  */
    272  1.1  mrg 
    273  1.1  mrg void
    274  1.1  mrg app_disable (void)
    275  1.1  mrg {
    276  1.1  mrg   if (app_on)
    277  1.1  mrg     {
    278  1.1  mrg       fputs (ASM_APP_OFF, asm_out_file);
    279  1.1  mrg       app_on = 0;
    280  1.1  mrg     }
    281  1.1  mrg }
    282  1.1  mrg 
    283  1.1  mrg /* Return the number of slots filled in the current
    285  1.1  mrg    delayed branch sequence (we don't count the insn needing the
    286  1.1  mrg    delay slot).   Zero if not in a delayed branch sequence.  */
    287  1.1  mrg 
    288  1.1  mrg int
    289  1.1  mrg dbr_sequence_length (void)
    290  1.1  mrg {
    291  1.1  mrg   if (final_sequence != 0)
    292  1.1  mrg     return XVECLEN (final_sequence, 0) - 1;
    293  1.1  mrg   else
    294  1.1  mrg     return 0;
    295  1.1  mrg }
    296  1.1  mrg 
    297  1.1  mrg /* The next two pages contain routines used to compute the length of an insn
    299  1.1  mrg    and to shorten branches.  */
    300  1.1  mrg 
    301  1.1  mrg /* Arrays for insn lengths, and addresses.  The latter is referenced by
    302  1.1  mrg    `insn_current_length'.  */
    303  1.1  mrg 
    304  1.1  mrg static int *insn_lengths;
    305  1.1  mrg 
    306  1.1  mrg vec<int> insn_addresses_;
    307  1.1  mrg 
    308  1.1  mrg /* Max uid for which the above arrays are valid.  */
    309  1.1  mrg static int insn_lengths_max_uid;
    310  1.1  mrg 
    311  1.1  mrg /* Address of insn being processed.  Used by `insn_current_length'.  */
    312  1.1  mrg int insn_current_address;
    313  1.1  mrg 
    314  1.1  mrg /* Address of insn being processed in previous iteration.  */
    315  1.1  mrg int insn_last_address;
    316  1.1  mrg 
    317  1.1  mrg /* known invariant alignment of insn being processed.  */
    318  1.1  mrg int insn_current_align;
    319  1.1  mrg 
    320  1.1  mrg /* After shorten_branches, for any insn, uid_align[INSN_UID (insn)]
    321  1.1  mrg    gives the next following alignment insn that increases the known
    322  1.1  mrg    alignment, or NULL_RTX if there is no such insn.
    323  1.1  mrg    For any alignment obtained this way, we can again index uid_align with
    324  1.1  mrg    its uid to obtain the next following align that in turn increases the
    325  1.1  mrg    alignment, till we reach NULL_RTX; the sequence obtained this way
    326  1.1  mrg    for each insn we'll call the alignment chain of this insn in the following
    327  1.1  mrg    comments.  */
    328  1.1  mrg 
    329  1.1  mrg static rtx *uid_align;
    330  1.1  mrg static int *uid_shuid;
    331  1.1  mrg static vec<align_flags> label_align;
    332  1.1  mrg 
    333  1.1  mrg /* Indicate that branch shortening hasn't yet been done.  */
    334  1.1  mrg 
    335  1.1  mrg void
    336  1.1  mrg init_insn_lengths (void)
    337  1.1  mrg {
    338  1.1  mrg   if (uid_shuid)
    339  1.1  mrg     {
    340  1.1  mrg       free (uid_shuid);
    341  1.1  mrg       uid_shuid = 0;
    342  1.1  mrg     }
    343  1.1  mrg   if (insn_lengths)
    344  1.1  mrg     {
    345  1.1  mrg       free (insn_lengths);
    346  1.1  mrg       insn_lengths = 0;
    347  1.1  mrg       insn_lengths_max_uid = 0;
    348  1.1  mrg     }
    349  1.1  mrg   if (HAVE_ATTR_length)
    350  1.1  mrg     INSN_ADDRESSES_FREE ();
    351  1.1  mrg   if (uid_align)
    352  1.1  mrg     {
    353  1.1  mrg       free (uid_align);
    354  1.1  mrg       uid_align = 0;
    355  1.1  mrg     }
    356  1.1  mrg }
    357  1.1  mrg 
    358  1.1  mrg /* Obtain the current length of an insn.  If branch shortening has been done,
    359  1.1  mrg    get its actual length.  Otherwise, use FALLBACK_FN to calculate the
    360  1.1  mrg    length.  */
    361  1.1  mrg static int
    362  1.1  mrg get_attr_length_1 (rtx_insn *insn, int (*fallback_fn) (rtx_insn *))
    363  1.1  mrg {
    364  1.1  mrg   rtx body;
    365  1.1  mrg   int i;
    366  1.1  mrg   int length = 0;
    367  1.1  mrg 
    368  1.1  mrg   if (!HAVE_ATTR_length)
    369  1.1  mrg     return 0;
    370  1.1  mrg 
    371  1.1  mrg   if (insn_lengths_max_uid > INSN_UID (insn))
    372  1.1  mrg     return insn_lengths[INSN_UID (insn)];
    373  1.1  mrg   else
    374  1.1  mrg     switch (GET_CODE (insn))
    375  1.1  mrg       {
    376  1.1  mrg       case NOTE:
    377  1.1  mrg       case BARRIER:
    378  1.1  mrg       case CODE_LABEL:
    379  1.1  mrg       case DEBUG_INSN:
    380  1.1  mrg 	return 0;
    381  1.1  mrg 
    382  1.1  mrg       case CALL_INSN:
    383  1.1  mrg       case JUMP_INSN:
    384  1.1  mrg 	body = PATTERN (insn);
    385  1.1  mrg 	if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
    386  1.1  mrg 	  length = asm_insn_count (body) * fallback_fn (insn);
    387  1.1  mrg 	else
    388  1.1  mrg 	  length = fallback_fn (insn);
    389  1.1  mrg 	break;
    390  1.1  mrg 
    391  1.1  mrg       case INSN:
    392  1.1  mrg 	body = PATTERN (insn);
    393  1.1  mrg 	if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
    394  1.1  mrg 	  return 0;
    395  1.1  mrg 
    396  1.1  mrg 	else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
    397  1.1  mrg 	  length = asm_insn_count (body) * fallback_fn (insn);
    398  1.1  mrg 	else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
    399  1.1  mrg 	  for (i = 0; i < seq->len (); i++)
    400  1.1  mrg 	    length += get_attr_length_1 (seq->insn (i), fallback_fn);
    401  1.1  mrg 	else
    402  1.1  mrg 	  length = fallback_fn (insn);
    403  1.1  mrg 	break;
    404  1.1  mrg 
    405  1.1  mrg       default:
    406  1.1  mrg 	break;
    407  1.1  mrg       }
    408  1.1  mrg 
    409  1.1  mrg #ifdef ADJUST_INSN_LENGTH
    410  1.1  mrg   ADJUST_INSN_LENGTH (insn, length);
    411  1.1  mrg #endif
    412  1.1  mrg   return length;
    413  1.1  mrg }
    414  1.1  mrg 
    415  1.1  mrg /* Obtain the current length of an insn.  If branch shortening has been done,
    416  1.1  mrg    get its actual length.  Otherwise, get its maximum length.  */
    417  1.1  mrg int
    418  1.1  mrg get_attr_length (rtx_insn *insn)
    419  1.1  mrg {
    420  1.1  mrg   return get_attr_length_1 (insn, insn_default_length);
    421  1.1  mrg }
    422  1.1  mrg 
    423  1.1  mrg /* Obtain the current length of an insn.  If branch shortening has been done,
    424  1.1  mrg    get its actual length.  Otherwise, get its minimum length.  */
    425  1.1  mrg int
    426  1.1  mrg get_attr_min_length (rtx_insn *insn)
    427  1.1  mrg {
    428  1.1  mrg   return get_attr_length_1 (insn, insn_min_length);
    429  1.1  mrg }
    430  1.1  mrg 
    431  1.1  mrg /* Code to handle alignment inside shorten_branches.  */
    433  1.1  mrg 
    434  1.1  mrg /* Here is an explanation how the algorithm in align_fuzz can give
    435  1.1  mrg    proper results:
    436  1.1  mrg 
    437  1.1  mrg    Call a sequence of instructions beginning with alignment point X
    438  1.1  mrg    and continuing until the next alignment point `block X'.  When `X'
    439  1.1  mrg    is used in an expression, it means the alignment value of the
    440  1.1  mrg    alignment point.
    441  1.1  mrg 
    442  1.1  mrg    Call the distance between the start of the first insn of block X, and
    443  1.1  mrg    the end of the last insn of block X `IX', for the `inner size of X'.
    444  1.1  mrg    This is clearly the sum of the instruction lengths.
    445  1.1  mrg 
    446  1.1  mrg    Likewise with the next alignment-delimited block following X, which we
    447  1.1  mrg    shall call block Y.
    448  1.1  mrg 
    449  1.1  mrg    Call the distance between the start of the first insn of block X, and
    450  1.1  mrg    the start of the first insn of block Y `OX', for the `outer size of X'.
    451  1.1  mrg 
    452  1.1  mrg    The estimated padding is then OX - IX.
    453  1.1  mrg 
    454  1.1  mrg    OX can be safely estimated as
    455  1.1  mrg 
    456  1.1  mrg            if (X >= Y)
    457  1.1  mrg                    OX = round_up(IX, Y)
    458  1.1  mrg            else
    459  1.1  mrg                    OX = round_up(IX, X) + Y - X
    460  1.1  mrg 
    461  1.1  mrg    Clearly est(IX) >= real(IX), because that only depends on the
    462  1.1  mrg    instruction lengths, and those being overestimated is a given.
    463  1.1  mrg 
    464  1.1  mrg    Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so
    465  1.1  mrg    we needn't worry about that when thinking about OX.
    466  1.1  mrg 
    467  1.1  mrg    When X >= Y, the alignment provided by Y adds no uncertainty factor
    468  1.1  mrg    for branch ranges starting before X, so we can just round what we have.
    469  1.1  mrg    But when X < Y, we don't know anything about the, so to speak,
    470  1.1  mrg    `middle bits', so we have to assume the worst when aligning up from an
    471  1.1  mrg    address mod X to one mod Y, which is Y - X.  */
    472  1.1  mrg 
    473  1.1  mrg #ifndef LABEL_ALIGN
    474  1.1  mrg #define LABEL_ALIGN(LABEL) align_labels
    475  1.1  mrg #endif
    476  1.1  mrg 
    477  1.1  mrg #ifndef LOOP_ALIGN
    478  1.1  mrg #define LOOP_ALIGN(LABEL) align_loops
    479  1.1  mrg #endif
    480  1.1  mrg 
    481  1.1  mrg #ifndef LABEL_ALIGN_AFTER_BARRIER
    482  1.1  mrg #define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0
    483  1.1  mrg #endif
    484  1.1  mrg 
    485  1.1  mrg #ifndef JUMP_ALIGN
    486  1.1  mrg #define JUMP_ALIGN(LABEL) align_jumps
    487  1.1  mrg #endif
    488  1.1  mrg 
    489  1.1  mrg #ifndef ADDR_VEC_ALIGN
    490  1.1  mrg static int
    491  1.1  mrg final_addr_vec_align (rtx_jump_table_data *addr_vec)
    492  1.1  mrg {
    493  1.1  mrg   int align = GET_MODE_SIZE (addr_vec->get_data_mode ());
    494  1.1  mrg 
    495  1.1  mrg   if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
    496  1.1  mrg     align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
    497  1.1  mrg   return exact_log2 (align);
    498  1.1  mrg 
    499  1.1  mrg }
    500  1.1  mrg 
    501  1.1  mrg #define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC)
    502  1.1  mrg #endif
    503  1.1  mrg 
    504  1.1  mrg #ifndef INSN_LENGTH_ALIGNMENT
    505  1.1  mrg #define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log
    506  1.1  mrg #endif
    507  1.1  mrg 
    508  1.1  mrg #define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)])
    509  1.1  mrg 
    510  1.1  mrg static int min_labelno, max_labelno;
    511  1.1  mrg 
    512  1.1  mrg #define LABEL_TO_ALIGNMENT(LABEL) \
    513  1.1  mrg   (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno])
    514  1.1  mrg 
    515  1.1  mrg /* For the benefit of port specific code do this also as a function.  */
    516  1.1  mrg 
    517  1.1  mrg align_flags
    518  1.1  mrg label_to_alignment (rtx label)
    519  1.1  mrg {
    520  1.1  mrg   if (CODE_LABEL_NUMBER (label) <= max_labelno)
    521  1.1  mrg     return LABEL_TO_ALIGNMENT (label);
    522  1.1  mrg   return align_flags ();
    523  1.1  mrg }
    524  1.1  mrg 
    525  1.1  mrg /* The differences in addresses
    526  1.1  mrg    between a branch and its target might grow or shrink depending on
    527  1.1  mrg    the alignment the start insn of the range (the branch for a forward
    528  1.1  mrg    branch or the label for a backward branch) starts out on; if these
    529  1.1  mrg    differences are used naively, they can even oscillate infinitely.
    530  1.1  mrg    We therefore want to compute a 'worst case' address difference that
    531  1.1  mrg    is independent of the alignment the start insn of the range end
    532  1.1  mrg    up on, and that is at least as large as the actual difference.
    533  1.1  mrg    The function align_fuzz calculates the amount we have to add to the
    534  1.1  mrg    naively computed difference, by traversing the part of the alignment
    535  1.1  mrg    chain of the start insn of the range that is in front of the end insn
    536  1.1  mrg    of the range, and considering for each alignment the maximum amount
    537  1.1  mrg    that it might contribute to a size increase.
    538  1.1  mrg 
    539  1.1  mrg    For casesi tables, we also want to know worst case minimum amounts of
    540  1.1  mrg    address difference, in case a machine description wants to introduce
    541  1.1  mrg    some common offset that is added to all offsets in a table.
    542  1.1  mrg    For this purpose, align_fuzz with a growth argument of 0 computes the
    543  1.1  mrg    appropriate adjustment.  */
    544  1.1  mrg 
    545  1.1  mrg /* Compute the maximum delta by which the difference of the addresses of
    546  1.1  mrg    START and END might grow / shrink due to a different address for start
    547  1.1  mrg    which changes the size of alignment insns between START and END.
    548  1.1  mrg    KNOWN_ALIGN_LOG is the alignment known for START.
    549  1.1  mrg    GROWTH should be ~0 if the objective is to compute potential code size
    550  1.1  mrg    increase, and 0 if the objective is to compute potential shrink.
    551  1.1  mrg    The return value is undefined for any other value of GROWTH.  */
    552  1.1  mrg 
    553  1.1  mrg static int
    554  1.1  mrg align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth)
    555  1.1  mrg {
    556  1.1  mrg   int uid = INSN_UID (start);
    557  1.1  mrg   rtx align_label;
    558  1.1  mrg   int known_align = 1 << known_align_log;
    559  1.1  mrg   int end_shuid = INSN_SHUID (end);
    560  1.1  mrg   int fuzz = 0;
    561  1.1  mrg 
    562  1.1  mrg   for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid])
    563  1.1  mrg     {
    564  1.1  mrg       int align_addr, new_align;
    565  1.1  mrg 
    566  1.1  mrg       uid = INSN_UID (align_label);
    567  1.1  mrg       align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid];
    568  1.1  mrg       if (uid_shuid[uid] > end_shuid)
    569  1.1  mrg 	break;
    570  1.1  mrg       align_flags alignment = LABEL_TO_ALIGNMENT (align_label);
    571  1.1  mrg       new_align = 1 << alignment.levels[0].log;
    572  1.1  mrg       if (new_align < known_align)
    573  1.1  mrg 	continue;
    574  1.1  mrg       fuzz += (-align_addr ^ growth) & (new_align - known_align);
    575  1.1  mrg       known_align = new_align;
    576  1.1  mrg     }
    577  1.1  mrg   return fuzz;
    578  1.1  mrg }
    579  1.1  mrg 
    580  1.1  mrg /* Compute a worst-case reference address of a branch so that it
    581  1.1  mrg    can be safely used in the presence of aligned labels.  Since the
    582  1.1  mrg    size of the branch itself is unknown, the size of the branch is
    583  1.1  mrg    not included in the range.  I.e. for a forward branch, the reference
    584  1.1  mrg    address is the end address of the branch as known from the previous
    585  1.1  mrg    branch shortening pass, minus a value to account for possible size
    586  1.1  mrg    increase due to alignment.  For a backward branch, it is the start
    587  1.1  mrg    address of the branch as known from the current pass, plus a value
    588  1.1  mrg    to account for possible size increase due to alignment.
    589  1.1  mrg    NB.: Therefore, the maximum offset allowed for backward branches needs
    590  1.1  mrg    to exclude the branch size.  */
    591  1.1  mrg 
    592  1.1  mrg int
    593  1.1  mrg insn_current_reference_address (rtx_insn *branch)
    594  1.1  mrg {
    595  1.1  mrg   rtx dest;
    596  1.1  mrg   int seq_uid;
    597  1.1  mrg 
    598  1.1  mrg   if (! INSN_ADDRESSES_SET_P ())
    599  1.1  mrg     return 0;
    600  1.1  mrg 
    601  1.1  mrg   rtx_insn *seq = NEXT_INSN (PREV_INSN (branch));
    602  1.1  mrg   seq_uid = INSN_UID (seq);
    603  1.1  mrg   if (!jump_to_label_p (branch))
    604  1.1  mrg     /* This can happen for example on the PA; the objective is to know the
    605  1.1  mrg        offset to address something in front of the start of the function.
    606  1.1  mrg        Thus, we can treat it like a backward branch.
    607  1.1  mrg        We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than
    608  1.1  mrg        any alignment we'd encounter, so we skip the call to align_fuzz.  */
    609  1.1  mrg     return insn_current_address;
    610  1.1  mrg   dest = JUMP_LABEL (branch);
    611  1.1  mrg 
    612  1.1  mrg   /* BRANCH has no proper alignment chain set, so use SEQ.
    613  1.1  mrg      BRANCH also has no INSN_SHUID.  */
    614  1.1  mrg   if (INSN_SHUID (seq) < INSN_SHUID (dest))
    615  1.1  mrg     {
    616  1.1  mrg       /* Forward branch.  */
    617  1.1  mrg       return (insn_last_address + insn_lengths[seq_uid]
    618  1.1  mrg 	      - align_fuzz (seq, dest, length_unit_log, ~0));
    619  1.1  mrg     }
    620  1.1  mrg   else
    621  1.1  mrg     {
    622  1.1  mrg       /* Backward branch.  */
    623  1.1  mrg       return (insn_current_address
    624  1.1  mrg 	      + align_fuzz (dest, seq, length_unit_log, ~0));
    625  1.1  mrg     }
    626  1.1  mrg }
    627  1.1  mrg 
    628  1.1  mrg /* Compute branch alignments based on CFG profile.  */
    630  1.1  mrg 
    631  1.1  mrg unsigned int
    632  1.1  mrg compute_alignments (void)
    633  1.1  mrg {
    634  1.1  mrg   basic_block bb;
    635  1.1  mrg   align_flags max_alignment;
    636  1.1  mrg 
    637  1.1  mrg   label_align.truncate (0);
    638  1.1  mrg 
    639  1.1  mrg   max_labelno = max_label_num ();
    640  1.1  mrg   min_labelno = get_first_label_num ();
    641  1.1  mrg   label_align.safe_grow_cleared (max_labelno - min_labelno + 1, true);
    642  1.1  mrg 
    643  1.1  mrg   /* If not optimizing or optimizing for size, don't assign any alignments.  */
    644  1.1  mrg   if (! optimize || optimize_function_for_size_p (cfun))
    645  1.1  mrg     return 0;
    646  1.1  mrg 
    647  1.1  mrg   if (dump_file)
    648  1.1  mrg     {
    649  1.1  mrg       dump_reg_info (dump_file);
    650  1.1  mrg       dump_flow_info (dump_file, TDF_DETAILS);
    651  1.1  mrg       flow_loops_dump (dump_file, NULL, 1);
    652  1.1  mrg     }
    653  1.1  mrg   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
    654  1.1  mrg   profile_count count_threshold = cfun->cfg->count_max.apply_scale
    655  1.1  mrg 		 (1, param_align_threshold);
    656  1.1  mrg 
    657  1.1  mrg   if (dump_file)
    658  1.1  mrg     {
    659  1.1  mrg       fprintf (dump_file, "count_max: ");
    660  1.1  mrg       cfun->cfg->count_max.dump (dump_file);
    661  1.1  mrg       fprintf (dump_file, "\n");
    662  1.1  mrg     }
    663  1.1  mrg   FOR_EACH_BB_FN (bb, cfun)
    664  1.1  mrg     {
    665  1.1  mrg       rtx_insn *label = BB_HEAD (bb);
    666  1.1  mrg       bool has_fallthru = 0;
    667  1.1  mrg       edge e;
    668  1.1  mrg       edge_iterator ei;
    669  1.1  mrg 
    670  1.1  mrg       if (!LABEL_P (label)
    671  1.1  mrg 	  || optimize_bb_for_size_p (bb))
    672  1.1  mrg 	{
    673  1.1  mrg 	  if (dump_file)
    674  1.1  mrg 	    fprintf (dump_file,
    675  1.1  mrg 		     "BB %4i loop %2i loop_depth %2i skipped.\n",
    676  1.1  mrg 		     bb->index,
    677  1.1  mrg 		     bb->loop_father->num,
    678  1.1  mrg 		     bb_loop_depth (bb));
    679  1.1  mrg 	  continue;
    680  1.1  mrg 	}
    681  1.1  mrg       max_alignment = LABEL_ALIGN (label);
    682  1.1  mrg       profile_count fallthru_count = profile_count::zero ();
    683  1.1  mrg       profile_count branch_count = profile_count::zero ();
    684  1.1  mrg 
    685  1.1  mrg       FOR_EACH_EDGE (e, ei, bb->preds)
    686  1.1  mrg 	{
    687  1.1  mrg 	  if (e->flags & EDGE_FALLTHRU)
    688  1.1  mrg 	    has_fallthru = 1, fallthru_count += e->count ();
    689  1.1  mrg 	  else
    690  1.1  mrg 	    branch_count += e->count ();
    691  1.1  mrg 	}
    692  1.1  mrg       if (dump_file)
    693  1.1  mrg 	{
    694  1.1  mrg 	  fprintf (dump_file, "BB %4i loop %2i loop_depth"
    695  1.1  mrg 		   " %2i fall ",
    696  1.1  mrg 		   bb->index, bb->loop_father->num,
    697  1.1  mrg 		   bb_loop_depth (bb));
    698  1.1  mrg 	  fallthru_count.dump (dump_file);
    699  1.1  mrg 	  fprintf (dump_file, " branch ");
    700  1.1  mrg 	  branch_count.dump (dump_file);
    701  1.1  mrg 	  if (!bb->loop_father->inner && bb->loop_father->num)
    702  1.1  mrg 	    fprintf (dump_file, " inner_loop");
    703  1.1  mrg 	  if (bb->loop_father->header == bb)
    704  1.1  mrg 	    fprintf (dump_file, " loop_header");
    705  1.1  mrg 	  fprintf (dump_file, "\n");
    706  1.1  mrg 	}
    707  1.1  mrg       if (!fallthru_count.initialized_p () || !branch_count.initialized_p ())
    708  1.1  mrg 	continue;
    709  1.1  mrg 
    710  1.1  mrg       /* There are two purposes to align block with no fallthru incoming edge:
    711  1.1  mrg 	 1) to avoid fetch stalls when branch destination is near cache boundary
    712  1.1  mrg 	 2) to improve cache efficiency in case the previous block is not executed
    713  1.1  mrg 	    (so it does not need to be in the cache).
    714  1.1  mrg 
    715  1.1  mrg 	 We to catch first case, we align frequently executed blocks.
    716  1.1  mrg 	 To catch the second, we align blocks that are executed more frequently
    717  1.1  mrg 	 than the predecessor and the predecessor is likely to not be executed
    718  1.1  mrg 	 when function is called.  */
    719  1.1  mrg 
    720  1.1  mrg       if (!has_fallthru
    721  1.1  mrg 	  && (branch_count > count_threshold
    722  1.1  mrg 	      || (bb->count > bb->prev_bb->count.apply_scale (10, 1)
    723  1.1  mrg 		  && (bb->prev_bb->count
    724  1.1  mrg 		      <= ENTRY_BLOCK_PTR_FOR_FN (cfun)
    725  1.1  mrg 			   ->count.apply_scale (1, 2)))))
    726  1.1  mrg 	{
    727  1.1  mrg 	  align_flags alignment = JUMP_ALIGN (label);
    728  1.1  mrg 	  if (dump_file)
    729  1.1  mrg 	    fprintf (dump_file, "  jump alignment added.\n");
    730  1.1  mrg 	  max_alignment = align_flags::max (max_alignment, alignment);
    731  1.1  mrg 	}
    732  1.1  mrg       /* In case block is frequent and reached mostly by non-fallthru edge,
    733  1.1  mrg 	 align it.  It is most likely a first block of loop.  */
    734  1.1  mrg       if (has_fallthru
    735  1.1  mrg 	  && !(single_succ_p (bb)
    736  1.1  mrg 	       && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
    737  1.1  mrg 	  && optimize_bb_for_speed_p (bb)
    738  1.1  mrg 	  && branch_count + fallthru_count > count_threshold
    739  1.1  mrg 	  && (branch_count
    740  1.1  mrg 	      > fallthru_count.apply_scale
    741  1.1  mrg 		    (param_align_loop_iterations, 1)))
    742  1.1  mrg 	{
    743  1.1  mrg 	  align_flags alignment = LOOP_ALIGN (label);
    744  1.1  mrg 	  if (dump_file)
    745  1.1  mrg 	    fprintf (dump_file, "  internal loop alignment added.\n");
    746  1.1  mrg 	  max_alignment = align_flags::max (max_alignment, alignment);
    747  1.1  mrg 	}
    748  1.1  mrg       LABEL_TO_ALIGNMENT (label) = max_alignment;
    749  1.1  mrg     }
    750  1.1  mrg 
    751  1.1  mrg   loop_optimizer_finalize ();
    752  1.1  mrg   free_dominance_info (CDI_DOMINATORS);
    753  1.1  mrg   return 0;
    754  1.1  mrg }
    755  1.1  mrg 
    756  1.1  mrg /* Grow the LABEL_ALIGN array after new labels are created.  */
    757  1.1  mrg 
    758  1.1  mrg static void
    759  1.1  mrg grow_label_align (void)
    760  1.1  mrg {
    761  1.1  mrg   int old = max_labelno;
    762  1.1  mrg   int n_labels;
    763  1.1  mrg   int n_old_labels;
    764  1.1  mrg 
    765  1.1  mrg   max_labelno = max_label_num ();
    766  1.1  mrg 
    767  1.1  mrg   n_labels = max_labelno - min_labelno + 1;
    768  1.1  mrg   n_old_labels = old - min_labelno + 1;
    769  1.1  mrg 
    770  1.1  mrg   label_align.safe_grow_cleared (n_labels, true);
    771  1.1  mrg 
    772  1.1  mrg   /* Range of labels grows monotonically in the function.  Failing here
    773  1.1  mrg      means that the initialization of array got lost.  */
    774  1.1  mrg   gcc_assert (n_old_labels <= n_labels);
    775  1.1  mrg }
    776  1.1  mrg 
    777  1.1  mrg /* Update the already computed alignment information.  LABEL_PAIRS is a vector
    778  1.1  mrg    made up of pairs of labels for which the alignment information of the first
    779  1.1  mrg    element will be copied from that of the second element.  */
    780  1.1  mrg 
    781  1.1  mrg void
    782  1.1  mrg update_alignments (vec<rtx> &label_pairs)
    783  1.1  mrg {
    784  1.1  mrg   unsigned int i = 0;
    785  1.1  mrg   rtx iter, label = NULL_RTX;
    786  1.1  mrg 
    787  1.1  mrg   if (max_labelno != max_label_num ())
    788  1.1  mrg     grow_label_align ();
    789  1.1  mrg 
    790  1.1  mrg   FOR_EACH_VEC_ELT (label_pairs, i, iter)
    791  1.1  mrg     if (i & 1)
    792  1.1  mrg       LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter);
    793  1.1  mrg     else
    794  1.1  mrg       label = iter;
    795  1.1  mrg }
    796  1.1  mrg 
    797  1.1  mrg namespace {
    798  1.1  mrg 
    799  1.1  mrg const pass_data pass_data_compute_alignments =
    800  1.1  mrg {
    801  1.1  mrg   RTL_PASS, /* type */
    802  1.1  mrg   "alignments", /* name */
    803  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
    804  1.1  mrg   TV_NONE, /* tv_id */
    805  1.1  mrg   0, /* properties_required */
    806  1.1  mrg   0, /* properties_provided */
    807  1.1  mrg   0, /* properties_destroyed */
    808  1.1  mrg   0, /* todo_flags_start */
    809  1.1  mrg   0, /* todo_flags_finish */
    810  1.1  mrg };
    811  1.1  mrg 
    812  1.1  mrg class pass_compute_alignments : public rtl_opt_pass
    813  1.1  mrg {
    814  1.1  mrg public:
    815  1.1  mrg   pass_compute_alignments (gcc::context *ctxt)
    816  1.1  mrg     : rtl_opt_pass (pass_data_compute_alignments, ctxt)
    817  1.1  mrg   {}
    818  1.1  mrg 
    819  1.1  mrg   /* opt_pass methods: */
    820  1.1  mrg   virtual unsigned int execute (function *) { return compute_alignments (); }
    821  1.1  mrg 
    822  1.1  mrg }; // class pass_compute_alignments
    823  1.1  mrg 
    824  1.1  mrg } // anon namespace
    825  1.1  mrg 
    826  1.1  mrg rtl_opt_pass *
    827  1.1  mrg make_pass_compute_alignments (gcc::context *ctxt)
    828  1.1  mrg {
    829  1.1  mrg   return new pass_compute_alignments (ctxt);
    830  1.1  mrg }
    831  1.1  mrg 
    832  1.1  mrg 
    833  1.1  mrg /* Make a pass over all insns and compute their actual lengths by shortening
    835  1.1  mrg    any branches of variable length if possible.  */
    836  1.1  mrg 
    837  1.1  mrg /* shorten_branches might be called multiple times:  for example, the SH
    838  1.1  mrg    port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
    839  1.1  mrg    In order to do this, it needs proper length information, which it obtains
    840  1.1  mrg    by calling shorten_branches.  This cannot be collapsed with
    841  1.1  mrg    shorten_branches itself into a single pass unless we also want to integrate
    842  1.1  mrg    reorg.cc, since the branch splitting exposes new instructions with delay
    843  1.1  mrg    slots.  */
    844  1.1  mrg 
    845  1.1  mrg void
    846  1.1  mrg shorten_branches (rtx_insn *first)
    847  1.1  mrg {
    848  1.1  mrg   rtx_insn *insn;
    849  1.1  mrg   int max_uid;
    850  1.1  mrg   int i;
    851  1.1  mrg   rtx_insn *seq;
    852  1.1  mrg   int something_changed = 1;
    853  1.1  mrg   char *varying_length;
    854  1.1  mrg   rtx body;
    855  1.1  mrg   int uid;
    856  1.1  mrg   rtx align_tab[MAX_CODE_ALIGN + 1];
    857  1.1  mrg 
    858  1.1  mrg   /* Compute maximum UID and allocate label_align / uid_shuid.  */
    859  1.1  mrg   max_uid = get_max_uid ();
    860  1.1  mrg 
    861  1.1  mrg   /* Free uid_shuid before reallocating it.  */
    862  1.1  mrg   free (uid_shuid);
    863  1.1  mrg 
    864  1.1  mrg   uid_shuid = XNEWVEC (int, max_uid);
    865  1.1  mrg 
    866  1.1  mrg   if (max_labelno != max_label_num ())
    867  1.1  mrg     grow_label_align ();
    868  1.1  mrg 
    869  1.1  mrg   /* Initialize label_align and set up uid_shuid to be strictly
    870  1.1  mrg      monotonically rising with insn order.  */
    871  1.1  mrg   /* We use alignment here to keep track of the maximum alignment we want to
    872  1.1  mrg      impose on the next CODE_LABEL (or the current one if we are processing
    873  1.1  mrg      the CODE_LABEL itself).  */
    874  1.1  mrg 
    875  1.1  mrg   align_flags max_alignment;
    876  1.1  mrg 
    877  1.1  mrg   for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
    878  1.1  mrg     {
    879  1.1  mrg       INSN_SHUID (insn) = i++;
    880  1.1  mrg       if (INSN_P (insn))
    881  1.1  mrg 	continue;
    882  1.1  mrg 
    883  1.1  mrg       if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
    884  1.1  mrg 	{
    885  1.1  mrg 	  /* Merge in alignments computed by compute_alignments.  */
    886  1.1  mrg 	  align_flags alignment = LABEL_TO_ALIGNMENT (label);
    887  1.1  mrg 	  max_alignment = align_flags::max (max_alignment, alignment);
    888  1.1  mrg 
    889  1.1  mrg 	  rtx_jump_table_data *table = jump_table_for_label (label);
    890  1.1  mrg 	  if (!table)
    891  1.1  mrg 	    {
    892  1.1  mrg 	      align_flags alignment = LABEL_ALIGN (label);
    893  1.1  mrg 	      max_alignment = align_flags::max (max_alignment, alignment);
    894  1.1  mrg 	    }
    895  1.1  mrg 	  /* ADDR_VECs only take room if read-only data goes into the text
    896  1.1  mrg 	     section.  */
    897  1.1  mrg 	  if ((JUMP_TABLES_IN_TEXT_SECTION
    898  1.1  mrg 	       || readonly_data_section == text_section)
    899  1.1  mrg 	      && table)
    900  1.1  mrg 	    {
    901  1.1  mrg 	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
    902  1.1  mrg 	      max_alignment = align_flags::max (max_alignment, alignment);
    903  1.1  mrg 	    }
    904  1.1  mrg 	  LABEL_TO_ALIGNMENT (label) = max_alignment;
    905  1.1  mrg 	  max_alignment = align_flags ();
    906  1.1  mrg 	}
    907  1.1  mrg       else if (BARRIER_P (insn))
    908  1.1  mrg 	{
    909  1.1  mrg 	  rtx_insn *label;
    910  1.1  mrg 
    911  1.1  mrg 	  for (label = insn; label && ! INSN_P (label);
    912  1.1  mrg 	       label = NEXT_INSN (label))
    913  1.1  mrg 	    if (LABEL_P (label))
    914  1.1  mrg 	      {
    915  1.1  mrg 		align_flags alignment
    916  1.1  mrg 		  = align_flags (LABEL_ALIGN_AFTER_BARRIER (insn));
    917  1.1  mrg 		max_alignment = align_flags::max (max_alignment, alignment);
    918  1.1  mrg 		break;
    919  1.1  mrg 	      }
    920  1.1  mrg 	}
    921  1.1  mrg     }
    922  1.1  mrg   if (!HAVE_ATTR_length)
    923  1.1  mrg     return;
    924  1.1  mrg 
    925  1.1  mrg   /* Allocate the rest of the arrays.  */
    926  1.1  mrg   insn_lengths = XNEWVEC (int, max_uid);
    927  1.1  mrg   insn_lengths_max_uid = max_uid;
    928  1.1  mrg   /* Syntax errors can lead to labels being outside of the main insn stream.
    929  1.1  mrg      Initialize insn_addresses, so that we get reproducible results.  */
    930  1.1  mrg   INSN_ADDRESSES_ALLOC (max_uid);
    931  1.1  mrg 
    932  1.1  mrg   varying_length = XCNEWVEC (char, max_uid);
    933  1.1  mrg 
    934  1.1  mrg   /* Initialize uid_align.  We scan instructions
    935  1.1  mrg      from end to start, and keep in align_tab[n] the last seen insn
    936  1.1  mrg      that does an alignment of at least n+1, i.e. the successor
    937  1.1  mrg      in the alignment chain for an insn that does / has a known
    938  1.1  mrg      alignment of n.  */
    939  1.1  mrg   uid_align = XCNEWVEC (rtx, max_uid);
    940  1.1  mrg 
    941  1.1  mrg   for (i = MAX_CODE_ALIGN + 1; --i >= 0;)
    942  1.1  mrg     align_tab[i] = NULL_RTX;
    943  1.1  mrg   seq = get_last_insn ();
    944  1.1  mrg   for (; seq; seq = PREV_INSN (seq))
    945  1.1  mrg     {
    946  1.1  mrg       int uid = INSN_UID (seq);
    947  1.1  mrg       int log;
    948  1.1  mrg       log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq).levels[0].log : 0);
    949  1.1  mrg       uid_align[uid] = align_tab[0];
    950  1.1  mrg       if (log)
    951  1.1  mrg 	{
    952  1.1  mrg 	  /* Found an alignment label.  */
    953  1.1  mrg 	  gcc_checking_assert (log < MAX_CODE_ALIGN + 1);
    954  1.1  mrg 	  uid_align[uid] = align_tab[log];
    955  1.1  mrg 	  for (i = log - 1; i >= 0; i--)
    956  1.1  mrg 	    align_tab[i] = seq;
    957  1.1  mrg 	}
    958  1.1  mrg     }
    959  1.1  mrg 
    960  1.1  mrg   /* When optimizing, we start assuming minimum length, and keep increasing
    961  1.1  mrg      lengths as we find the need for this, till nothing changes.
    962  1.1  mrg      When not optimizing, we start assuming maximum lengths, and
    963  1.1  mrg      do a single pass to update the lengths.  */
    964  1.1  mrg   bool increasing = optimize != 0;
    965  1.1  mrg 
    966  1.1  mrg #ifdef CASE_VECTOR_SHORTEN_MODE
    967  1.1  mrg   if (optimize)
    968  1.1  mrg     {
    969  1.1  mrg       /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum
    970  1.1  mrg          label fields.  */
    971  1.1  mrg 
    972  1.1  mrg       int min_shuid = INSN_SHUID (get_insns ()) - 1;
    973  1.1  mrg       int max_shuid = INSN_SHUID (get_last_insn ()) + 1;
    974  1.1  mrg       int rel;
    975  1.1  mrg 
    976  1.1  mrg       for (insn = first; insn != 0; insn = NEXT_INSN (insn))
    977  1.1  mrg 	{
    978  1.1  mrg 	  rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat;
    979  1.1  mrg 	  int len, i, min, max, insn_shuid;
    980  1.1  mrg 	  int min_align;
    981  1.1  mrg 	  addr_diff_vec_flags flags;
    982  1.1  mrg 
    983  1.1  mrg 	  if (! JUMP_TABLE_DATA_P (insn)
    984  1.1  mrg 	      || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
    985  1.1  mrg 	    continue;
    986  1.1  mrg 	  pat = PATTERN (insn);
    987  1.1  mrg 	  len = XVECLEN (pat, 1);
    988  1.1  mrg 	  gcc_assert (len > 0);
    989  1.1  mrg 	  min_align = MAX_CODE_ALIGN;
    990  1.1  mrg 	  for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
    991  1.1  mrg 	    {
    992  1.1  mrg 	      rtx lab = XEXP (XVECEXP (pat, 1, i), 0);
    993  1.1  mrg 	      int shuid = INSN_SHUID (lab);
    994  1.1  mrg 	      if (shuid < min)
    995  1.1  mrg 		{
    996  1.1  mrg 		  min = shuid;
    997  1.1  mrg 		  min_lab = lab;
    998  1.1  mrg 		}
    999  1.1  mrg 	      if (shuid > max)
   1000  1.1  mrg 		{
   1001  1.1  mrg 		  max = shuid;
   1002  1.1  mrg 		  max_lab = lab;
   1003  1.1  mrg 		}
   1004  1.1  mrg 
   1005  1.1  mrg 	      int label_alignment = LABEL_TO_ALIGNMENT (lab).levels[0].log;
   1006  1.1  mrg 	      if (min_align > label_alignment)
   1007  1.1  mrg 		min_align = label_alignment;
   1008  1.1  mrg 	    }
   1009  1.1  mrg 	  XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab);
   1010  1.1  mrg 	  XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab);
   1011  1.1  mrg 	  insn_shuid = INSN_SHUID (insn);
   1012  1.1  mrg 	  rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
   1013  1.1  mrg 	  memset (&flags, 0, sizeof (flags));
   1014  1.1  mrg 	  flags.min_align = min_align;
   1015  1.1  mrg 	  flags.base_after_vec = rel > insn_shuid;
   1016  1.1  mrg 	  flags.min_after_vec  = min > insn_shuid;
   1017  1.1  mrg 	  flags.max_after_vec  = max > insn_shuid;
   1018  1.1  mrg 	  flags.min_after_base = min > rel;
   1019  1.1  mrg 	  flags.max_after_base = max > rel;
   1020  1.1  mrg 	  ADDR_DIFF_VEC_FLAGS (pat) = flags;
   1021  1.1  mrg 
   1022  1.1  mrg 	  if (increasing)
   1023  1.1  mrg 	    PUT_MODE (pat, CASE_VECTOR_SHORTEN_MODE (0, 0, pat));
   1024  1.1  mrg 	}
   1025  1.1  mrg     }
   1026  1.1  mrg #endif /* CASE_VECTOR_SHORTEN_MODE */
   1027  1.1  mrg 
   1028  1.1  mrg   /* Compute initial lengths, addresses, and varying flags for each insn.  */
   1029  1.1  mrg   int (*length_fun) (rtx_insn *) = increasing ? insn_min_length : insn_default_length;
   1030  1.1  mrg 
   1031  1.1  mrg   for (insn_current_address = 0, insn = first;
   1032  1.1  mrg        insn != 0;
   1033  1.1  mrg        insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
   1034  1.1  mrg     {
   1035  1.1  mrg       uid = INSN_UID (insn);
   1036  1.1  mrg 
   1037  1.1  mrg       insn_lengths[uid] = 0;
   1038  1.1  mrg 
   1039  1.1  mrg       if (LABEL_P (insn))
   1040  1.1  mrg 	{
   1041  1.1  mrg 	  int log = LABEL_TO_ALIGNMENT (insn).levels[0].log;
   1042  1.1  mrg 	  if (log)
   1043  1.1  mrg 	    {
   1044  1.1  mrg 	      int align = 1 << log;
   1045  1.1  mrg 	      int new_address = (insn_current_address + align - 1) & -align;
   1046  1.1  mrg 	      insn_lengths[uid] = new_address - insn_current_address;
   1047  1.1  mrg 	    }
   1048  1.1  mrg 	}
   1049  1.1  mrg 
   1050  1.1  mrg       INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
   1051  1.1  mrg 
   1052  1.1  mrg       if (NOTE_P (insn) || BARRIER_P (insn)
   1053  1.1  mrg 	  || LABEL_P (insn) || DEBUG_INSN_P (insn))
   1054  1.1  mrg 	continue;
   1055  1.1  mrg       if (insn->deleted ())
   1056  1.1  mrg 	continue;
   1057  1.1  mrg 
   1058  1.1  mrg       body = PATTERN (insn);
   1059  1.1  mrg       if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn))
   1060  1.1  mrg 	{
   1061  1.1  mrg 	  /* This only takes room if read-only data goes into the text
   1062  1.1  mrg 	     section.  */
   1063  1.1  mrg 	  if (JUMP_TABLES_IN_TEXT_SECTION
   1064  1.1  mrg 	      || readonly_data_section == text_section)
   1065  1.1  mrg 	    insn_lengths[uid] = (XVECLEN (body,
   1066  1.1  mrg 					  GET_CODE (body) == ADDR_DIFF_VEC)
   1067  1.1  mrg 				 * GET_MODE_SIZE (table->get_data_mode ()));
   1068  1.1  mrg 	  /* Alignment is handled by ADDR_VEC_ALIGN.  */
   1069  1.1  mrg 	}
   1070  1.1  mrg       else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
   1071  1.1  mrg 	insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn);
   1072  1.1  mrg       else if (rtx_sequence *body_seq = dyn_cast <rtx_sequence *> (body))
   1073  1.1  mrg 	{
   1074  1.1  mrg 	  int i;
   1075  1.1  mrg 	  int const_delay_slots;
   1076  1.1  mrg 	  if (DELAY_SLOTS)
   1077  1.1  mrg 	    const_delay_slots = const_num_delay_slots (body_seq->insn (0));
   1078  1.1  mrg 	  else
   1079  1.1  mrg 	    const_delay_slots = 0;
   1080  1.1  mrg 
   1081  1.1  mrg 	  int (*inner_length_fun) (rtx_insn *)
   1082  1.1  mrg 	    = const_delay_slots ? length_fun : insn_default_length;
   1083  1.1  mrg 	  /* Inside a delay slot sequence, we do not do any branch shortening
   1084  1.1  mrg 	     if the shortening could change the number of delay slots
   1085  1.1  mrg 	     of the branch.  */
   1086  1.1  mrg 	  for (i = 0; i < body_seq->len (); i++)
   1087  1.1  mrg 	    {
   1088  1.1  mrg 	      rtx_insn *inner_insn = body_seq->insn (i);
   1089  1.1  mrg 	      int inner_uid = INSN_UID (inner_insn);
   1090  1.1  mrg 	      int inner_length;
   1091  1.1  mrg 
   1092  1.1  mrg 	      if (GET_CODE (PATTERN (inner_insn)) == ASM_INPUT
   1093  1.1  mrg 		  || asm_noperands (PATTERN (inner_insn)) >= 0)
   1094  1.1  mrg 		inner_length = (asm_insn_count (PATTERN (inner_insn))
   1095  1.1  mrg 				* insn_default_length (inner_insn));
   1096  1.1  mrg 	      else
   1097  1.1  mrg 		inner_length = inner_length_fun (inner_insn);
   1098  1.1  mrg 
   1099  1.1  mrg 	      insn_lengths[inner_uid] = inner_length;
   1100  1.1  mrg 	      if (const_delay_slots)
   1101  1.1  mrg 		{
   1102  1.1  mrg 		  if ((varying_length[inner_uid]
   1103  1.1  mrg 		       = insn_variable_length_p (inner_insn)) != 0)
   1104  1.1  mrg 		    varying_length[uid] = 1;
   1105  1.1  mrg 		  INSN_ADDRESSES (inner_uid) = (insn_current_address
   1106  1.1  mrg 						+ insn_lengths[uid]);
   1107  1.1  mrg 		}
   1108  1.1  mrg 	      else
   1109  1.1  mrg 		varying_length[inner_uid] = 0;
   1110  1.1  mrg 	      insn_lengths[uid] += inner_length;
   1111  1.1  mrg 	    }
   1112  1.1  mrg 	}
   1113  1.1  mrg       else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER)
   1114  1.1  mrg 	{
   1115  1.1  mrg 	  insn_lengths[uid] = length_fun (insn);
   1116  1.1  mrg 	  varying_length[uid] = insn_variable_length_p (insn);
   1117  1.1  mrg 	}
   1118  1.1  mrg 
   1119  1.1  mrg       /* If needed, do any adjustment.  */
   1120  1.1  mrg #ifdef ADJUST_INSN_LENGTH
   1121  1.1  mrg       ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
   1122  1.1  mrg       if (insn_lengths[uid] < 0)
   1123  1.1  mrg 	fatal_insn ("negative insn length", insn);
   1124  1.1  mrg #endif
   1125  1.1  mrg     }
   1126  1.1  mrg 
   1127  1.1  mrg   /* Now loop over all the insns finding varying length insns.  For each,
   1128  1.1  mrg      get the current insn length.  If it has changed, reflect the change.
   1129  1.1  mrg      When nothing changes for a full pass, we are done.  */
   1130  1.1  mrg 
   1131  1.1  mrg   while (something_changed)
   1132  1.1  mrg     {
   1133  1.1  mrg       something_changed = 0;
   1134  1.1  mrg       insn_current_align = MAX_CODE_ALIGN - 1;
   1135  1.1  mrg       for (insn_current_address = 0, insn = first;
   1136  1.1  mrg 	   insn != 0;
   1137  1.1  mrg 	   insn = NEXT_INSN (insn))
   1138  1.1  mrg 	{
   1139  1.1  mrg 	  int new_length;
   1140  1.1  mrg #ifdef ADJUST_INSN_LENGTH
   1141  1.1  mrg 	  int tmp_length;
   1142  1.1  mrg #endif
   1143  1.1  mrg 	  int length_align;
   1144  1.1  mrg 
   1145  1.1  mrg 	  uid = INSN_UID (insn);
   1146  1.1  mrg 
   1147  1.1  mrg 	  if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
   1148  1.1  mrg 	    {
   1149  1.1  mrg 	      int log = LABEL_TO_ALIGNMENT (label).levels[0].log;
   1150  1.1  mrg 
   1151  1.1  mrg #ifdef CASE_VECTOR_SHORTEN_MODE
   1152  1.1  mrg 	      /* If the mode of a following jump table was changed, we
   1153  1.1  mrg 		 may need to update the alignment of this label.  */
   1154  1.1  mrg 
   1155  1.1  mrg 	      if (JUMP_TABLES_IN_TEXT_SECTION
   1156  1.1  mrg 		  || readonly_data_section == text_section)
   1157  1.1  mrg 		{
   1158  1.1  mrg 		  rtx_jump_table_data *table = jump_table_for_label (label);
   1159  1.1  mrg 		  if (table)
   1160  1.1  mrg 		    {
   1161  1.1  mrg 		      int newlog = ADDR_VEC_ALIGN (table);
   1162  1.1  mrg 		      if (newlog != log)
   1163  1.1  mrg 			{
   1164  1.1  mrg 			  log = newlog;
   1165  1.1  mrg 			  LABEL_TO_ALIGNMENT (insn) = log;
   1166  1.1  mrg 			  something_changed = 1;
   1167  1.1  mrg 			}
   1168  1.1  mrg 		    }
   1169  1.1  mrg 		}
   1170  1.1  mrg #endif
   1171  1.1  mrg 
   1172  1.1  mrg 	      if (log > insn_current_align)
   1173  1.1  mrg 		{
   1174  1.1  mrg 		  int align = 1 << log;
   1175  1.1  mrg 		  int new_address= (insn_current_address + align - 1) & -align;
   1176  1.1  mrg 		  insn_lengths[uid] = new_address - insn_current_address;
   1177  1.1  mrg 		  insn_current_align = log;
   1178  1.1  mrg 		  insn_current_address = new_address;
   1179  1.1  mrg 		}
   1180  1.1  mrg 	      else
   1181  1.1  mrg 		insn_lengths[uid] = 0;
   1182  1.1  mrg 	      INSN_ADDRESSES (uid) = insn_current_address;
   1183  1.1  mrg 	      continue;
   1184  1.1  mrg 	    }
   1185  1.1  mrg 
   1186  1.1  mrg 	  length_align = INSN_LENGTH_ALIGNMENT (insn);
   1187  1.1  mrg 	  if (length_align < insn_current_align)
   1188  1.1  mrg 	    insn_current_align = length_align;
   1189  1.1  mrg 
   1190  1.1  mrg 	  insn_last_address = INSN_ADDRESSES (uid);
   1191  1.1  mrg 	  INSN_ADDRESSES (uid) = insn_current_address;
   1192  1.1  mrg 
   1193  1.1  mrg #ifdef CASE_VECTOR_SHORTEN_MODE
   1194  1.1  mrg 	  if (optimize
   1195  1.1  mrg 	      && JUMP_TABLE_DATA_P (insn)
   1196  1.1  mrg 	      && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
   1197  1.1  mrg 	    {
   1198  1.1  mrg 	      rtx_jump_table_data *table = as_a <rtx_jump_table_data *> (insn);
   1199  1.1  mrg 	      rtx body = PATTERN (insn);
   1200  1.1  mrg 	      int old_length = insn_lengths[uid];
   1201  1.1  mrg 	      rtx_insn *rel_lab =
   1202  1.1  mrg 		safe_as_a <rtx_insn *> (XEXP (XEXP (body, 0), 0));
   1203  1.1  mrg 	      rtx min_lab = XEXP (XEXP (body, 2), 0);
   1204  1.1  mrg 	      rtx max_lab = XEXP (XEXP (body, 3), 0);
   1205  1.1  mrg 	      int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab));
   1206  1.1  mrg 	      int min_addr = INSN_ADDRESSES (INSN_UID (min_lab));
   1207  1.1  mrg 	      int max_addr = INSN_ADDRESSES (INSN_UID (max_lab));
   1208  1.1  mrg 	      rtx_insn *prev;
   1209  1.1  mrg 	      int rel_align = 0;
   1210  1.1  mrg 	      addr_diff_vec_flags flags;
   1211  1.1  mrg 	      scalar_int_mode vec_mode;
   1212  1.1  mrg 
   1213  1.1  mrg 	      /* Avoid automatic aggregate initialization.  */
   1214  1.1  mrg 	      flags = ADDR_DIFF_VEC_FLAGS (body);
   1215  1.1  mrg 
   1216  1.1  mrg 	      /* Try to find a known alignment for rel_lab.  */
   1217  1.1  mrg 	      for (prev = rel_lab;
   1218  1.1  mrg 		   prev
   1219  1.1  mrg 		   && ! insn_lengths[INSN_UID (prev)]
   1220  1.1  mrg 		   && ! (varying_length[INSN_UID (prev)] & 1);
   1221  1.1  mrg 		   prev = PREV_INSN (prev))
   1222  1.1  mrg 		if (varying_length[INSN_UID (prev)] & 2)
   1223  1.1  mrg 		  {
   1224  1.1  mrg 		    rel_align = LABEL_TO_ALIGNMENT (prev).levels[0].log;
   1225  1.1  mrg 		    break;
   1226  1.1  mrg 		  }
   1227  1.1  mrg 
   1228  1.1  mrg 	      /* See the comment on addr_diff_vec_flags in rtl.h for the
   1229  1.1  mrg 		 meaning of the flags values.  base: REL_LAB   vec: INSN  */
   1230  1.1  mrg 	      /* Anything after INSN has still addresses from the last
   1231  1.1  mrg 		 pass; adjust these so that they reflect our current
   1232  1.1  mrg 		 estimate for this pass.  */
   1233  1.1  mrg 	      if (flags.base_after_vec)
   1234  1.1  mrg 		rel_addr += insn_current_address - insn_last_address;
   1235  1.1  mrg 	      if (flags.min_after_vec)
   1236  1.1  mrg 		min_addr += insn_current_address - insn_last_address;
   1237  1.1  mrg 	      if (flags.max_after_vec)
   1238  1.1  mrg 		max_addr += insn_current_address - insn_last_address;
   1239  1.1  mrg 	      /* We want to know the worst case, i.e. lowest possible value
   1240  1.1  mrg 		 for the offset of MIN_LAB.  If MIN_LAB is after REL_LAB,
   1241  1.1  mrg 		 its offset is positive, and we have to be wary of code shrink;
   1242  1.1  mrg 		 otherwise, it is negative, and we have to be vary of code
   1243  1.1  mrg 		 size increase.  */
   1244  1.1  mrg 	      if (flags.min_after_base)
   1245  1.1  mrg 		{
   1246  1.1  mrg 		  /* If INSN is between REL_LAB and MIN_LAB, the size
   1247  1.1  mrg 		     changes we are about to make can change the alignment
   1248  1.1  mrg 		     within the observed offset, therefore we have to break
   1249  1.1  mrg 		     it up into two parts that are independent.  */
   1250  1.1  mrg 		  if (! flags.base_after_vec && flags.min_after_vec)
   1251  1.1  mrg 		    {
   1252  1.1  mrg 		      min_addr -= align_fuzz (rel_lab, insn, rel_align, 0);
   1253  1.1  mrg 		      min_addr -= align_fuzz (insn, min_lab, 0, 0);
   1254  1.1  mrg 		    }
   1255  1.1  mrg 		  else
   1256  1.1  mrg 		    min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0);
   1257  1.1  mrg 		}
   1258  1.1  mrg 	      else
   1259  1.1  mrg 		{
   1260  1.1  mrg 		  if (flags.base_after_vec && ! flags.min_after_vec)
   1261  1.1  mrg 		    {
   1262  1.1  mrg 		      min_addr -= align_fuzz (min_lab, insn, 0, ~0);
   1263  1.1  mrg 		      min_addr -= align_fuzz (insn, rel_lab, 0, ~0);
   1264  1.1  mrg 		    }
   1265  1.1  mrg 		  else
   1266  1.1  mrg 		    min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0);
   1267  1.1  mrg 		}
   1268  1.1  mrg 	      /* Likewise, determine the highest lowest possible value
   1269  1.1  mrg 		 for the offset of MAX_LAB.  */
   1270  1.1  mrg 	      if (flags.max_after_base)
   1271  1.1  mrg 		{
   1272  1.1  mrg 		  if (! flags.base_after_vec && flags.max_after_vec)
   1273  1.1  mrg 		    {
   1274  1.1  mrg 		      max_addr += align_fuzz (rel_lab, insn, rel_align, ~0);
   1275  1.1  mrg 		      max_addr += align_fuzz (insn, max_lab, 0, ~0);
   1276  1.1  mrg 		    }
   1277  1.1  mrg 		  else
   1278  1.1  mrg 		    max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0);
   1279  1.1  mrg 		}
   1280  1.1  mrg 	      else
   1281  1.1  mrg 		{
   1282  1.1  mrg 		  if (flags.base_after_vec && ! flags.max_after_vec)
   1283  1.1  mrg 		    {
   1284  1.1  mrg 		      max_addr += align_fuzz (max_lab, insn, 0, 0);
   1285  1.1  mrg 		      max_addr += align_fuzz (insn, rel_lab, 0, 0);
   1286  1.1  mrg 		    }
   1287  1.1  mrg 		  else
   1288  1.1  mrg 		    max_addr += align_fuzz (max_lab, rel_lab, 0, 0);
   1289  1.1  mrg 		}
   1290  1.1  mrg 	      vec_mode = CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
   1291  1.1  mrg 						   max_addr - rel_addr, body);
   1292  1.1  mrg 	      if (!increasing
   1293  1.1  mrg 		  || (GET_MODE_SIZE (vec_mode)
   1294  1.1  mrg 		      >= GET_MODE_SIZE (table->get_data_mode ())))
   1295  1.1  mrg 		PUT_MODE (body, vec_mode);
   1296  1.1  mrg 	      if (JUMP_TABLES_IN_TEXT_SECTION
   1297  1.1  mrg 		  || readonly_data_section == text_section)
   1298  1.1  mrg 		{
   1299  1.1  mrg 		  insn_lengths[uid]
   1300  1.1  mrg 		    = (XVECLEN (body, 1)
   1301  1.1  mrg 		       * GET_MODE_SIZE (table->get_data_mode ()));
   1302  1.1  mrg 		  insn_current_address += insn_lengths[uid];
   1303  1.1  mrg 		  if (insn_lengths[uid] != old_length)
   1304  1.1  mrg 		    something_changed = 1;
   1305  1.1  mrg 		}
   1306  1.1  mrg 
   1307  1.1  mrg 	      continue;
   1308  1.1  mrg 	    }
   1309  1.1  mrg #endif /* CASE_VECTOR_SHORTEN_MODE */
   1310  1.1  mrg 
   1311  1.1  mrg 	  if (! (varying_length[uid]))
   1312  1.1  mrg 	    {
   1313  1.1  mrg 	      if (NONJUMP_INSN_P (insn)
   1314  1.1  mrg 		  && GET_CODE (PATTERN (insn)) == SEQUENCE)
   1315  1.1  mrg 		{
   1316  1.1  mrg 		  int i;
   1317  1.1  mrg 
   1318  1.1  mrg 		  body = PATTERN (insn);
   1319  1.1  mrg 		  for (i = 0; i < XVECLEN (body, 0); i++)
   1320  1.1  mrg 		    {
   1321  1.1  mrg 		      rtx inner_insn = XVECEXP (body, 0, i);
   1322  1.1  mrg 		      int inner_uid = INSN_UID (inner_insn);
   1323  1.1  mrg 
   1324  1.1  mrg 		      INSN_ADDRESSES (inner_uid) = insn_current_address;
   1325  1.1  mrg 
   1326  1.1  mrg 		      insn_current_address += insn_lengths[inner_uid];
   1327  1.1  mrg 		    }
   1328  1.1  mrg 		}
   1329  1.1  mrg 	      else
   1330  1.1  mrg 		insn_current_address += insn_lengths[uid];
   1331  1.1  mrg 
   1332  1.1  mrg 	      continue;
   1333  1.1  mrg 	    }
   1334  1.1  mrg 
   1335  1.1  mrg 	  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
   1336  1.1  mrg 	    {
   1337  1.1  mrg 	      rtx_sequence *seqn = as_a <rtx_sequence *> (PATTERN (insn));
   1338  1.1  mrg 	      int i;
   1339  1.1  mrg 
   1340  1.1  mrg 	      body = PATTERN (insn);
   1341  1.1  mrg 	      new_length = 0;
   1342  1.1  mrg 	      for (i = 0; i < seqn->len (); i++)
   1343  1.1  mrg 		{
   1344  1.1  mrg 		  rtx_insn *inner_insn = seqn->insn (i);
   1345  1.1  mrg 		  int inner_uid = INSN_UID (inner_insn);
   1346  1.1  mrg 		  int inner_length;
   1347  1.1  mrg 
   1348  1.1  mrg 		  INSN_ADDRESSES (inner_uid) = insn_current_address;
   1349  1.1  mrg 
   1350  1.1  mrg 		  /* insn_current_length returns 0 for insns with a
   1351  1.1  mrg 		     non-varying length.  */
   1352  1.1  mrg 		  if (! varying_length[inner_uid])
   1353  1.1  mrg 		    inner_length = insn_lengths[inner_uid];
   1354  1.1  mrg 		  else
   1355  1.1  mrg 		    inner_length = insn_current_length (inner_insn);
   1356  1.1  mrg 
   1357  1.1  mrg 		  if (inner_length != insn_lengths[inner_uid])
   1358  1.1  mrg 		    {
   1359  1.1  mrg 		      if (!increasing || inner_length > insn_lengths[inner_uid])
   1360  1.1  mrg 			{
   1361  1.1  mrg 			  insn_lengths[inner_uid] = inner_length;
   1362  1.1  mrg 			  something_changed = 1;
   1363  1.1  mrg 			}
   1364  1.1  mrg 		      else
   1365  1.1  mrg 			inner_length = insn_lengths[inner_uid];
   1366  1.1  mrg 		    }
   1367  1.1  mrg 		  insn_current_address += inner_length;
   1368  1.1  mrg 		  new_length += inner_length;
   1369  1.1  mrg 		}
   1370  1.1  mrg 	    }
   1371  1.1  mrg 	  else
   1372  1.1  mrg 	    {
   1373  1.1  mrg 	      new_length = insn_current_length (insn);
   1374  1.1  mrg 	      insn_current_address += new_length;
   1375  1.1  mrg 	    }
   1376  1.1  mrg 
   1377  1.1  mrg #ifdef ADJUST_INSN_LENGTH
   1378  1.1  mrg 	  /* If needed, do any adjustment.  */
   1379  1.1  mrg 	  tmp_length = new_length;
   1380  1.1  mrg 	  ADJUST_INSN_LENGTH (insn, new_length);
   1381  1.1  mrg 	  insn_current_address += (new_length - tmp_length);
   1382  1.1  mrg #endif
   1383  1.1  mrg 
   1384  1.1  mrg 	  if (new_length != insn_lengths[uid]
   1385  1.1  mrg 	      && (!increasing || new_length > insn_lengths[uid]))
   1386  1.1  mrg 	    {
   1387  1.1  mrg 	      insn_lengths[uid] = new_length;
   1388  1.1  mrg 	      something_changed = 1;
   1389  1.1  mrg 	    }
   1390  1.1  mrg 	  else
   1391  1.1  mrg 	    insn_current_address += insn_lengths[uid] - new_length;
   1392  1.1  mrg 	}
   1393  1.1  mrg       /* For a non-optimizing compile, do only a single pass.  */
   1394  1.1  mrg       if (!increasing)
   1395  1.1  mrg 	break;
   1396  1.1  mrg     }
   1397  1.1  mrg   crtl->max_insn_address = insn_current_address;
   1398  1.1  mrg   free (varying_length);
   1399  1.1  mrg }
   1400  1.1  mrg 
   1401  1.1  mrg /* Given the body of an INSN known to be generated by an ASM statement, return
   1402  1.1  mrg    the number of machine instructions likely to be generated for this insn.
   1403  1.1  mrg    This is used to compute its length.  */
   1404  1.1  mrg 
   1405  1.1  mrg static int
   1406  1.1  mrg asm_insn_count (rtx body)
   1407  1.1  mrg {
   1408  1.1  mrg   const char *templ;
   1409  1.1  mrg 
   1410  1.1  mrg   if (GET_CODE (body) == ASM_INPUT)
   1411  1.1  mrg     templ = XSTR (body, 0);
   1412  1.1  mrg   else
   1413  1.1  mrg     templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
   1414  1.1  mrg 
   1415  1.1  mrg   return asm_str_count (templ);
   1416  1.1  mrg }
   1417  1.1  mrg 
   1418  1.1  mrg /* Return the number of machine instructions likely to be generated for the
   1419  1.1  mrg    inline-asm template. */
   1420  1.1  mrg int
   1421  1.1  mrg asm_str_count (const char *templ)
   1422  1.1  mrg {
   1423  1.1  mrg   int count = 1;
   1424  1.1  mrg 
   1425  1.1  mrg   if (!*templ)
   1426  1.1  mrg     return 0;
   1427  1.1  mrg 
   1428  1.1  mrg   for (; *templ; templ++)
   1429  1.1  mrg     if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ)
   1430  1.1  mrg 	|| *templ == '\n')
   1431  1.1  mrg       count++;
   1432  1.1  mrg 
   1433  1.1  mrg   return count;
   1434  1.1  mrg }
   1435  1.1  mrg 
   1436  1.1  mrg /* Return true if DWARF2 debug info can be emitted for DECL.  */
   1438  1.1  mrg 
   1439  1.1  mrg static bool
   1440  1.1  mrg dwarf2_debug_info_emitted_p (tree decl)
   1441  1.1  mrg {
   1442  1.1  mrg   /* When DWARF2 debug info is not generated internally.  */
   1443  1.1  mrg   if (!dwarf_debuginfo_p () && !dwarf_based_debuginfo_p ())
   1444  1.1  mrg     return false;
   1445  1.1  mrg 
   1446  1.1  mrg   if (DECL_IGNORED_P (decl))
   1447  1.1  mrg     return false;
   1448  1.1  mrg 
   1449  1.1  mrg   return true;
   1450  1.1  mrg }
   1451  1.1  mrg 
   1452  1.1  mrg /* Return scope resulting from combination of S1 and S2.  */
   1453  1.1  mrg static tree
   1454  1.1  mrg choose_inner_scope (tree s1, tree s2)
   1455  1.1  mrg {
   1456  1.1  mrg    if (!s1)
   1457  1.1  mrg      return s2;
   1458  1.1  mrg    if (!s2)
   1459  1.1  mrg      return s1;
   1460  1.1  mrg    if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2))
   1461  1.1  mrg      return s1;
   1462  1.1  mrg    return s2;
   1463  1.1  mrg }
   1464  1.1  mrg 
   1465  1.1  mrg /* Emit lexical block notes needed to change scope from S1 to S2.  */
   1466  1.1  mrg 
   1467  1.1  mrg static void
   1468  1.1  mrg change_scope (rtx_insn *orig_insn, tree s1, tree s2)
   1469  1.1  mrg {
   1470  1.1  mrg   rtx_insn *insn = orig_insn;
   1471  1.1  mrg   tree com = NULL_TREE;
   1472  1.1  mrg   tree ts1 = s1, ts2 = s2;
   1473  1.1  mrg   tree s;
   1474  1.1  mrg 
   1475  1.1  mrg   while (ts1 != ts2)
   1476  1.1  mrg     {
   1477  1.1  mrg       gcc_assert (ts1 && ts2);
   1478  1.1  mrg       if (BLOCK_NUMBER (ts1) > BLOCK_NUMBER (ts2))
   1479  1.1  mrg 	ts1 = BLOCK_SUPERCONTEXT (ts1);
   1480  1.1  mrg       else if (BLOCK_NUMBER (ts1) < BLOCK_NUMBER (ts2))
   1481  1.1  mrg 	ts2 = BLOCK_SUPERCONTEXT (ts2);
   1482  1.1  mrg       else
   1483  1.1  mrg 	{
   1484  1.1  mrg 	  ts1 = BLOCK_SUPERCONTEXT (ts1);
   1485  1.1  mrg 	  ts2 = BLOCK_SUPERCONTEXT (ts2);
   1486  1.1  mrg 	}
   1487  1.1  mrg     }
   1488  1.1  mrg   com = ts1;
   1489  1.1  mrg 
   1490  1.1  mrg   /* Close scopes.  */
   1491  1.1  mrg   s = s1;
   1492  1.1  mrg   while (s != com)
   1493  1.1  mrg     {
   1494  1.1  mrg       rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
   1495  1.1  mrg       NOTE_BLOCK (note) = s;
   1496  1.1  mrg       s = BLOCK_SUPERCONTEXT (s);
   1497  1.1  mrg     }
   1498  1.1  mrg 
   1499  1.1  mrg   /* Open scopes.  */
   1500  1.1  mrg   s = s2;
   1501  1.1  mrg   while (s != com)
   1502  1.1  mrg     {
   1503  1.1  mrg       insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn);
   1504  1.1  mrg       NOTE_BLOCK (insn) = s;
   1505  1.1  mrg       s = BLOCK_SUPERCONTEXT (s);
   1506  1.1  mrg     }
   1507  1.1  mrg }
   1508  1.1  mrg 
   1509  1.1  mrg /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
   1510  1.1  mrg    on the scope tree and the newly reordered instructions.  */
   1511  1.1  mrg 
   1512  1.1  mrg static void
   1513  1.1  mrg reemit_insn_block_notes (void)
   1514  1.1  mrg {
   1515  1.1  mrg   tree cur_block = DECL_INITIAL (cfun->decl);
   1516  1.1  mrg   rtx_insn *insn;
   1517  1.1  mrg 
   1518  1.1  mrg   insn = get_insns ();
   1519  1.1  mrg   for (; insn; insn = NEXT_INSN (insn))
   1520  1.1  mrg     {
   1521  1.1  mrg       tree this_block;
   1522  1.1  mrg 
   1523  1.1  mrg       /* Prevent lexical blocks from straddling section boundaries.  */
   1524  1.1  mrg       if (NOTE_P (insn))
   1525  1.1  mrg 	switch (NOTE_KIND (insn))
   1526  1.1  mrg 	  {
   1527  1.1  mrg 	  case NOTE_INSN_SWITCH_TEXT_SECTIONS:
   1528  1.1  mrg 	    {
   1529  1.1  mrg 	      for (tree s = cur_block; s != DECL_INITIAL (cfun->decl);
   1530  1.1  mrg 		   s = BLOCK_SUPERCONTEXT (s))
   1531  1.1  mrg 		{
   1532  1.1  mrg 		  rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
   1533  1.1  mrg 		  NOTE_BLOCK (note) = s;
   1534  1.1  mrg 		  note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn);
   1535  1.1  mrg 		  NOTE_BLOCK (note) = s;
   1536  1.1  mrg 		}
   1537  1.1  mrg 	    }
   1538  1.1  mrg 	    break;
   1539  1.1  mrg 
   1540  1.1  mrg 	  case NOTE_INSN_BEGIN_STMT:
   1541  1.1  mrg 	  case NOTE_INSN_INLINE_ENTRY:
   1542  1.1  mrg 	    this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn));
   1543  1.1  mrg 	    goto set_cur_block_to_this_block;
   1544  1.1  mrg 
   1545  1.1  mrg 	  default:
   1546  1.1  mrg 	    continue;
   1547  1.1  mrg 	}
   1548  1.1  mrg 
   1549  1.1  mrg       if (!active_insn_p (insn))
   1550  1.1  mrg         continue;
   1551  1.1  mrg 
   1552  1.1  mrg       /* Avoid putting scope notes between jump table and its label.  */
   1553  1.1  mrg       if (JUMP_TABLE_DATA_P (insn))
   1554  1.1  mrg 	continue;
   1555  1.1  mrg 
   1556  1.1  mrg       this_block = insn_scope (insn);
   1557  1.1  mrg       /* For sequences compute scope resulting from merging all scopes
   1558  1.1  mrg 	 of instructions nested inside.  */
   1559  1.1  mrg       if (rtx_sequence *body = dyn_cast <rtx_sequence *> (PATTERN (insn)))
   1560  1.1  mrg 	{
   1561  1.1  mrg 	  int i;
   1562  1.1  mrg 
   1563  1.1  mrg 	  this_block = NULL;
   1564  1.1  mrg 	  for (i = 0; i < body->len (); i++)
   1565  1.1  mrg 	    this_block = choose_inner_scope (this_block,
   1566  1.1  mrg 					     insn_scope (body->insn (i)));
   1567  1.1  mrg 	}
   1568  1.1  mrg     set_cur_block_to_this_block:
   1569  1.1  mrg       if (! this_block)
   1570  1.1  mrg 	{
   1571  1.1  mrg 	  if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
   1572  1.1  mrg 	    continue;
   1573  1.1  mrg 	  else
   1574  1.1  mrg 	    this_block = DECL_INITIAL (cfun->decl);
   1575  1.1  mrg 	}
   1576  1.1  mrg 
   1577  1.1  mrg       if (this_block != cur_block)
   1578  1.1  mrg 	{
   1579  1.1  mrg 	  change_scope (insn, cur_block, this_block);
   1580  1.1  mrg 	  cur_block = this_block;
   1581  1.1  mrg 	}
   1582  1.1  mrg     }
   1583  1.1  mrg 
   1584  1.1  mrg   /* change_scope emits before the insn, not after.  */
   1585  1.1  mrg   rtx_note *note = emit_note (NOTE_INSN_DELETED);
   1586  1.1  mrg   change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
   1587  1.1  mrg   delete_insn (note);
   1588  1.1  mrg 
   1589  1.1  mrg   reorder_blocks ();
   1590  1.1  mrg }
   1591  1.1  mrg 
   1592  1.1  mrg static const char *some_local_dynamic_name;
   1593  1.1  mrg 
   1594  1.1  mrg /* Locate some local-dynamic symbol still in use by this function
   1595  1.1  mrg    so that we can print its name in local-dynamic base patterns.
   1596  1.1  mrg    Return null if there are no local-dynamic references.  */
   1597  1.1  mrg 
   1598  1.1  mrg const char *
   1599  1.1  mrg get_some_local_dynamic_name ()
   1600  1.1  mrg {
   1601  1.1  mrg   subrtx_iterator::array_type array;
   1602  1.1  mrg   rtx_insn *insn;
   1603  1.1  mrg 
   1604  1.1  mrg   if (some_local_dynamic_name)
   1605  1.1  mrg     return some_local_dynamic_name;
   1606  1.1  mrg 
   1607  1.1  mrg   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
   1608  1.1  mrg     if (NONDEBUG_INSN_P (insn))
   1609  1.1  mrg       FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
   1610  1.1  mrg 	{
   1611  1.1  mrg 	  const_rtx x = *iter;
   1612  1.1  mrg 	  if (GET_CODE (x) == SYMBOL_REF)
   1613  1.1  mrg 	    {
   1614  1.1  mrg 	      if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
   1615  1.1  mrg 		return some_local_dynamic_name = XSTR (x, 0);
   1616  1.1  mrg 	      if (CONSTANT_POOL_ADDRESS_P (x))
   1617  1.1  mrg 		iter.substitute (get_pool_constant (x));
   1618  1.1  mrg 	    }
   1619  1.1  mrg 	}
   1620  1.1  mrg 
   1621  1.1  mrg   return 0;
   1622  1.1  mrg }
   1623  1.1  mrg 
   1624  1.1  mrg /* Arrange for us to emit a source location note before any further
   1625  1.1  mrg    real insns or section changes, by setting the SEEN_NEXT_VIEW bit in
   1626  1.1  mrg    *SEEN, as long as we are keeping track of location views.  The bit
   1627  1.1  mrg    indicates we have referenced the next view at the current PC, so we
   1628  1.1  mrg    have to emit it.  This should be called next to the var_location
   1629  1.1  mrg    debug hook.  */
   1630  1.1  mrg 
   1631  1.1  mrg static inline void
   1632  1.1  mrg set_next_view_needed (int *seen)
   1633  1.1  mrg {
   1634  1.1  mrg   if (debug_variable_location_views)
   1635  1.1  mrg     *seen |= SEEN_NEXT_VIEW;
   1636  1.1  mrg }
   1637  1.1  mrg 
   1638  1.1  mrg /* Clear the flag in *SEEN indicating we need to emit the next view.
   1639  1.1  mrg    This should be called next to the source_line debug hook.  */
   1640  1.1  mrg 
   1641  1.1  mrg static inline void
   1642  1.1  mrg clear_next_view_needed (int *seen)
   1643  1.1  mrg {
   1644  1.1  mrg   *seen &= ~SEEN_NEXT_VIEW;
   1645  1.1  mrg }
   1646  1.1  mrg 
   1647  1.1  mrg /* Test whether we have a pending request to emit the next view in
   1648  1.1  mrg    *SEEN, and emit it if needed, clearing the request bit.  */
   1649  1.1  mrg 
   1650  1.1  mrg static inline void
   1651  1.1  mrg maybe_output_next_view (int *seen)
   1652  1.1  mrg {
   1653  1.1  mrg   if ((*seen & SEEN_NEXT_VIEW) != 0)
   1654  1.1  mrg     {
   1655  1.1  mrg       clear_next_view_needed (seen);
   1656  1.1  mrg       (*debug_hooks->source_line) (last_linenum, last_columnnum,
   1657  1.1  mrg 				   last_filename, last_discriminator,
   1658  1.1  mrg 				   false);
   1659  1.1  mrg     }
   1660  1.1  mrg }
   1661  1.1  mrg 
   1662  1.1  mrg /* We want to emit param bindings (before the first begin_stmt) in the
   1663  1.1  mrg    initial view, if we are emitting views.  To that end, we may
   1664  1.1  mrg    consume initial notes in the function, processing them in
   1665  1.1  mrg    final_start_function, before signaling the beginning of the
   1666  1.1  mrg    prologue, rather than in final.
   1667  1.1  mrg 
   1668  1.1  mrg    We don't test whether the DECLs are PARM_DECLs: the assumption is
   1669  1.1  mrg    that there will be a NOTE_INSN_BEGIN_STMT marker before any
   1670  1.1  mrg    non-parameter NOTE_INSN_VAR_LOCATION.  It's ok if the marker is not
   1671  1.1  mrg    there, we'll just have more variable locations bound in the initial
   1672  1.1  mrg    view, which is consistent with their being bound without any code
   1673  1.1  mrg    that would give them a value.  */
   1674  1.1  mrg 
   1675  1.1  mrg static inline bool
   1676  1.1  mrg in_initial_view_p (rtx_insn *insn)
   1677  1.1  mrg {
   1678  1.1  mrg   return (!DECL_IGNORED_P (current_function_decl)
   1679  1.1  mrg 	  && debug_variable_location_views
   1680  1.1  mrg 	  && insn && GET_CODE (insn) == NOTE
   1681  1.1  mrg 	  && (NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
   1682  1.1  mrg 	      || NOTE_KIND (insn) == NOTE_INSN_DELETED));
   1683  1.1  mrg }
   1684  1.1  mrg 
   1685  1.1  mrg /* Output assembler code for the start of a function,
   1686  1.1  mrg    and initialize some of the variables in this file
   1687  1.1  mrg    for the new function.  The label for the function and associated
   1688  1.1  mrg    assembler pseudo-ops have already been output in `assemble_start_function'.
   1689  1.1  mrg 
   1690  1.1  mrg    FIRST is the first insn of the rtl for the function being compiled.
   1691  1.1  mrg    FILE is the file to write assembler code to.
   1692  1.1  mrg    SEEN should be initially set to zero, and it may be updated to
   1693  1.1  mrg    indicate we have references to the next location view, that would
   1694  1.1  mrg    require us to emit it at the current PC.
   1695  1.1  mrg    OPTIMIZE_P is nonzero if we should eliminate redundant
   1696  1.1  mrg      test and compare insns.  */
   1697  1.1  mrg 
   1698  1.1  mrg static void
   1699  1.1  mrg final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
   1700  1.1  mrg 			int optimize_p ATTRIBUTE_UNUSED)
   1701  1.1  mrg {
   1702  1.1  mrg   block_depth = 0;
   1703  1.1  mrg 
   1704  1.1  mrg   this_is_asm_operands = 0;
   1705  1.1  mrg 
   1706  1.1  mrg   need_profile_function = false;
   1707  1.1  mrg 
   1708  1.1  mrg   last_filename = LOCATION_FILE (prologue_location);
   1709  1.1  mrg   last_linenum = LOCATION_LINE (prologue_location);
   1710  1.1  mrg   last_columnnum = LOCATION_COLUMN (prologue_location);
   1711  1.1  mrg   last_discriminator = discriminator = 0;
   1712  1.1  mrg   last_bb_discriminator = bb_discriminator = 0;
   1713  1.1  mrg   force_source_line = false;
   1714  1.1  mrg 
   1715  1.1  mrg   high_block_linenum = high_function_linenum = last_linenum;
   1716  1.1  mrg 
   1717  1.1  mrg   if (flag_sanitize & SANITIZE_ADDRESS)
   1718  1.1  mrg     asan_function_start ();
   1719  1.1  mrg 
   1720  1.1  mrg   rtx_insn *first = *firstp;
   1721  1.1  mrg   if (in_initial_view_p (first))
   1722  1.1  mrg     {
   1723  1.1  mrg       do
   1724  1.1  mrg 	{
   1725  1.1  mrg 	  final_scan_insn (first, file, 0, 0, seen);
   1726  1.1  mrg 	  first = NEXT_INSN (first);
   1727  1.1  mrg 	}
   1728  1.1  mrg       while (in_initial_view_p (first));
   1729  1.1  mrg       *firstp = first;
   1730  1.1  mrg     }
   1731  1.1  mrg 
   1732  1.1  mrg   if (!DECL_IGNORED_P (current_function_decl))
   1733  1.1  mrg     debug_hooks->begin_prologue (last_linenum, last_columnnum,
   1734  1.1  mrg 				 last_filename);
   1735  1.1  mrg 
   1736  1.1  mrg   if (!dwarf2_debug_info_emitted_p (current_function_decl))
   1737  1.1  mrg     dwarf2out_begin_prologue (0, 0, NULL);
   1738  1.1  mrg 
   1739  1.1  mrg   if (DECL_IGNORED_P (current_function_decl) && last_linenum && last_filename)
   1740  1.1  mrg     debug_hooks->set_ignored_loc (last_linenum, last_columnnum, last_filename);
   1741  1.1  mrg 
   1742  1.1  mrg #ifdef LEAF_REG_REMAP
   1743  1.1  mrg   if (crtl->uses_only_leaf_regs)
   1744  1.1  mrg     leaf_renumber_regs (first);
   1745  1.1  mrg #endif
   1746  1.1  mrg 
   1747  1.1  mrg   /* The Sun386i and perhaps other machines don't work right
   1748  1.1  mrg      if the profiling code comes after the prologue.  */
   1749  1.1  mrg   if (targetm.profile_before_prologue () && crtl->profile)
   1750  1.1  mrg     {
   1751  1.1  mrg       if (targetm.asm_out.function_prologue == default_function_pro_epilogue
   1752  1.1  mrg 	  && targetm.have_prologue ())
   1753  1.1  mrg 	{
   1754  1.1  mrg 	  rtx_insn *insn;
   1755  1.1  mrg 	  for (insn = first; insn; insn = NEXT_INSN (insn))
   1756  1.1  mrg 	    if (!NOTE_P (insn))
   1757  1.1  mrg 	      {
   1758  1.1  mrg 		insn = NULL;
   1759  1.1  mrg 		break;
   1760  1.1  mrg 	      }
   1761  1.1  mrg 	    else if (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK
   1762  1.1  mrg 		     || NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
   1763  1.1  mrg 	      break;
   1764  1.1  mrg 	    else if (NOTE_KIND (insn) == NOTE_INSN_DELETED
   1765  1.1  mrg 		     || NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
   1766  1.1  mrg 	      continue;
   1767  1.1  mrg 	    else
   1768  1.1  mrg 	      {
   1769  1.1  mrg 		insn = NULL;
   1770  1.1  mrg 		break;
   1771  1.1  mrg 	      }
   1772  1.1  mrg 
   1773  1.1  mrg 	  if (insn)
   1774  1.1  mrg 	    need_profile_function = true;
   1775  1.1  mrg 	  else
   1776  1.1  mrg 	    profile_function (file);
   1777  1.1  mrg 	}
   1778  1.1  mrg       else
   1779  1.1  mrg 	profile_function (file);
   1780  1.1  mrg     }
   1781  1.1  mrg 
   1782  1.1  mrg   /* If debugging, assign block numbers to all of the blocks in this
   1783  1.1  mrg      function.  */
   1784  1.1  mrg   if (write_symbols)
   1785  1.1  mrg     {
   1786  1.1  mrg       reemit_insn_block_notes ();
   1787  1.1  mrg       number_blocks (current_function_decl);
   1788  1.1  mrg       /* We never actually put out begin/end notes for the top-level
   1789  1.1  mrg 	 block in the function.  But, conceptually, that block is
   1790  1.1  mrg 	 always needed.  */
   1791  1.1  mrg       TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
   1792  1.1  mrg     }
   1793  1.1  mrg 
   1794  1.1  mrg   unsigned HOST_WIDE_INT min_frame_size
   1795  1.1  mrg     = constant_lower_bound (get_frame_size ());
   1796  1.1  mrg   if (min_frame_size > (unsigned HOST_WIDE_INT) warn_frame_larger_than_size)
   1797  1.1  mrg     {
   1798  1.1  mrg       /* Issue a warning */
   1799  1.1  mrg       warning (OPT_Wframe_larger_than_,
   1800  1.1  mrg 	       "the frame size of %wu bytes is larger than %wu bytes",
   1801  1.1  mrg 	       min_frame_size, warn_frame_larger_than_size);
   1802  1.1  mrg     }
   1803  1.1  mrg 
   1804  1.1  mrg   /* First output the function prologue: code to set up the stack frame.  */
   1805  1.1  mrg   targetm.asm_out.function_prologue (file);
   1806  1.1  mrg 
   1807  1.1  mrg   /* If the machine represents the prologue as RTL, the profiling code must
   1808  1.1  mrg      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
   1809  1.1  mrg   if (! targetm.have_prologue ())
   1810  1.1  mrg     profile_after_prologue (file);
   1811  1.1  mrg }
   1812  1.1  mrg 
   1813  1.1  mrg /* This is an exported final_start_function_1, callable without SEEN.  */
   1814  1.1  mrg 
   1815  1.1  mrg void
   1816  1.1  mrg final_start_function (rtx_insn *first, FILE *file,
   1817  1.1  mrg 		      int optimize_p ATTRIBUTE_UNUSED)
   1818  1.1  mrg {
   1819  1.1  mrg   int seen = 0;
   1820  1.1  mrg   final_start_function_1 (&first, file, &seen, optimize_p);
   1821  1.1  mrg   gcc_assert (seen == 0);
   1822  1.1  mrg }
   1823  1.1  mrg 
   1824  1.1  mrg static void
   1825  1.1  mrg profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
   1826  1.1  mrg {
   1827  1.1  mrg   if (!targetm.profile_before_prologue () && crtl->profile)
   1828  1.1  mrg     profile_function (file);
   1829  1.1  mrg }
   1830  1.1  mrg 
   1831  1.1  mrg static void
   1832  1.1  mrg profile_function (FILE *file ATTRIBUTE_UNUSED)
   1833  1.1  mrg {
   1834  1.1  mrg #ifndef NO_PROFILE_COUNTERS
   1835  1.1  mrg # define NO_PROFILE_COUNTERS	0
   1836  1.1  mrg #endif
   1837  1.1  mrg #ifdef ASM_OUTPUT_REG_PUSH
   1838  1.1  mrg   rtx sval = NULL, chain = NULL;
   1839  1.1  mrg 
   1840  1.1  mrg   if (cfun->returns_struct)
   1841  1.1  mrg     sval = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl),
   1842  1.1  mrg 					   true);
   1843  1.1  mrg   if (cfun->static_chain_decl)
   1844  1.1  mrg     chain = targetm.calls.static_chain (current_function_decl, true);
   1845  1.1  mrg #endif /* ASM_OUTPUT_REG_PUSH */
   1846  1.1  mrg 
   1847  1.1  mrg   if (! NO_PROFILE_COUNTERS)
   1848  1.1  mrg     {
   1849  1.1  mrg       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   1850  1.1  mrg       switch_to_section (data_section);
   1851  1.1  mrg       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
   1852  1.1  mrg       targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
   1853  1.1  mrg       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
   1854  1.1  mrg     }
   1855  1.1  mrg 
   1856  1.1  mrg   switch_to_section (current_function_section ());
   1857  1.1  mrg 
   1858  1.1  mrg #ifdef ASM_OUTPUT_REG_PUSH
   1859  1.1  mrg   if (sval && REG_P (sval))
   1860  1.1  mrg     ASM_OUTPUT_REG_PUSH (file, REGNO (sval));
   1861  1.1  mrg   if (chain && REG_P (chain))
   1862  1.1  mrg     ASM_OUTPUT_REG_PUSH (file, REGNO (chain));
   1863  1.1  mrg #endif
   1864  1.1  mrg 
   1865  1.1  mrg   FUNCTION_PROFILER (file, current_function_funcdef_no);
   1866  1.1  mrg 
   1867  1.1  mrg #ifdef ASM_OUTPUT_REG_PUSH
   1868  1.1  mrg   if (chain && REG_P (chain))
   1869  1.1  mrg     ASM_OUTPUT_REG_POP (file, REGNO (chain));
   1870  1.1  mrg   if (sval && REG_P (sval))
   1871  1.1  mrg     ASM_OUTPUT_REG_POP (file, REGNO (sval));
   1872  1.1  mrg #endif
   1873  1.1  mrg }
   1874  1.1  mrg 
   1875  1.1  mrg /* Output assembler code for the end of a function.
   1876  1.1  mrg    For clarity, args are same as those of `final_start_function'
   1877  1.1  mrg    even though not all of them are needed.  */
   1878  1.1  mrg 
   1879  1.1  mrg void
   1880  1.1  mrg final_end_function (void)
   1881  1.1  mrg {
   1882  1.1  mrg   app_disable ();
   1883  1.1  mrg 
   1884  1.1  mrg   if (!DECL_IGNORED_P (current_function_decl))
   1885  1.1  mrg     debug_hooks->end_function (high_function_linenum);
   1886  1.1  mrg 
   1887  1.1  mrg   /* Finally, output the function epilogue:
   1888  1.1  mrg      code to restore the stack frame and return to the caller.  */
   1889  1.1  mrg   targetm.asm_out.function_epilogue (asm_out_file);
   1890  1.1  mrg 
   1891  1.1  mrg   /* And debug output.  */
   1892  1.1  mrg   if (!DECL_IGNORED_P (current_function_decl))
   1893  1.1  mrg     debug_hooks->end_epilogue (last_linenum, last_filename);
   1894  1.1  mrg 
   1895  1.1  mrg   if (!dwarf2_debug_info_emitted_p (current_function_decl)
   1896  1.1  mrg       && dwarf2out_do_frame ())
   1897  1.1  mrg     dwarf2out_end_epilogue (last_linenum, last_filename);
   1898  1.1  mrg 
   1899  1.1  mrg   some_local_dynamic_name = 0;
   1900  1.1  mrg }
   1901  1.1  mrg 
   1902  1.1  mrg 
   1904  1.1  mrg /* Dumper helper for basic block information. FILE is the assembly
   1905  1.1  mrg    output file, and INSN is the instruction being emitted.  */
   1906  1.1  mrg 
   1907  1.1  mrg static void
   1908  1.1  mrg dump_basic_block_info (FILE *file, rtx_insn *insn, basic_block *start_to_bb,
   1909  1.1  mrg                        basic_block *end_to_bb, int bb_map_size, int *bb_seqn)
   1910  1.1  mrg {
   1911  1.1  mrg   basic_block bb;
   1912  1.1  mrg 
   1913  1.1  mrg   if (!flag_debug_asm)
   1914  1.1  mrg     return;
   1915  1.1  mrg 
   1916  1.1  mrg   if (INSN_UID (insn) < bb_map_size
   1917  1.1  mrg       && (bb = start_to_bb[INSN_UID (insn)]) != NULL)
   1918  1.1  mrg     {
   1919  1.1  mrg       edge e;
   1920  1.1  mrg       edge_iterator ei;
   1921  1.1  mrg 
   1922  1.1  mrg       fprintf (file, "%s BLOCK %d", ASM_COMMENT_START, bb->index);
   1923  1.1  mrg       if (bb->count.initialized_p ())
   1924  1.1  mrg 	{
   1925  1.1  mrg           fprintf (file, ", count:");
   1926  1.1  mrg 	  bb->count.dump (file);
   1927  1.1  mrg 	}
   1928  1.1  mrg       fprintf (file, " seq:%d", (*bb_seqn)++);
   1929  1.1  mrg       fprintf (file, "\n%s PRED:", ASM_COMMENT_START);
   1930  1.1  mrg       FOR_EACH_EDGE (e, ei, bb->preds)
   1931  1.1  mrg         {
   1932  1.1  mrg           dump_edge_info (file, e, TDF_DETAILS, 0);
   1933  1.1  mrg         }
   1934  1.1  mrg       fprintf (file, "\n");
   1935  1.1  mrg     }
   1936  1.1  mrg   if (INSN_UID (insn) < bb_map_size
   1937  1.1  mrg       && (bb = end_to_bb[INSN_UID (insn)]) != NULL)
   1938  1.1  mrg     {
   1939  1.1  mrg       edge e;
   1940  1.1  mrg       edge_iterator ei;
   1941  1.1  mrg 
   1942  1.1  mrg       fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START);
   1943  1.1  mrg       FOR_EACH_EDGE (e, ei, bb->succs)
   1944  1.1  mrg        {
   1945  1.1  mrg          dump_edge_info (asm_out_file, e, TDF_DETAILS, 1);
   1946  1.1  mrg        }
   1947  1.1  mrg       fprintf (file, "\n");
   1948  1.1  mrg     }
   1949  1.1  mrg }
   1950  1.1  mrg 
   1951  1.1  mrg /* Output assembler code for some insns: all or part of a function.
   1952  1.1  mrg    For description of args, see `final_start_function', above.  */
   1953  1.1  mrg 
   1954  1.1  mrg static void
   1955  1.1  mrg final_1 (rtx_insn *first, FILE *file, int seen, int optimize_p)
   1956  1.1  mrg {
   1957  1.1  mrg   rtx_insn *insn, *next;
   1958  1.1  mrg 
   1959  1.1  mrg   /* Used for -dA dump.  */
   1960  1.1  mrg   basic_block *start_to_bb = NULL;
   1961  1.1  mrg   basic_block *end_to_bb = NULL;
   1962  1.1  mrg   int bb_map_size = 0;
   1963  1.1  mrg   int bb_seqn = 0;
   1964  1.1  mrg 
   1965  1.1  mrg   last_ignored_compare = 0;
   1966  1.1  mrg 
   1967  1.1  mrg   init_recog ();
   1968  1.1  mrg 
   1969  1.1  mrg   CC_STATUS_INIT;
   1970  1.1  mrg 
   1971  1.1  mrg   if (flag_debug_asm)
   1972  1.1  mrg     {
   1973  1.1  mrg       basic_block bb;
   1974  1.1  mrg 
   1975  1.1  mrg       bb_map_size = get_max_uid () + 1;
   1976  1.1  mrg       start_to_bb = XCNEWVEC (basic_block, bb_map_size);
   1977  1.1  mrg       end_to_bb = XCNEWVEC (basic_block, bb_map_size);
   1978  1.1  mrg 
   1979  1.1  mrg       /* There is no cfg for a thunk.  */
   1980  1.1  mrg       if (!cfun->is_thunk)
   1981  1.1  mrg 	FOR_EACH_BB_REVERSE_FN (bb, cfun)
   1982  1.1  mrg 	  {
   1983  1.1  mrg 	    start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
   1984  1.1  mrg 	    end_to_bb[INSN_UID (BB_END (bb))] = bb;
   1985  1.1  mrg 	  }
   1986  1.1  mrg     }
   1987  1.1  mrg 
   1988  1.1  mrg   /* Output the insns.  */
   1989  1.1  mrg   for (insn = first; insn;)
   1990  1.1  mrg     {
   1991  1.1  mrg       if (HAVE_ATTR_length)
   1992  1.1  mrg 	{
   1993  1.1  mrg 	  if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
   1994  1.1  mrg 	    {
   1995  1.1  mrg 	      /* This can be triggered by bugs elsewhere in the compiler if
   1996  1.1  mrg 		 new insns are created after init_insn_lengths is called.  */
   1997  1.1  mrg 	      gcc_assert (NOTE_P (insn));
   1998  1.1  mrg 	      insn_current_address = -1;
   1999  1.1  mrg 	    }
   2000  1.1  mrg 	  else
   2001  1.1  mrg 	    insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
   2002  1.1  mrg 	  /* final can be seen as an iteration of shorten_branches that
   2003  1.1  mrg 	     does nothing (since a fixed point has already been reached).  */
   2004  1.1  mrg 	  insn_last_address = insn_current_address;
   2005  1.1  mrg 	}
   2006  1.1  mrg 
   2007  1.1  mrg       dump_basic_block_info (file, insn, start_to_bb, end_to_bb,
   2008  1.1  mrg                              bb_map_size, &bb_seqn);
   2009  1.1  mrg       insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
   2010  1.1  mrg     }
   2011  1.1  mrg 
   2012  1.1  mrg   maybe_output_next_view (&seen);
   2013  1.1  mrg 
   2014  1.1  mrg   if (flag_debug_asm)
   2015  1.1  mrg     {
   2016  1.1  mrg       free (start_to_bb);
   2017  1.1  mrg       free (end_to_bb);
   2018  1.1  mrg     }
   2019  1.1  mrg 
   2020  1.1  mrg   /* Remove CFI notes, to avoid compare-debug failures.  */
   2021  1.1  mrg   for (insn = first; insn; insn = next)
   2022  1.1  mrg     {
   2023  1.1  mrg       next = NEXT_INSN (insn);
   2024  1.1  mrg       if (NOTE_P (insn)
   2025  1.1  mrg 	  && (NOTE_KIND (insn) == NOTE_INSN_CFI
   2026  1.1  mrg 	      || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL))
   2027  1.1  mrg 	delete_insn (insn);
   2028  1.1  mrg     }
   2029  1.1  mrg }
   2030  1.1  mrg 
   2031  1.1  mrg /* This is an exported final_1, callable without SEEN.  */
   2032  1.1  mrg 
   2033  1.1  mrg void
   2034  1.1  mrg final (rtx_insn *first, FILE *file, int optimize_p)
   2035  1.1  mrg {
   2036  1.1  mrg   /* Those that use the internal final_start_function_1/final_1 API
   2037  1.1  mrg      skip initial debug bind notes in final_start_function_1, and pass
   2038  1.1  mrg      the modified FIRST to final_1.  But those that use the public
   2039  1.1  mrg      final_start_function/final APIs, final_start_function can't move
   2040  1.1  mrg      FIRST because it's not passed by reference, so if they were
   2041  1.1  mrg      skipped there, skip them again here.  */
   2042  1.1  mrg   while (in_initial_view_p (first))
   2043  1.1  mrg     first = NEXT_INSN (first);
   2044  1.1  mrg 
   2045  1.1  mrg   final_1 (first, file, 0, optimize_p);
   2046  1.1  mrg }
   2047  1.1  mrg 
   2048  1.1  mrg const char *
   2050  1.1  mrg get_insn_template (int code, rtx_insn *insn)
   2051  1.1  mrg {
   2052  1.1  mrg   switch (insn_data[code].output_format)
   2053  1.1  mrg     {
   2054  1.1  mrg     case INSN_OUTPUT_FORMAT_SINGLE:
   2055  1.1  mrg       return insn_data[code].output.single;
   2056  1.1  mrg     case INSN_OUTPUT_FORMAT_MULTI:
   2057  1.1  mrg       return insn_data[code].output.multi[which_alternative];
   2058  1.1  mrg     case INSN_OUTPUT_FORMAT_FUNCTION:
   2059  1.1  mrg       gcc_assert (insn);
   2060  1.1  mrg       return (*insn_data[code].output.function) (recog_data.operand, insn);
   2061  1.1  mrg 
   2062  1.1  mrg     default:
   2063  1.1  mrg       gcc_unreachable ();
   2064  1.1  mrg     }
   2065  1.1  mrg }
   2066  1.1  mrg 
   2067  1.1  mrg /* Emit the appropriate declaration for an alternate-entry-point
   2068  1.1  mrg    symbol represented by INSN, to FILE.  INSN is a CODE_LABEL with
   2069  1.1  mrg    LABEL_KIND != LABEL_NORMAL.
   2070  1.1  mrg 
   2071  1.1  mrg    The case fall-through in this function is intentional.  */
   2072  1.1  mrg static void
   2073  1.1  mrg output_alternate_entry_point (FILE *file, rtx_insn *insn)
   2074  1.1  mrg {
   2075  1.1  mrg   const char *name = LABEL_NAME (insn);
   2076  1.1  mrg 
   2077  1.1  mrg   switch (LABEL_KIND (insn))
   2078  1.1  mrg     {
   2079  1.1  mrg     case LABEL_WEAK_ENTRY:
   2080  1.1  mrg #ifdef ASM_WEAKEN_LABEL
   2081  1.1  mrg       ASM_WEAKEN_LABEL (file, name);
   2082  1.1  mrg       gcc_fallthrough ();
   2083  1.1  mrg #endif
   2084  1.1  mrg     case LABEL_GLOBAL_ENTRY:
   2085  1.1  mrg       targetm.asm_out.globalize_label (file, name);
   2086  1.1  mrg       gcc_fallthrough ();
   2087  1.1  mrg     case LABEL_STATIC_ENTRY:
   2088  1.1  mrg #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
   2089  1.1  mrg       ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
   2090  1.1  mrg #endif
   2091  1.1  mrg       ASM_OUTPUT_LABEL (file, name);
   2092  1.1  mrg       break;
   2093  1.1  mrg 
   2094  1.1  mrg     case LABEL_NORMAL:
   2095  1.1  mrg     default:
   2096  1.1  mrg       gcc_unreachable ();
   2097  1.1  mrg     }
   2098  1.1  mrg }
   2099  1.1  mrg 
   2100  1.1  mrg /* Given a CALL_INSN, find and return the nested CALL. */
   2101  1.1  mrg static rtx
   2102  1.1  mrg call_from_call_insn (rtx_call_insn *insn)
   2103  1.1  mrg {
   2104  1.1  mrg   rtx x;
   2105  1.1  mrg   gcc_assert (CALL_P (insn));
   2106  1.1  mrg   x = PATTERN (insn);
   2107  1.1  mrg 
   2108  1.1  mrg   while (GET_CODE (x) != CALL)
   2109  1.1  mrg     {
   2110  1.1  mrg       switch (GET_CODE (x))
   2111  1.1  mrg 	{
   2112  1.1  mrg 	default:
   2113  1.1  mrg 	  gcc_unreachable ();
   2114  1.1  mrg 	case COND_EXEC:
   2115  1.1  mrg 	  x = COND_EXEC_CODE (x);
   2116  1.1  mrg 	  break;
   2117  1.1  mrg 	case PARALLEL:
   2118  1.1  mrg 	  x = XVECEXP (x, 0, 0);
   2119  1.1  mrg 	  break;
   2120  1.1  mrg 	case SET:
   2121  1.1  mrg 	  x = XEXP (x, 1);
   2122  1.1  mrg 	  break;
   2123  1.1  mrg 	}
   2124  1.1  mrg     }
   2125  1.1  mrg   return x;
   2126  1.1  mrg }
   2127  1.1  mrg 
   2128  1.1  mrg /* Print a comment into the asm showing FILENAME, LINENUM, and the
   2129  1.1  mrg    corresponding source line, if available.  */
   2130  1.1  mrg 
   2131  1.1  mrg static void
   2132  1.1  mrg asm_show_source (const char *filename, int linenum)
   2133  1.1  mrg {
   2134  1.1  mrg   if (!filename)
   2135  1.1  mrg     return;
   2136  1.1  mrg 
   2137  1.1  mrg   char_span line = location_get_source_line (filename, linenum);
   2138  1.1  mrg   if (!line)
   2139  1.1  mrg     return;
   2140  1.1  mrg 
   2141  1.1  mrg   fprintf (asm_out_file, "%s %s:%i: ", ASM_COMMENT_START, filename, linenum);
   2142  1.1  mrg   /* "line" is not 0-terminated, so we must use its length.  */
   2143  1.1  mrg   fwrite (line.get_buffer (), 1, line.length (), asm_out_file);
   2144  1.1  mrg   fputc ('\n', asm_out_file);
   2145  1.1  mrg }
   2146  1.1  mrg 
   2147  1.1  mrg /* Judge if an absolute jump table is relocatable.  */
   2148  1.1  mrg 
   2149  1.1  mrg bool
   2150  1.1  mrg jumptable_relocatable (void)
   2151  1.1  mrg {
   2152  1.1  mrg   bool relocatable = false;
   2153  1.1  mrg 
   2154  1.1  mrg   if (!CASE_VECTOR_PC_RELATIVE
   2155  1.1  mrg       && !targetm.asm_out.generate_pic_addr_diff_vec ()
   2156  1.1  mrg       && targetm_common.have_named_sections)
   2157  1.1  mrg      relocatable = targetm.asm_out.reloc_rw_mask ();
   2158  1.1  mrg 
   2159  1.1  mrg   return relocatable;
   2160  1.1  mrg }
   2161  1.1  mrg 
   2162  1.1  mrg /* The final scan for one insn, INSN.
   2163  1.1  mrg    Args are same as in `final', except that INSN
   2164  1.1  mrg    is the insn being scanned.
   2165  1.1  mrg    Value returned is the next insn to be scanned.
   2166  1.1  mrg 
   2167  1.1  mrg    NOPEEPHOLES is the flag to disallow peephole processing (currently
   2168  1.1  mrg    used for within delayed branch sequence output).
   2169  1.1  mrg 
   2170  1.1  mrg    SEEN is used to track the end of the prologue, for emitting
   2171  1.1  mrg    debug information.  We force the emission of a line note after
   2172  1.1  mrg    both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG.  */
   2173  1.1  mrg 
   2174  1.1  mrg static rtx_insn *
   2175  1.1  mrg final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
   2176  1.1  mrg 		   int nopeepholes ATTRIBUTE_UNUSED, int *seen)
   2177  1.1  mrg {
   2178  1.1  mrg   rtx_insn *next;
   2179  1.1  mrg   rtx_jump_table_data *table;
   2180  1.1  mrg 
   2181  1.1  mrg   insn_counter++;
   2182  1.1  mrg 
   2183  1.1  mrg   /* Ignore deleted insns.  These can occur when we split insns (due to a
   2184  1.1  mrg      template of "#") while not optimizing.  */
   2185  1.1  mrg   if (insn->deleted ())
   2186  1.1  mrg     return NEXT_INSN (insn);
   2187  1.1  mrg 
   2188  1.1  mrg   switch (GET_CODE (insn))
   2189  1.1  mrg     {
   2190  1.1  mrg     case NOTE:
   2191  1.1  mrg       switch (NOTE_KIND (insn))
   2192  1.1  mrg 	{
   2193  1.1  mrg 	case NOTE_INSN_DELETED:
   2194  1.1  mrg 	case NOTE_INSN_UPDATE_SJLJ_CONTEXT:
   2195  1.1  mrg 	  break;
   2196  1.1  mrg 
   2197  1.1  mrg 	case NOTE_INSN_SWITCH_TEXT_SECTIONS:
   2198  1.1  mrg 	  maybe_output_next_view (seen);
   2199  1.1  mrg 
   2200  1.1  mrg 	  output_function_exception_table (0);
   2201  1.1  mrg 
   2202  1.1  mrg 	  if (targetm.asm_out.unwind_emit)
   2203  1.1  mrg 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
   2204  1.1  mrg 
   2205  1.1  mrg 	  in_cold_section_p = !in_cold_section_p;
   2206  1.1  mrg 
   2207  1.1  mrg 	  gcc_checking_assert (in_cold_section_p);
   2208  1.1  mrg 	  if (in_cold_section_p)
   2209  1.1  mrg 	    cold_function_name
   2210  1.1  mrg 	      = clone_function_name (current_function_decl, "cold");
   2211  1.1  mrg 
   2212  1.1  mrg 	  if (dwarf2out_do_frame ())
   2213  1.1  mrg 	    {
   2214  1.1  mrg 	      dwarf2out_switch_text_section ();
   2215  1.1  mrg 	      if (!dwarf2_debug_info_emitted_p (current_function_decl)
   2216  1.1  mrg 		  && !DECL_IGNORED_P (current_function_decl))
   2217  1.1  mrg 		debug_hooks->switch_text_section ();
   2218  1.1  mrg 	    }
   2219  1.1  mrg 	  else if (!DECL_IGNORED_P (current_function_decl))
   2220  1.1  mrg 	    debug_hooks->switch_text_section ();
   2221  1.1  mrg 	  if (DECL_IGNORED_P (current_function_decl) && last_linenum
   2222  1.1  mrg 	      && last_filename)
   2223  1.1  mrg 	    debug_hooks->set_ignored_loc (last_linenum, last_columnnum,
   2224  1.1  mrg 					  last_filename);
   2225  1.1  mrg 
   2226  1.1  mrg 	  switch_to_section (current_function_section ());
   2227  1.1  mrg 	  targetm.asm_out.function_switched_text_sections (asm_out_file,
   2228  1.1  mrg 							   current_function_decl,
   2229  1.1  mrg 							   in_cold_section_p);
   2230  1.1  mrg 	  /* Emit a label for the split cold section.  Form label name by
   2231  1.1  mrg 	     suffixing "cold" to the original function's name.  */
   2232  1.1  mrg 	  if (in_cold_section_p)
   2233  1.1  mrg 	    {
   2234  1.1  mrg #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
   2235  1.1  mrg 	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
   2236  1.1  mrg 					      IDENTIFIER_POINTER
   2237  1.1  mrg 					          (cold_function_name),
   2238  1.1  mrg 					      current_function_decl);
   2239  1.1  mrg #else
   2240  1.1  mrg 	      ASM_OUTPUT_LABEL (asm_out_file,
   2241  1.1  mrg 				IDENTIFIER_POINTER (cold_function_name));
   2242  1.1  mrg #endif
   2243  1.1  mrg 	      if (dwarf2out_do_frame ()
   2244  1.1  mrg 	          && cfun->fde->dw_fde_second_begin != NULL)
   2245  1.1  mrg 		ASM_OUTPUT_LABEL (asm_out_file, cfun->fde->dw_fde_second_begin);
   2246  1.1  mrg 	    }
   2247  1.1  mrg 	  break;
   2248  1.1  mrg 
   2249  1.1  mrg 	case NOTE_INSN_BASIC_BLOCK:
   2250  1.1  mrg 	  if (need_profile_function)
   2251  1.1  mrg 	    {
   2252  1.1  mrg 	      profile_function (asm_out_file);
   2253  1.1  mrg 	      need_profile_function = false;
   2254  1.1  mrg 	    }
   2255  1.1  mrg 
   2256  1.1  mrg 	  if (targetm.asm_out.unwind_emit)
   2257  1.1  mrg 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
   2258  1.1  mrg 
   2259  1.1  mrg 	  bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
   2260  1.1  mrg 	  break;
   2261  1.1  mrg 
   2262  1.1  mrg 	case NOTE_INSN_EH_REGION_BEG:
   2263  1.1  mrg 	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB",
   2264  1.1  mrg 				  NOTE_EH_HANDLER (insn));
   2265  1.1  mrg 	  break;
   2266  1.1  mrg 
   2267  1.1  mrg 	case NOTE_INSN_EH_REGION_END:
   2268  1.1  mrg 	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE",
   2269  1.1  mrg 				  NOTE_EH_HANDLER (insn));
   2270  1.1  mrg 	  break;
   2271  1.1  mrg 
   2272  1.1  mrg 	case NOTE_INSN_PROLOGUE_END:
   2273  1.1  mrg 	  targetm.asm_out.function_end_prologue (file);
   2274  1.1  mrg 	  profile_after_prologue (file);
   2275  1.1  mrg 
   2276  1.1  mrg 	  if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
   2277  1.1  mrg 	    {
   2278  1.1  mrg 	      *seen |= SEEN_EMITTED;
   2279  1.1  mrg 	      force_source_line = true;
   2280  1.1  mrg 	    }
   2281  1.1  mrg 	  else
   2282  1.1  mrg 	    *seen |= SEEN_NOTE;
   2283  1.1  mrg 
   2284  1.1  mrg 	  break;
   2285  1.1  mrg 
   2286  1.1  mrg 	case NOTE_INSN_EPILOGUE_BEG:
   2287  1.1  mrg           if (!DECL_IGNORED_P (current_function_decl))
   2288  1.1  mrg             (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
   2289  1.1  mrg 	  targetm.asm_out.function_begin_epilogue (file);
   2290  1.1  mrg 	  break;
   2291  1.1  mrg 
   2292  1.1  mrg 	case NOTE_INSN_CFI:
   2293  1.1  mrg 	  dwarf2out_emit_cfi (NOTE_CFI (insn));
   2294  1.1  mrg 	  break;
   2295  1.1  mrg 
   2296  1.1  mrg 	case NOTE_INSN_CFI_LABEL:
   2297  1.1  mrg 	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI",
   2298  1.1  mrg 				  NOTE_LABEL_NUMBER (insn));
   2299  1.1  mrg 	  break;
   2300  1.1  mrg 
   2301  1.1  mrg 	case NOTE_INSN_FUNCTION_BEG:
   2302  1.1  mrg 	  if (need_profile_function)
   2303  1.1  mrg 	    {
   2304  1.1  mrg 	      profile_function (asm_out_file);
   2305  1.1  mrg 	      need_profile_function = false;
   2306  1.1  mrg 	    }
   2307  1.1  mrg 
   2308  1.1  mrg 	  app_disable ();
   2309  1.1  mrg 	  if (!DECL_IGNORED_P (current_function_decl))
   2310  1.1  mrg 	    debug_hooks->end_prologue (last_linenum, last_filename);
   2311  1.1  mrg 
   2312  1.1  mrg 	  if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
   2313  1.1  mrg 	    {
   2314  1.1  mrg 	      *seen |= SEEN_EMITTED;
   2315  1.1  mrg 	      force_source_line = true;
   2316  1.1  mrg 	    }
   2317  1.1  mrg 	  else
   2318  1.1  mrg 	    *seen |= SEEN_NOTE;
   2319  1.1  mrg 
   2320  1.1  mrg 	  break;
   2321  1.1  mrg 
   2322  1.1  mrg 	case NOTE_INSN_BLOCK_BEG:
   2323  1.1  mrg 	  if (debug_info_level >= DINFO_LEVEL_NORMAL
   2324  1.1  mrg 	      || dwarf_debuginfo_p ()
   2325  1.1  mrg 	      || write_symbols == VMS_DEBUG)
   2326  1.1  mrg 	    {
   2327  1.1  mrg 	      int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
   2328  1.1  mrg 
   2329  1.1  mrg 	      app_disable ();
   2330  1.1  mrg 	      ++block_depth;
   2331  1.1  mrg 	      high_block_linenum = last_linenum;
   2332  1.1  mrg 
   2333  1.1  mrg 	      /* Output debugging info about the symbol-block beginning.  */
   2334  1.1  mrg 	      if (!DECL_IGNORED_P (current_function_decl))
   2335  1.1  mrg 		debug_hooks->begin_block (last_linenum, n);
   2336  1.1  mrg 
   2337  1.1  mrg 	      /* Mark this block as output.  */
   2338  1.1  mrg 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
   2339  1.1  mrg 	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
   2340  1.1  mrg 	    }
   2341  1.1  mrg 	  if (write_symbols == DBX_DEBUG)
   2342  1.1  mrg 	    {
   2343  1.1  mrg 	      location_t *locus_ptr
   2344  1.1  mrg 		= block_nonartificial_location (NOTE_BLOCK (insn));
   2345  1.1  mrg 
   2346  1.1  mrg 	      if (locus_ptr != NULL)
   2347  1.1  mrg 		{
   2348  1.1  mrg 		  override_filename = LOCATION_FILE (*locus_ptr);
   2349  1.1  mrg 		  override_linenum = LOCATION_LINE (*locus_ptr);
   2350  1.1  mrg 		  override_columnnum = LOCATION_COLUMN (*locus_ptr);
   2351  1.1  mrg 		  override_discriminator = compute_discriminator (*locus_ptr);
   2352  1.1  mrg 		}
   2353  1.1  mrg 	    }
   2354  1.1  mrg 	  break;
   2355  1.1  mrg 
   2356  1.1  mrg 	case NOTE_INSN_BLOCK_END:
   2357  1.1  mrg 	  maybe_output_next_view (seen);
   2358  1.1  mrg 
   2359  1.1  mrg 	  if (debug_info_level >= DINFO_LEVEL_NORMAL
   2360  1.1  mrg 	      || dwarf_debuginfo_p ()
   2361  1.1  mrg 	      || write_symbols == VMS_DEBUG)
   2362  1.1  mrg 	    {
   2363  1.1  mrg 	      int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
   2364  1.1  mrg 
   2365  1.1  mrg 	      app_disable ();
   2366  1.1  mrg 
   2367  1.1  mrg 	      /* End of a symbol-block.  */
   2368  1.1  mrg 	      --block_depth;
   2369  1.1  mrg 	      gcc_assert (block_depth >= 0);
   2370  1.1  mrg 
   2371  1.1  mrg 	      if (!DECL_IGNORED_P (current_function_decl))
   2372  1.1  mrg 		debug_hooks->end_block (high_block_linenum, n);
   2373  1.1  mrg 	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
   2374  1.1  mrg 			  == in_cold_section_p);
   2375  1.1  mrg 	    }
   2376  1.1  mrg 	  if (write_symbols == DBX_DEBUG)
   2377  1.1  mrg 	    {
   2378  1.1  mrg 	      tree outer_block = BLOCK_SUPERCONTEXT (NOTE_BLOCK (insn));
   2379  1.1  mrg 	      location_t *locus_ptr
   2380  1.1  mrg 		= block_nonartificial_location (outer_block);
   2381  1.1  mrg 
   2382  1.1  mrg 	      if (locus_ptr != NULL)
   2383  1.1  mrg 		{
   2384  1.1  mrg 		  override_filename = LOCATION_FILE (*locus_ptr);
   2385  1.1  mrg 		  override_linenum = LOCATION_LINE (*locus_ptr);
   2386  1.1  mrg 		  override_columnnum = LOCATION_COLUMN (*locus_ptr);
   2387  1.1  mrg 		  override_discriminator = compute_discriminator (*locus_ptr);
   2388  1.1  mrg 		}
   2389  1.1  mrg 	      else
   2390  1.1  mrg 		{
   2391  1.1  mrg 		  override_filename = NULL;
   2392  1.1  mrg 		  override_linenum = 0;
   2393  1.1  mrg 		  override_columnnum = 0;
   2394  1.1  mrg 		  override_discriminator = 0;
   2395  1.1  mrg 		}
   2396  1.1  mrg 	    }
   2397  1.1  mrg 	  break;
   2398  1.1  mrg 
   2399  1.1  mrg 	case NOTE_INSN_DELETED_LABEL:
   2400  1.1  mrg 	  /* Emit the label.  We may have deleted the CODE_LABEL because
   2401  1.1  mrg 	     the label could be proved to be unreachable, though still
   2402  1.1  mrg 	     referenced (in the form of having its address taken.  */
   2403  1.1  mrg 	  ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
   2404  1.1  mrg 	  break;
   2405  1.1  mrg 
   2406  1.1  mrg 	case NOTE_INSN_DELETED_DEBUG_LABEL:
   2407  1.1  mrg 	  /* Similarly, but need to use different namespace for it.  */
   2408  1.1  mrg 	  if (CODE_LABEL_NUMBER (insn) != -1)
   2409  1.1  mrg 	    ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn));
   2410  1.1  mrg 	  break;
   2411  1.1  mrg 
   2412  1.1  mrg 	case NOTE_INSN_VAR_LOCATION:
   2413  1.1  mrg 	  if (!DECL_IGNORED_P (current_function_decl))
   2414  1.1  mrg 	    {
   2415  1.1  mrg 	      debug_hooks->var_location (insn);
   2416  1.1  mrg 	      set_next_view_needed (seen);
   2417  1.1  mrg 	    }
   2418  1.1  mrg 	  break;
   2419  1.1  mrg 
   2420  1.1  mrg 	case NOTE_INSN_BEGIN_STMT:
   2421  1.1  mrg 	  gcc_checking_assert (cfun->debug_nonbind_markers);
   2422  1.1  mrg 	  if (!DECL_IGNORED_P (current_function_decl)
   2423  1.1  mrg 	      && notice_source_line (insn, NULL))
   2424  1.1  mrg 	    {
   2425  1.1  mrg 	    output_source_line:
   2426  1.1  mrg 	      (*debug_hooks->source_line) (last_linenum, last_columnnum,
   2427  1.1  mrg 					   last_filename, last_discriminator,
   2428  1.1  mrg 					   true);
   2429  1.1  mrg 	      clear_next_view_needed (seen);
   2430  1.1  mrg 	    }
   2431  1.1  mrg 	  break;
   2432  1.1  mrg 
   2433  1.1  mrg 	case NOTE_INSN_INLINE_ENTRY:
   2434  1.1  mrg 	  gcc_checking_assert (cfun->debug_nonbind_markers);
   2435  1.1  mrg 	  if (!DECL_IGNORED_P (current_function_decl)
   2436  1.1  mrg 	      && notice_source_line (insn, NULL))
   2437  1.1  mrg 	    {
   2438  1.1  mrg 	      (*debug_hooks->inline_entry) (LOCATION_BLOCK
   2439  1.1  mrg 					    (NOTE_MARKER_LOCATION (insn)));
   2440  1.1  mrg 	      goto output_source_line;
   2441  1.1  mrg 	    }
   2442  1.1  mrg 	  break;
   2443  1.1  mrg 
   2444  1.1  mrg 	default:
   2445  1.1  mrg 	  gcc_unreachable ();
   2446  1.1  mrg 	  break;
   2447  1.1  mrg 	}
   2448  1.1  mrg       break;
   2449  1.1  mrg 
   2450  1.1  mrg     case BARRIER:
   2451  1.1  mrg       break;
   2452  1.1  mrg 
   2453  1.1  mrg     case CODE_LABEL:
   2454  1.1  mrg       /* The target port might emit labels in the output function for
   2455  1.1  mrg 	 some insn, e.g. sh.cc output_branchy_insn.  */
   2456  1.1  mrg       if (CODE_LABEL_NUMBER (insn) <= max_labelno)
   2457  1.1  mrg 	{
   2458  1.1  mrg 	  align_flags alignment = LABEL_TO_ALIGNMENT (insn);
   2459  1.1  mrg 	  if (alignment.levels[0].log && NEXT_INSN (insn))
   2460  1.1  mrg 	    {
   2461  1.1  mrg #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   2462  1.1  mrg 	      /* Output both primary and secondary alignment.  */
   2463  1.1  mrg 	      ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[0].log,
   2464  1.1  mrg 					 alignment.levels[0].maxskip);
   2465  1.1  mrg 	      ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[1].log,
   2466  1.1  mrg 					 alignment.levels[1].maxskip);
   2467  1.1  mrg #else
   2468  1.1  mrg #ifdef ASM_OUTPUT_ALIGN_WITH_NOP
   2469  1.1  mrg               ASM_OUTPUT_ALIGN_WITH_NOP (file, alignment.levels[0].log);
   2470  1.1  mrg #else
   2471  1.1  mrg 	      ASM_OUTPUT_ALIGN (file, alignment.levels[0].log);
   2472  1.1  mrg #endif
   2473  1.1  mrg #endif
   2474  1.1  mrg 	    }
   2475  1.1  mrg 	}
   2476  1.1  mrg       CC_STATUS_INIT;
   2477  1.1  mrg 
   2478  1.1  mrg       if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
   2479  1.1  mrg 	debug_hooks->label (as_a <rtx_code_label *> (insn));
   2480  1.1  mrg 
   2481  1.1  mrg       app_disable ();
   2482  1.1  mrg 
   2483  1.1  mrg       /* If this label is followed by a jump-table, make sure we put
   2484  1.1  mrg 	 the label in the read-only section.  Also possibly write the
   2485  1.1  mrg 	 label and jump table together.  */
   2486  1.1  mrg       table = jump_table_for_label (as_a <rtx_code_label *> (insn));
   2487  1.1  mrg       if (table)
   2488  1.1  mrg 	{
   2489  1.1  mrg #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
   2490  1.1  mrg 	  /* In this case, the case vector is being moved by the
   2491  1.1  mrg 	     target, so don't output the label at all.  Leave that
   2492  1.1  mrg 	     to the back end macros.  */
   2493  1.1  mrg #else
   2494  1.1  mrg 	  if (! JUMP_TABLES_IN_TEXT_SECTION)
   2495  1.1  mrg 	    {
   2496  1.1  mrg 	      int log_align;
   2497  1.1  mrg 
   2498  1.1  mrg 	      switch_to_section (targetm.asm_out.function_rodata_section
   2499  1.1  mrg 				 (current_function_decl,
   2500  1.1  mrg 				  jumptable_relocatable ()));
   2501  1.1  mrg 
   2502  1.1  mrg #ifdef ADDR_VEC_ALIGN
   2503  1.1  mrg 	      log_align = ADDR_VEC_ALIGN (table);
   2504  1.1  mrg #else
   2505  1.1  mrg 	      log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
   2506  1.1  mrg #endif
   2507  1.1  mrg 	      ASM_OUTPUT_ALIGN (file, log_align);
   2508  1.1  mrg 	    }
   2509  1.1  mrg 	  else
   2510  1.1  mrg 	    switch_to_section (current_function_section ());
   2511  1.1  mrg 
   2512  1.1  mrg #ifdef ASM_OUTPUT_CASE_LABEL
   2513  1.1  mrg 	  ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), table);
   2514  1.1  mrg #else
   2515  1.1  mrg 	  targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
   2516  1.1  mrg #endif
   2517  1.1  mrg #endif
   2518  1.1  mrg 	  break;
   2519  1.1  mrg 	}
   2520  1.1  mrg       if (LABEL_ALT_ENTRY_P (insn))
   2521  1.1  mrg 	output_alternate_entry_point (file, insn);
   2522  1.1  mrg       else
   2523  1.1  mrg 	targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
   2524  1.1  mrg       break;
   2525  1.1  mrg 
   2526  1.1  mrg     default:
   2527  1.1  mrg       {
   2528  1.1  mrg 	rtx body = PATTERN (insn);
   2529  1.1  mrg 	int insn_code_number;
   2530  1.1  mrg 	const char *templ;
   2531  1.1  mrg 	bool is_stmt, *is_stmt_p;
   2532  1.1  mrg 
   2533  1.1  mrg 	if (MAY_HAVE_DEBUG_MARKER_INSNS && cfun->debug_nonbind_markers)
   2534  1.1  mrg 	  {
   2535  1.1  mrg 	    is_stmt = false;
   2536  1.1  mrg 	    is_stmt_p = NULL;
   2537  1.1  mrg 	  }
   2538  1.1  mrg 	else
   2539  1.1  mrg 	  is_stmt_p = &is_stmt;
   2540  1.1  mrg 
   2541  1.1  mrg 	/* Reset this early so it is correct for ASM statements.  */
   2542  1.1  mrg 	current_insn_predicate = NULL_RTX;
   2543  1.1  mrg 
   2544  1.1  mrg 	/* An INSN, JUMP_INSN or CALL_INSN.
   2545  1.1  mrg 	   First check for special kinds that recog doesn't recognize.  */
   2546  1.1  mrg 
   2547  1.1  mrg 	if (GET_CODE (body) == USE /* These are just declarations.  */
   2548  1.1  mrg 	    || GET_CODE (body) == CLOBBER)
   2549  1.1  mrg 	  break;
   2550  1.1  mrg 
   2551  1.1  mrg 	/* Detect insns that are really jump-tables
   2552  1.1  mrg 	   and output them as such.  */
   2553  1.1  mrg 
   2554  1.1  mrg         if (JUMP_TABLE_DATA_P (insn))
   2555  1.1  mrg 	  {
   2556  1.1  mrg #if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC))
   2557  1.1  mrg 	    int vlen, idx;
   2558  1.1  mrg #endif
   2559  1.1  mrg 
   2560  1.1  mrg 	    if (! JUMP_TABLES_IN_TEXT_SECTION)
   2561  1.1  mrg 	      switch_to_section (targetm.asm_out.function_rodata_section
   2562  1.1  mrg 				 (current_function_decl,
   2563  1.1  mrg 				  jumptable_relocatable ()));
   2564  1.1  mrg 	    else
   2565  1.1  mrg 	      switch_to_section (current_function_section ());
   2566  1.1  mrg 
   2567  1.1  mrg 	    app_disable ();
   2568  1.1  mrg 
   2569  1.1  mrg #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
   2570  1.1  mrg 	    if (GET_CODE (body) == ADDR_VEC)
   2571  1.1  mrg 	      {
   2572  1.1  mrg #ifdef ASM_OUTPUT_ADDR_VEC
   2573  1.1  mrg 		ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
   2574  1.1  mrg #else
   2575  1.1  mrg 		gcc_unreachable ();
   2576  1.1  mrg #endif
   2577  1.1  mrg 	      }
   2578  1.1  mrg 	    else
   2579  1.1  mrg 	      {
   2580  1.1  mrg #ifdef ASM_OUTPUT_ADDR_DIFF_VEC
   2581  1.1  mrg 		ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
   2582  1.1  mrg #else
   2583  1.1  mrg 		gcc_unreachable ();
   2584  1.1  mrg #endif
   2585  1.1  mrg 	      }
   2586  1.1  mrg #else
   2587  1.1  mrg 	    vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
   2588  1.1  mrg 	    for (idx = 0; idx < vlen; idx++)
   2589  1.1  mrg 	      {
   2590  1.1  mrg 		if (GET_CODE (body) == ADDR_VEC)
   2591  1.1  mrg 		  {
   2592  1.1  mrg #ifdef ASM_OUTPUT_ADDR_VEC_ELT
   2593  1.1  mrg 		    ASM_OUTPUT_ADDR_VEC_ELT
   2594  1.1  mrg 		      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
   2595  1.1  mrg #else
   2596  1.1  mrg 		    gcc_unreachable ();
   2597  1.1  mrg #endif
   2598  1.1  mrg 		  }
   2599  1.1  mrg 		else
   2600  1.1  mrg 		  {
   2601  1.1  mrg #ifdef ASM_OUTPUT_ADDR_DIFF_ELT
   2602  1.1  mrg 		    ASM_OUTPUT_ADDR_DIFF_ELT
   2603  1.1  mrg 		      (file,
   2604  1.1  mrg 		       body,
   2605  1.1  mrg 		       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
   2606  1.1  mrg 		       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
   2607  1.1  mrg #else
   2608  1.1  mrg 		    gcc_unreachable ();
   2609  1.1  mrg #endif
   2610  1.1  mrg 		  }
   2611  1.1  mrg 	      }
   2612  1.1  mrg #ifdef ASM_OUTPUT_CASE_END
   2613  1.1  mrg 	    ASM_OUTPUT_CASE_END (file,
   2614  1.1  mrg 				 CODE_LABEL_NUMBER (PREV_INSN (insn)),
   2615  1.1  mrg 				 insn);
   2616  1.1  mrg #endif
   2617  1.1  mrg #endif
   2618  1.1  mrg 
   2619  1.1  mrg 	    switch_to_section (current_function_section ());
   2620  1.1  mrg 
   2621  1.1  mrg 	    if (debug_variable_location_views
   2622  1.1  mrg 		&& !DECL_IGNORED_P (current_function_decl))
   2623  1.1  mrg 	      debug_hooks->var_location (insn);
   2624  1.1  mrg 
   2625  1.1  mrg 	    break;
   2626  1.1  mrg 	  }
   2627  1.1  mrg 	/* Output this line note if it is the first or the last line
   2628  1.1  mrg 	   note in a row.  */
   2629  1.1  mrg 	if (!DECL_IGNORED_P (current_function_decl)
   2630  1.1  mrg 	    && notice_source_line (insn, is_stmt_p))
   2631  1.1  mrg 	  {
   2632  1.1  mrg 	    if (flag_verbose_asm)
   2633  1.1  mrg 	      asm_show_source (last_filename, last_linenum);
   2634  1.1  mrg 	    (*debug_hooks->source_line) (last_linenum, last_columnnum,
   2635  1.1  mrg 					 last_filename, last_discriminator,
   2636  1.1  mrg 					 is_stmt);
   2637  1.1  mrg 	    clear_next_view_needed (seen);
   2638  1.1  mrg 	  }
   2639  1.1  mrg 	else
   2640  1.1  mrg 	  maybe_output_next_view (seen);
   2641  1.1  mrg 
   2642  1.1  mrg 	gcc_checking_assert (!DEBUG_INSN_P (insn));
   2643  1.1  mrg 
   2644  1.1  mrg 	if (GET_CODE (body) == PARALLEL
   2645  1.1  mrg 	    && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
   2646  1.1  mrg 	  body = XVECEXP (body, 0, 0);
   2647  1.1  mrg 
   2648  1.1  mrg 	if (GET_CODE (body) == ASM_INPUT)
   2649  1.1  mrg 	  {
   2650  1.1  mrg 	    const char *string = XSTR (body, 0);
   2651  1.1  mrg 
   2652  1.1  mrg 	    /* There's no telling what that did to the condition codes.  */
   2653  1.1  mrg 	    CC_STATUS_INIT;
   2654  1.1  mrg 
   2655  1.1  mrg 	    if (string[0])
   2656  1.1  mrg 	      {
   2657  1.1  mrg 		expanded_location loc;
   2658  1.1  mrg 
   2659  1.1  mrg 		app_enable ();
   2660  1.1  mrg 		loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
   2661  1.1  mrg 		if (*loc.file && loc.line)
   2662  1.1  mrg 		  fprintf (asm_out_file, "%s %i \"%s\" 1\n",
   2663  1.1  mrg 			   ASM_COMMENT_START, loc.line, loc.file);
   2664  1.1  mrg 		fprintf (asm_out_file, "\t%s\n", string);
   2665  1.1  mrg #if HAVE_AS_LINE_ZERO
   2666  1.1  mrg 		if (*loc.file && loc.line)
   2667  1.1  mrg 		  fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
   2668  1.1  mrg #endif
   2669  1.1  mrg 	      }
   2670  1.1  mrg 	    break;
   2671  1.1  mrg 	  }
   2672  1.1  mrg 
   2673  1.1  mrg 	/* Detect `asm' construct with operands.  */
   2674  1.1  mrg 	if (asm_noperands (body) >= 0)
   2675  1.1  mrg 	  {
   2676  1.1  mrg 	    unsigned int noperands = asm_noperands (body);
   2677  1.1  mrg 	    rtx *ops = XALLOCAVEC (rtx, noperands);
   2678  1.1  mrg 	    const char *string;
   2679  1.1  mrg 	    location_t loc;
   2680  1.1  mrg 	    expanded_location expanded;
   2681  1.1  mrg 
   2682  1.1  mrg 	    /* There's no telling what that did to the condition codes.  */
   2683  1.1  mrg 	    CC_STATUS_INIT;
   2684  1.1  mrg 
   2685  1.1  mrg 	    /* Get out the operand values.  */
   2686  1.1  mrg 	    string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc);
   2687  1.1  mrg 	    /* Inhibit dying on what would otherwise be compiler bugs.  */
   2688  1.1  mrg 	    insn_noperands = noperands;
   2689  1.1  mrg 	    this_is_asm_operands = insn;
   2690  1.1  mrg 	    expanded = expand_location (loc);
   2691  1.1  mrg 
   2692  1.1  mrg #ifdef FINAL_PRESCAN_INSN
   2693  1.1  mrg 	    FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
   2694  1.1  mrg #endif
   2695  1.1  mrg 
   2696  1.1  mrg 	    /* Output the insn using them.  */
   2697  1.1  mrg 	    if (string[0])
   2698  1.1  mrg 	      {
   2699  1.1  mrg 		app_enable ();
   2700  1.1  mrg 		if (expanded.file && expanded.line)
   2701  1.1  mrg 		  fprintf (asm_out_file, "%s %i \"%s\" 1\n",
   2702  1.1  mrg 			   ASM_COMMENT_START, expanded.line, expanded.file);
   2703  1.1  mrg 	        output_asm_insn (string, ops);
   2704  1.1  mrg #if HAVE_AS_LINE_ZERO
   2705  1.1  mrg 		if (expanded.file && expanded.line)
   2706  1.1  mrg 		  fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
   2707  1.1  mrg #endif
   2708  1.1  mrg 	      }
   2709  1.1  mrg 
   2710  1.1  mrg 	    if (targetm.asm_out.final_postscan_insn)
   2711  1.1  mrg 	      targetm.asm_out.final_postscan_insn (file, insn, ops,
   2712  1.1  mrg 						   insn_noperands);
   2713  1.1  mrg 
   2714  1.1  mrg 	    this_is_asm_operands = 0;
   2715  1.1  mrg 	    break;
   2716  1.1  mrg 	  }
   2717  1.1  mrg 
   2718  1.1  mrg 	app_disable ();
   2719  1.1  mrg 
   2720  1.1  mrg 	if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
   2721  1.1  mrg 	  {
   2722  1.1  mrg 	    /* A delayed-branch sequence */
   2723  1.1  mrg 	    int i;
   2724  1.1  mrg 
   2725  1.1  mrg 	    final_sequence = seq;
   2726  1.1  mrg 
   2727  1.1  mrg 	    /* The first insn in this SEQUENCE might be a JUMP_INSN that will
   2728  1.1  mrg 	       force the restoration of a comparison that was previously
   2729  1.1  mrg 	       thought unnecessary.  If that happens, cancel this sequence
   2730  1.1  mrg 	       and cause that insn to be restored.  */
   2731  1.1  mrg 
   2732  1.1  mrg 	    next = final_scan_insn (seq->insn (0), file, 0, 1, seen);
   2733  1.1  mrg 	    if (next != seq->insn (1))
   2734  1.1  mrg 	      {
   2735  1.1  mrg 		final_sequence = 0;
   2736  1.1  mrg 		return next;
   2737  1.1  mrg 	      }
   2738  1.1  mrg 
   2739  1.1  mrg 	    for (i = 1; i < seq->len (); i++)
   2740  1.1  mrg 	      {
   2741  1.1  mrg 		rtx_insn *insn = seq->insn (i);
   2742  1.1  mrg 		rtx_insn *next = NEXT_INSN (insn);
   2743  1.1  mrg 		/* We loop in case any instruction in a delay slot gets
   2744  1.1  mrg 		   split.  */
   2745  1.1  mrg 		do
   2746  1.1  mrg 		  insn = final_scan_insn (insn, file, 0, 1, seen);
   2747  1.1  mrg 		while (insn != next);
   2748  1.1  mrg 	      }
   2749  1.1  mrg #ifdef DBR_OUTPUT_SEQEND
   2750  1.1  mrg 	    DBR_OUTPUT_SEQEND (file);
   2751  1.1  mrg #endif
   2752  1.1  mrg 	    final_sequence = 0;
   2753  1.1  mrg 
   2754  1.1  mrg 	    /* If the insn requiring the delay slot was a CALL_INSN, the
   2755  1.1  mrg 	       insns in the delay slot are actually executed before the
   2756  1.1  mrg 	       called function.  Hence we don't preserve any CC-setting
   2757  1.1  mrg 	       actions in these insns and the CC must be marked as being
   2758  1.1  mrg 	       clobbered by the function.  */
   2759  1.1  mrg 	    if (CALL_P (seq->insn (0)))
   2760  1.1  mrg 	      {
   2761  1.1  mrg 		CC_STATUS_INIT;
   2762  1.1  mrg 	      }
   2763  1.1  mrg 	    break;
   2764  1.1  mrg 	  }
   2765  1.1  mrg 
   2766  1.1  mrg 	/* We have a real machine instruction as rtl.  */
   2767  1.1  mrg 
   2768  1.1  mrg 	body = PATTERN (insn);
   2769  1.1  mrg 
   2770  1.1  mrg 	/* Do machine-specific peephole optimizations if desired.  */
   2771  1.1  mrg 
   2772  1.1  mrg 	if (HAVE_peephole && optimize_p && !flag_no_peephole && !nopeepholes)
   2773  1.1  mrg 	  {
   2774  1.1  mrg 	    rtx_insn *next = peephole (insn);
   2775  1.1  mrg 	    /* When peepholing, if there were notes within the peephole,
   2776  1.1  mrg 	       emit them before the peephole.  */
   2777  1.1  mrg 	    if (next != 0 && next != NEXT_INSN (insn))
   2778  1.1  mrg 	      {
   2779  1.1  mrg 		rtx_insn *note, *prev = PREV_INSN (insn);
   2780  1.1  mrg 
   2781  1.1  mrg 		for (note = NEXT_INSN (insn); note != next;
   2782  1.1  mrg 		     note = NEXT_INSN (note))
   2783  1.1  mrg 		  final_scan_insn (note, file, optimize_p, nopeepholes, seen);
   2784  1.1  mrg 
   2785  1.1  mrg 		/* Put the notes in the proper position for a later
   2786  1.1  mrg 		   rescan.  For example, the SH target can do this
   2787  1.1  mrg 		   when generating a far jump in a delayed branch
   2788  1.1  mrg 		   sequence.  */
   2789  1.1  mrg 		note = NEXT_INSN (insn);
   2790  1.1  mrg 		SET_PREV_INSN (note) = prev;
   2791  1.1  mrg 		SET_NEXT_INSN (prev) = note;
   2792  1.1  mrg 		SET_NEXT_INSN (PREV_INSN (next)) = insn;
   2793  1.1  mrg 		SET_PREV_INSN (insn) = PREV_INSN (next);
   2794  1.1  mrg 		SET_NEXT_INSN (insn) = next;
   2795  1.1  mrg 		SET_PREV_INSN (next) = insn;
   2796  1.1  mrg 	      }
   2797  1.1  mrg 
   2798  1.1  mrg 	    /* PEEPHOLE might have changed this.  */
   2799  1.1  mrg 	    body = PATTERN (insn);
   2800  1.1  mrg 	  }
   2801  1.1  mrg 
   2802  1.1  mrg 	/* Try to recognize the instruction.
   2803  1.1  mrg 	   If successful, verify that the operands satisfy the
   2804  1.1  mrg 	   constraints for the instruction.  Crash if they don't,
   2805  1.1  mrg 	   since `reload' should have changed them so that they do.  */
   2806  1.1  mrg 
   2807  1.1  mrg 	insn_code_number = recog_memoized (insn);
   2808  1.1  mrg 	cleanup_subreg_operands (insn);
   2809  1.1  mrg 
   2810  1.1  mrg 	/* Dump the insn in the assembly for debugging (-dAP).
   2811  1.1  mrg 	   If the final dump is requested as slim RTL, dump slim
   2812  1.1  mrg 	   RTL to the assembly file also.  */
   2813  1.1  mrg 	if (flag_dump_rtl_in_asm)
   2814  1.1  mrg 	  {
   2815  1.1  mrg 	    print_rtx_head = ASM_COMMENT_START;
   2816  1.1  mrg 	    if (! (dump_flags & TDF_SLIM))
   2817  1.1  mrg 	      print_rtl_single (asm_out_file, insn);
   2818  1.1  mrg 	    else
   2819  1.1  mrg 	      dump_insn_slim (asm_out_file, insn);
   2820  1.1  mrg 	    print_rtx_head = "";
   2821  1.1  mrg 	  }
   2822  1.1  mrg 
   2823  1.1  mrg 	if (! constrain_operands_cached (insn, 1))
   2824  1.1  mrg 	  fatal_insn_not_found (insn);
   2825  1.1  mrg 
   2826  1.1  mrg 	/* Some target machines need to prescan each insn before
   2827  1.1  mrg 	   it is output.  */
   2828  1.1  mrg 
   2829  1.1  mrg #ifdef FINAL_PRESCAN_INSN
   2830  1.1  mrg 	FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
   2831  1.1  mrg #endif
   2832  1.1  mrg 
   2833  1.1  mrg 	if (targetm.have_conditional_execution ()
   2834  1.1  mrg 	    && GET_CODE (PATTERN (insn)) == COND_EXEC)
   2835  1.1  mrg 	  current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
   2836  1.1  mrg 
   2837  1.1  mrg 	current_output_insn = debug_insn = insn;
   2838  1.1  mrg 
   2839  1.1  mrg 	/* Find the proper template for this insn.  */
   2840  1.1  mrg 	templ = get_insn_template (insn_code_number, insn);
   2841  1.1  mrg 
   2842  1.1  mrg 	/* If the C code returns 0, it means that it is a jump insn
   2843  1.1  mrg 	   which follows a deleted test insn, and that test insn
   2844  1.1  mrg 	   needs to be reinserted.  */
   2845  1.1  mrg 	if (templ == 0)
   2846  1.1  mrg 	  {
   2847  1.1  mrg 	    rtx_insn *prev;
   2848  1.1  mrg 
   2849  1.1  mrg 	    gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare);
   2850  1.1  mrg 
   2851  1.1  mrg 	    /* We have already processed the notes between the setter and
   2852  1.1  mrg 	       the user.  Make sure we don't process them again, this is
   2853  1.1  mrg 	       particularly important if one of the notes is a block
   2854  1.1  mrg 	       scope note or an EH note.  */
   2855  1.1  mrg 	    for (prev = insn;
   2856  1.1  mrg 		 prev != last_ignored_compare;
   2857  1.1  mrg 		 prev = PREV_INSN (prev))
   2858  1.1  mrg 	      {
   2859  1.1  mrg 		if (NOTE_P (prev))
   2860  1.1  mrg 		  delete_insn (prev);	/* Use delete_note.  */
   2861  1.1  mrg 	      }
   2862  1.1  mrg 
   2863  1.1  mrg 	    return prev;
   2864  1.1  mrg 	  }
   2865  1.1  mrg 
   2866  1.1  mrg 	/* If the template is the string "#", it means that this insn must
   2867  1.1  mrg 	   be split.  */
   2868  1.1  mrg 	if (templ[0] == '#' && templ[1] == '\0')
   2869  1.1  mrg 	  {
   2870  1.1  mrg 	    rtx_insn *new_rtx = try_split (body, insn, 0);
   2871  1.1  mrg 
   2872  1.1  mrg 	    /* If we didn't split the insn, go away.  */
   2873  1.1  mrg 	    if (new_rtx == insn && PATTERN (new_rtx) == body)
   2874  1.1  mrg 	      fatal_insn ("could not split insn", insn);
   2875  1.1  mrg 
   2876  1.1  mrg 	    /* If we have a length attribute, this instruction should have
   2877  1.1  mrg 	       been split in shorten_branches, to ensure that we would have
   2878  1.1  mrg 	       valid length info for the splitees.  */
   2879  1.1  mrg 	    gcc_assert (!HAVE_ATTR_length);
   2880  1.1  mrg 
   2881  1.1  mrg 	    return new_rtx;
   2882  1.1  mrg 	  }
   2883  1.1  mrg 
   2884  1.1  mrg 	/* ??? This will put the directives in the wrong place if
   2885  1.1  mrg 	   get_insn_template outputs assembly directly.  However calling it
   2886  1.1  mrg 	   before get_insn_template breaks if the insns is split.  */
   2887  1.1  mrg 	if (targetm.asm_out.unwind_emit_before_insn
   2888  1.1  mrg 	    && targetm.asm_out.unwind_emit)
   2889  1.1  mrg 	  targetm.asm_out.unwind_emit (asm_out_file, insn);
   2890  1.1  mrg 
   2891  1.1  mrg 	rtx_call_insn *call_insn = dyn_cast <rtx_call_insn *> (insn);
   2892  1.1  mrg 	if (call_insn != NULL)
   2893  1.1  mrg 	  {
   2894  1.1  mrg 	    rtx x = call_from_call_insn (call_insn);
   2895  1.1  mrg 	    x = XEXP (x, 0);
   2896  1.1  mrg 	    if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
   2897  1.1  mrg 	      {
   2898  1.1  mrg 		tree t;
   2899  1.1  mrg 		x = XEXP (x, 0);
   2900  1.1  mrg 		t = SYMBOL_REF_DECL (x);
   2901  1.1  mrg 		if (t)
   2902  1.1  mrg 		  assemble_external (t);
   2903  1.1  mrg 	      }
   2904  1.1  mrg 	  }
   2905  1.1  mrg 
   2906  1.1  mrg 	/* Output assembler code from the template.  */
   2907  1.1  mrg 	output_asm_insn (templ, recog_data.operand);
   2908  1.1  mrg 
   2909  1.1  mrg 	/* Some target machines need to postscan each insn after
   2910  1.1  mrg 	   it is output.  */
   2911  1.1  mrg 	if (targetm.asm_out.final_postscan_insn)
   2912  1.1  mrg 	  targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
   2913  1.1  mrg 					       recog_data.n_operands);
   2914  1.1  mrg 
   2915  1.1  mrg 	if (!targetm.asm_out.unwind_emit_before_insn
   2916  1.1  mrg 	    && targetm.asm_out.unwind_emit)
   2917  1.1  mrg 	  targetm.asm_out.unwind_emit (asm_out_file, insn);
   2918  1.1  mrg 
   2919  1.1  mrg 	/* Let the debug info back-end know about this call.  We do this only
   2920  1.1  mrg 	   after the instruction has been emitted because labels that may be
   2921  1.1  mrg 	   created to reference the call instruction must appear after it.  */
   2922  1.1  mrg 	if ((debug_variable_location_views || call_insn != NULL)
   2923  1.1  mrg 	    && !DECL_IGNORED_P (current_function_decl))
   2924  1.1  mrg 	  debug_hooks->var_location (insn);
   2925  1.1  mrg 
   2926  1.1  mrg 	current_output_insn = debug_insn = 0;
   2927  1.1  mrg       }
   2928  1.1  mrg     }
   2929  1.1  mrg   return NEXT_INSN (insn);
   2930  1.1  mrg }
   2931  1.1  mrg 
   2932  1.1  mrg /* This is a wrapper around final_scan_insn_1 that allows ports to
   2933  1.1  mrg    call it recursively without a known value for SEEN.  The value is
   2934  1.1  mrg    saved at the outermost call, and recovered for recursive calls.
   2935  1.1  mrg    Recursive calls MUST pass NULL, or the same pointer if they can
   2936  1.1  mrg    otherwise get to it.  */
   2937  1.1  mrg 
   2938  1.1  mrg rtx_insn *
   2939  1.1  mrg final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p,
   2940  1.1  mrg 		 int nopeepholes, int *seen)
   2941  1.1  mrg {
   2942  1.1  mrg   static int *enclosing_seen;
   2943  1.1  mrg   static int recursion_counter;
   2944  1.1  mrg 
   2945  1.1  mrg   gcc_assert (seen || recursion_counter);
   2946  1.1  mrg   gcc_assert (!recursion_counter || !seen || seen == enclosing_seen);
   2947  1.1  mrg 
   2948  1.1  mrg   if (!recursion_counter++)
   2949  1.1  mrg     enclosing_seen = seen;
   2950  1.1  mrg   else if (!seen)
   2951  1.1  mrg     seen = enclosing_seen;
   2952  1.1  mrg 
   2953  1.1  mrg   rtx_insn *ret = final_scan_insn_1 (insn, file, optimize_p, nopeepholes, seen);
   2954  1.1  mrg 
   2955  1.1  mrg   if (!--recursion_counter)
   2956  1.1  mrg     enclosing_seen = NULL;
   2957  1.1  mrg 
   2958  1.1  mrg   return ret;
   2959  1.1  mrg }
   2960  1.1  mrg 
   2961  1.1  mrg 
   2962  1.1  mrg 
   2964  1.1  mrg /* Map DECLs to instance discriminators.  This is allocated and
   2965  1.1  mrg    defined in ada/gcc-interfaces/trans.cc, when compiling with -gnateS.
   2966  1.1  mrg    Mappings from this table are saved and restored for LTO, so
   2967  1.1  mrg    link-time compilation will have this map set, at least in
   2968  1.1  mrg    partitions containing at least one DECL with an associated instance
   2969  1.1  mrg    discriminator.  */
   2970  1.1  mrg 
   2971  1.1  mrg decl_to_instance_map_t *decl_to_instance_map;
   2972  1.1  mrg 
   2973  1.1  mrg /* Return the instance number assigned to DECL.  */
   2974  1.1  mrg 
   2975  1.1  mrg static inline int
   2976  1.1  mrg map_decl_to_instance (const_tree decl)
   2977  1.1  mrg {
   2978  1.1  mrg   int *inst;
   2979  1.1  mrg 
   2980  1.1  mrg   if (!decl_to_instance_map || !decl || !DECL_P (decl))
   2981  1.1  mrg     return 0;
   2982  1.1  mrg 
   2983  1.1  mrg   inst = decl_to_instance_map->get (decl);
   2984  1.1  mrg 
   2985  1.1  mrg   if (!inst)
   2986  1.1  mrg     return 0;
   2987  1.1  mrg 
   2988  1.1  mrg   return *inst;
   2989  1.1  mrg }
   2990  1.1  mrg 
   2991  1.1  mrg /* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC.  */
   2992  1.1  mrg 
   2993  1.1  mrg static inline int
   2994  1.1  mrg compute_discriminator (location_t loc)
   2995  1.1  mrg {
   2996  1.1  mrg   int discriminator;
   2997  1.1  mrg 
   2998  1.1  mrg   if (!decl_to_instance_map)
   2999  1.1  mrg     discriminator = bb_discriminator;
   3000  1.1  mrg   else
   3001  1.1  mrg     {
   3002  1.1  mrg       tree block = LOCATION_BLOCK (loc);
   3003  1.1  mrg 
   3004  1.1  mrg       while (block && TREE_CODE (block) == BLOCK
   3005  1.1  mrg 	     && !inlined_function_outer_scope_p (block))
   3006  1.1  mrg 	block = BLOCK_SUPERCONTEXT (block);
   3007  1.1  mrg 
   3008  1.1  mrg       tree decl;
   3009  1.1  mrg 
   3010  1.1  mrg       if (!block)
   3011  1.1  mrg 	decl = current_function_decl;
   3012  1.1  mrg       else if (DECL_P (block))
   3013  1.1  mrg 	decl = block;
   3014  1.1  mrg       else
   3015  1.1  mrg 	decl = block_ultimate_origin (block);
   3016  1.1  mrg 
   3017  1.1  mrg       discriminator = map_decl_to_instance (decl);
   3018  1.1  mrg     }
   3019  1.1  mrg 
   3020  1.1  mrg   return discriminator;
   3021  1.1  mrg }
   3022  1.1  mrg 
   3023  1.1  mrg /* Return whether a source line note needs to be emitted before INSN.
   3024  1.1  mrg    Sets IS_STMT to TRUE if the line should be marked as a possible
   3025  1.1  mrg    breakpoint location.  */
   3026  1.1  mrg 
   3027  1.1  mrg static bool
   3028  1.1  mrg notice_source_line (rtx_insn *insn, bool *is_stmt)
   3029  1.1  mrg {
   3030  1.1  mrg   const char *filename;
   3031  1.1  mrg   int linenum, columnnum;
   3032  1.1  mrg 
   3033  1.1  mrg   if (NOTE_MARKER_P (insn))
   3034  1.1  mrg     {
   3035  1.1  mrg       location_t loc = NOTE_MARKER_LOCATION (insn);
   3036  1.1  mrg       expanded_location xloc = expand_location (loc);
   3037  1.1  mrg       if (xloc.line == 0
   3038  1.1  mrg 	  && (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION
   3039  1.1  mrg 	      || LOCATION_LOCUS (loc) == BUILTINS_LOCATION))
   3040  1.1  mrg 	return false;
   3041  1.1  mrg 
   3042  1.1  mrg       filename = xloc.file;
   3043  1.1  mrg       linenum = xloc.line;
   3044  1.1  mrg       columnnum = xloc.column;
   3045  1.1  mrg       discriminator = compute_discriminator (loc);
   3046  1.1  mrg       force_source_line = true;
   3047  1.1  mrg     }
   3048  1.1  mrg   else if (override_filename)
   3049  1.1  mrg     {
   3050  1.1  mrg       filename = override_filename;
   3051  1.1  mrg       linenum = override_linenum;
   3052  1.1  mrg       columnnum = override_columnnum;
   3053  1.1  mrg       discriminator = override_discriminator;
   3054  1.1  mrg     }
   3055  1.1  mrg   else if (INSN_HAS_LOCATION (insn))
   3056  1.1  mrg     {
   3057  1.1  mrg       expanded_location xloc = insn_location (insn);
   3058  1.1  mrg       filename = xloc.file;
   3059  1.1  mrg       linenum = xloc.line;
   3060  1.1  mrg       columnnum = xloc.column;
   3061  1.1  mrg       discriminator = compute_discriminator (INSN_LOCATION (insn));
   3062  1.1  mrg     }
   3063  1.1  mrg   else
   3064  1.1  mrg     {
   3065  1.1  mrg       filename = NULL;
   3066  1.1  mrg       linenum = 0;
   3067  1.1  mrg       columnnum = 0;
   3068  1.1  mrg       discriminator = 0;
   3069  1.1  mrg     }
   3070  1.1  mrg 
   3071  1.1  mrg   if (filename == NULL)
   3072  1.1  mrg     return false;
   3073  1.1  mrg 
   3074  1.1  mrg   if (force_source_line
   3075  1.1  mrg       || filename != last_filename
   3076  1.1  mrg       || last_linenum != linenum
   3077  1.1  mrg       || (debug_column_info && last_columnnum != columnnum))
   3078  1.1  mrg     {
   3079  1.1  mrg       force_source_line = false;
   3080  1.1  mrg       last_filename = filename;
   3081  1.1  mrg       last_linenum = linenum;
   3082  1.1  mrg       last_columnnum = columnnum;
   3083  1.1  mrg       last_discriminator = discriminator;
   3084  1.1  mrg       if (is_stmt)
   3085  1.1  mrg 	*is_stmt = true;
   3086  1.1  mrg       high_block_linenum = MAX (last_linenum, high_block_linenum);
   3087  1.1  mrg       high_function_linenum = MAX (last_linenum, high_function_linenum);
   3088  1.1  mrg       return true;
   3089  1.1  mrg     }
   3090  1.1  mrg 
   3091  1.1  mrg   if (SUPPORTS_DISCRIMINATOR && last_discriminator != discriminator)
   3092  1.1  mrg     {
   3093  1.1  mrg       /* If the discriminator changed, but the line number did not,
   3094  1.1  mrg          output the line table entry with is_stmt false so the
   3095  1.1  mrg          debugger does not treat this as a breakpoint location.  */
   3096  1.1  mrg       last_discriminator = discriminator;
   3097  1.1  mrg       if (is_stmt)
   3098  1.1  mrg 	*is_stmt = false;
   3099  1.1  mrg       return true;
   3100  1.1  mrg     }
   3101  1.1  mrg 
   3102  1.1  mrg   return false;
   3103  1.1  mrg }
   3104  1.1  mrg 
   3105  1.1  mrg /* For each operand in INSN, simplify (subreg (reg)) so that it refers
   3107  1.1  mrg    directly to the desired hard register.  */
   3108  1.1  mrg 
   3109  1.1  mrg void
   3110  1.1  mrg cleanup_subreg_operands (rtx_insn *insn)
   3111  1.1  mrg {
   3112  1.1  mrg   int i;
   3113  1.1  mrg   bool changed = false;
   3114  1.1  mrg   extract_insn_cached (insn);
   3115  1.1  mrg   for (i = 0; i < recog_data.n_operands; i++)
   3116  1.1  mrg     {
   3117  1.1  mrg       /* The following test cannot use recog_data.operand when testing
   3118  1.1  mrg 	 for a SUBREG: the underlying object might have been changed
   3119  1.1  mrg 	 already if we are inside a match_operator expression that
   3120  1.1  mrg 	 matches the else clause.  Instead we test the underlying
   3121  1.1  mrg 	 expression directly.  */
   3122  1.1  mrg       if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
   3123  1.1  mrg 	{
   3124  1.1  mrg 	  recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true);
   3125  1.1  mrg 	  changed = true;
   3126  1.1  mrg 	}
   3127  1.1  mrg       else if (GET_CODE (recog_data.operand[i]) == PLUS
   3128  1.1  mrg 	       || GET_CODE (recog_data.operand[i]) == MULT
   3129  1.1  mrg 	       || MEM_P (recog_data.operand[i]))
   3130  1.1  mrg 	recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed);
   3131  1.1  mrg     }
   3132  1.1  mrg 
   3133  1.1  mrg   for (i = 0; i < recog_data.n_dups; i++)
   3134  1.1  mrg     {
   3135  1.1  mrg       if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
   3136  1.1  mrg 	{
   3137  1.1  mrg 	  *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true);
   3138  1.1  mrg 	  changed = true;
   3139  1.1  mrg 	}
   3140  1.1  mrg       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
   3141  1.1  mrg 	       || GET_CODE (*recog_data.dup_loc[i]) == MULT
   3142  1.1  mrg 	       || MEM_P (*recog_data.dup_loc[i]))
   3143  1.1  mrg 	*recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed);
   3144  1.1  mrg     }
   3145  1.1  mrg   if (changed)
   3146  1.1  mrg     df_insn_rescan (insn);
   3147  1.1  mrg }
   3148  1.1  mrg 
   3149  1.1  mrg /* If X is a SUBREG, try to replace it with a REG or a MEM, based on
   3150  1.1  mrg    the thing it is a subreg of.  Do it anyway if FINAL_P.  */
   3151  1.1  mrg 
   3152  1.1  mrg rtx
   3153  1.1  mrg alter_subreg (rtx *xp, bool final_p)
   3154  1.1  mrg {
   3155  1.1  mrg   rtx x = *xp;
   3156  1.1  mrg   rtx y = SUBREG_REG (x);
   3157  1.1  mrg 
   3158  1.1  mrg   /* simplify_subreg does not remove subreg from volatile references.
   3159  1.1  mrg      We are required to.  */
   3160  1.1  mrg   if (MEM_P (y))
   3161  1.1  mrg     {
   3162  1.1  mrg       poly_int64 offset = SUBREG_BYTE (x);
   3163  1.1  mrg 
   3164  1.1  mrg       /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
   3165  1.1  mrg 	 contains 0 instead of the proper offset.  See simplify_subreg.  */
   3166  1.1  mrg       if (paradoxical_subreg_p (x))
   3167  1.1  mrg 	offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
   3168  1.1  mrg 
   3169  1.1  mrg       if (final_p)
   3170  1.1  mrg 	*xp = adjust_address (y, GET_MODE (x), offset);
   3171  1.1  mrg       else
   3172  1.1  mrg 	*xp = adjust_address_nv (y, GET_MODE (x), offset);
   3173  1.1  mrg     }
   3174  1.1  mrg   else if (REG_P (y) && HARD_REGISTER_P (y))
   3175  1.1  mrg     {
   3176  1.1  mrg       rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
   3177  1.1  mrg 				     SUBREG_BYTE (x));
   3178  1.1  mrg 
   3179  1.1  mrg       if (new_rtx != 0)
   3180  1.1  mrg 	*xp = new_rtx;
   3181  1.1  mrg       else if (final_p && REG_P (y))
   3182  1.1  mrg 	{
   3183  1.1  mrg 	  /* Simplify_subreg can't handle some REG cases, but we have to.  */
   3184  1.1  mrg 	  unsigned int regno;
   3185  1.1  mrg 	  poly_int64 offset;
   3186  1.1  mrg 
   3187  1.1  mrg 	  regno = subreg_regno (x);
   3188  1.1  mrg 	  if (subreg_lowpart_p (x))
   3189  1.1  mrg 	    offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
   3190  1.1  mrg 	  else
   3191  1.1  mrg 	    offset = SUBREG_BYTE (x);
   3192  1.1  mrg 	  *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset);
   3193  1.1  mrg 	}
   3194  1.1  mrg     }
   3195  1.1  mrg 
   3196  1.1  mrg   return *xp;
   3197  1.1  mrg }
   3198  1.1  mrg 
   3199  1.1  mrg /* Do alter_subreg on all the SUBREGs contained in X.  */
   3200  1.1  mrg 
   3201  1.1  mrg static rtx
   3202  1.1  mrg walk_alter_subreg (rtx *xp, bool *changed)
   3203  1.1  mrg {
   3204  1.1  mrg   rtx x = *xp;
   3205  1.1  mrg   switch (GET_CODE (x))
   3206  1.1  mrg     {
   3207  1.1  mrg     case PLUS:
   3208  1.1  mrg     case MULT:
   3209  1.1  mrg     case AND:
   3210  1.1  mrg       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
   3211  1.1  mrg       XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed);
   3212  1.1  mrg       break;
   3213  1.1  mrg 
   3214  1.1  mrg     case MEM:
   3215  1.1  mrg     case ZERO_EXTEND:
   3216  1.1  mrg       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
   3217  1.1  mrg       break;
   3218  1.1  mrg 
   3219  1.1  mrg     case SUBREG:
   3220  1.1  mrg       *changed = true;
   3221  1.1  mrg       return alter_subreg (xp, true);
   3222  1.1  mrg 
   3223  1.1  mrg     default:
   3224  1.1  mrg       break;
   3225  1.1  mrg     }
   3226  1.1  mrg 
   3227  1.1  mrg   return *xp;
   3228  1.1  mrg }
   3229  1.1  mrg 
   3230  1.1  mrg /* Report inconsistency between the assembler template and the operands.
   3232  1.1  mrg    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
   3233  1.1  mrg 
   3234  1.1  mrg void
   3235  1.1  mrg output_operand_lossage (const char *cmsgid, ...)
   3236  1.1  mrg {
   3237  1.1  mrg   char *fmt_string;
   3238  1.1  mrg   char *new_message;
   3239  1.1  mrg   const char *pfx_str;
   3240  1.1  mrg   va_list ap;
   3241  1.1  mrg 
   3242  1.1  mrg   va_start (ap, cmsgid);
   3243  1.1  mrg 
   3244  1.1  mrg   pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
   3245  1.1  mrg   fmt_string = xasprintf ("%s%s", pfx_str, _(cmsgid));
   3246  1.1  mrg   new_message = xvasprintf (fmt_string, ap);
   3247  1.1  mrg 
   3248  1.1  mrg   if (this_is_asm_operands)
   3249  1.1  mrg     error_for_asm (this_is_asm_operands, "%s", new_message);
   3250  1.1  mrg   else
   3251  1.1  mrg     internal_error ("%s", new_message);
   3252  1.1  mrg 
   3253  1.1  mrg   free (fmt_string);
   3254  1.1  mrg   free (new_message);
   3255  1.1  mrg   va_end (ap);
   3256  1.1  mrg }
   3257  1.1  mrg 
   3258  1.1  mrg /* Output of assembler code from a template, and its subroutines.  */
   3260  1.1  mrg 
   3261  1.1  mrg /* Annotate the assembly with a comment describing the pattern and
   3262  1.1  mrg    alternative used.  */
   3263  1.1  mrg 
   3264  1.1  mrg static void
   3265  1.1  mrg output_asm_name (void)
   3266  1.1  mrg {
   3267  1.1  mrg   if (debug_insn)
   3268  1.1  mrg     {
   3269  1.1  mrg       fprintf (asm_out_file, "\t%s %d\t",
   3270  1.1  mrg 	       ASM_COMMENT_START, INSN_UID (debug_insn));
   3271  1.1  mrg 
   3272  1.1  mrg       fprintf (asm_out_file, "[c=%d",
   3273  1.1  mrg 	       insn_cost (debug_insn, optimize_insn_for_speed_p ()));
   3274  1.1  mrg       if (HAVE_ATTR_length)
   3275  1.1  mrg 	fprintf (asm_out_file, " l=%d",
   3276  1.1  mrg 		 get_attr_length (debug_insn));
   3277  1.1  mrg       fprintf (asm_out_file, "]  ");
   3278  1.1  mrg 
   3279  1.1  mrg       int num = INSN_CODE (debug_insn);
   3280  1.1  mrg       fprintf (asm_out_file, "%s", insn_data[num].name);
   3281  1.1  mrg       if (insn_data[num].n_alternatives > 1)
   3282  1.1  mrg 	fprintf (asm_out_file, "/%d", which_alternative);
   3283  1.1  mrg 
   3284  1.1  mrg       /* Clear this so only the first assembler insn
   3285  1.1  mrg 	 of any rtl insn will get the special comment for -dp.  */
   3286  1.1  mrg       debug_insn = 0;
   3287  1.1  mrg     }
   3288  1.1  mrg }
   3289  1.1  mrg 
   3290  1.1  mrg /* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it
   3291  1.1  mrg    or its address, return that expr .  Set *PADDRESSP to 1 if the expr
   3292  1.1  mrg    corresponds to the address of the object and 0 if to the object.  */
   3293  1.1  mrg 
   3294  1.1  mrg static tree
   3295  1.1  mrg get_mem_expr_from_op (rtx op, int *paddressp)
   3296  1.1  mrg {
   3297  1.1  mrg   tree expr;
   3298  1.1  mrg   int inner_addressp;
   3299  1.1  mrg 
   3300  1.1  mrg   *paddressp = 0;
   3301  1.1  mrg 
   3302  1.1  mrg   if (REG_P (op))
   3303  1.1  mrg     return REG_EXPR (op);
   3304  1.1  mrg   else if (!MEM_P (op))
   3305  1.1  mrg     return 0;
   3306  1.1  mrg 
   3307  1.1  mrg   if (MEM_EXPR (op) != 0)
   3308  1.1  mrg     return MEM_EXPR (op);
   3309  1.1  mrg 
   3310  1.1  mrg   /* Otherwise we have an address, so indicate it and look at the address.  */
   3311  1.1  mrg   *paddressp = 1;
   3312  1.1  mrg   op = XEXP (op, 0);
   3313  1.1  mrg 
   3314  1.1  mrg   /* First check if we have a decl for the address, then look at the right side
   3315  1.1  mrg      if it is a PLUS.  Otherwise, strip off arithmetic and keep looking.
   3316  1.1  mrg      But don't allow the address to itself be indirect.  */
   3317  1.1  mrg   if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp)
   3318  1.1  mrg     return expr;
   3319  1.1  mrg   else if (GET_CODE (op) == PLUS
   3320  1.1  mrg 	   && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
   3321  1.1  mrg     return expr;
   3322  1.1  mrg 
   3323  1.1  mrg   while (UNARY_P (op)
   3324  1.1  mrg 	 || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
   3325  1.1  mrg     op = XEXP (op, 0);
   3326  1.1  mrg 
   3327  1.1  mrg   expr = get_mem_expr_from_op (op, &inner_addressp);
   3328  1.1  mrg   return inner_addressp ? 0 : expr;
   3329  1.1  mrg }
   3330  1.1  mrg 
   3331  1.1  mrg /* Output operand names for assembler instructions.  OPERANDS is the
   3332  1.1  mrg    operand vector, OPORDER is the order to write the operands, and NOPS
   3333  1.1  mrg    is the number of operands to write.  */
   3334  1.1  mrg 
   3335  1.1  mrg static void
   3336  1.1  mrg output_asm_operand_names (rtx *operands, int *oporder, int nops)
   3337  1.1  mrg {
   3338  1.1  mrg   int wrote = 0;
   3339  1.1  mrg   int i;
   3340  1.1  mrg 
   3341  1.1  mrg   for (i = 0; i < nops; i++)
   3342  1.1  mrg     {
   3343  1.1  mrg       int addressp;
   3344  1.1  mrg       rtx op = operands[oporder[i]];
   3345  1.1  mrg       tree expr = get_mem_expr_from_op (op, &addressp);
   3346  1.1  mrg 
   3347  1.1  mrg       fprintf (asm_out_file, "%c%s",
   3348  1.1  mrg 	       wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
   3349  1.1  mrg       wrote = 1;
   3350  1.1  mrg       if (expr)
   3351  1.1  mrg 	{
   3352  1.1  mrg 	  fprintf (asm_out_file, "%s",
   3353  1.1  mrg 		   addressp ? "*" : "");
   3354  1.1  mrg 	  print_mem_expr (asm_out_file, expr);
   3355  1.1  mrg 	  wrote = 1;
   3356  1.1  mrg 	}
   3357  1.1  mrg       else if (REG_P (op) && ORIGINAL_REGNO (op)
   3358  1.1  mrg 	       && ORIGINAL_REGNO (op) != REGNO (op))
   3359  1.1  mrg 	fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
   3360  1.1  mrg     }
   3361  1.1  mrg }
   3362  1.1  mrg 
   3363  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3364  1.1  mrg /* Helper function to parse assembler dialects in the asm string.
   3365  1.1  mrg    This is called from output_asm_insn and asm_fprintf.  */
   3366  1.1  mrg static const char *
   3367  1.1  mrg do_assembler_dialects (const char *p, int *dialect)
   3368  1.1  mrg {
   3369  1.1  mrg   char c = *(p - 1);
   3370  1.1  mrg 
   3371  1.1  mrg   switch (c)
   3372  1.1  mrg     {
   3373  1.1  mrg     case '{':
   3374  1.1  mrg       {
   3375  1.1  mrg         int i;
   3376  1.1  mrg 
   3377  1.1  mrg         if (*dialect)
   3378  1.1  mrg           output_operand_lossage ("nested assembly dialect alternatives");
   3379  1.1  mrg         else
   3380  1.1  mrg           *dialect = 1;
   3381  1.1  mrg 
   3382  1.1  mrg         /* If we want the first dialect, do nothing.  Otherwise, skip
   3383  1.1  mrg            DIALECT_NUMBER of strings ending with '|'.  */
   3384  1.1  mrg         for (i = 0; i < dialect_number; i++)
   3385  1.1  mrg           {
   3386  1.1  mrg             while (*p && *p != '}')
   3387  1.1  mrg 	      {
   3388  1.1  mrg 		if (*p == '|')
   3389  1.1  mrg 		  {
   3390  1.1  mrg 		    p++;
   3391  1.1  mrg 		    break;
   3392  1.1  mrg 		  }
   3393  1.1  mrg 
   3394  1.1  mrg 		/* Skip over any character after a percent sign.  */
   3395  1.1  mrg 		if (*p == '%')
   3396  1.1  mrg 		  p++;
   3397  1.1  mrg 		if (*p)
   3398  1.1  mrg 		  p++;
   3399  1.1  mrg 	      }
   3400  1.1  mrg 
   3401  1.1  mrg             if (*p == '}')
   3402  1.1  mrg 	      break;
   3403  1.1  mrg           }
   3404  1.1  mrg 
   3405  1.1  mrg         if (*p == '\0')
   3406  1.1  mrg           output_operand_lossage ("unterminated assembly dialect alternative");
   3407  1.1  mrg       }
   3408  1.1  mrg       break;
   3409  1.1  mrg 
   3410  1.1  mrg     case '|':
   3411  1.1  mrg       if (*dialect)
   3412  1.1  mrg         {
   3413  1.1  mrg           /* Skip to close brace.  */
   3414  1.1  mrg           do
   3415  1.1  mrg             {
   3416  1.1  mrg 	      if (*p == '\0')
   3417  1.1  mrg 		{
   3418  1.1  mrg 		  output_operand_lossage ("unterminated assembly dialect alternative");
   3419  1.1  mrg 		  break;
   3420  1.1  mrg 		}
   3421  1.1  mrg 
   3422  1.1  mrg 	      /* Skip over any character after a percent sign.  */
   3423  1.1  mrg 	      if (*p == '%' && p[1])
   3424  1.1  mrg 		{
   3425  1.1  mrg 		  p += 2;
   3426  1.1  mrg 		  continue;
   3427  1.1  mrg 		}
   3428  1.1  mrg 
   3429  1.1  mrg 	      if (*p++ == '}')
   3430  1.1  mrg 		break;
   3431  1.1  mrg             }
   3432  1.1  mrg           while (1);
   3433  1.1  mrg 
   3434  1.1  mrg           *dialect = 0;
   3435  1.1  mrg         }
   3436  1.1  mrg       else
   3437  1.1  mrg         putc (c, asm_out_file);
   3438  1.1  mrg       break;
   3439  1.1  mrg 
   3440  1.1  mrg     case '}':
   3441  1.1  mrg       if (! *dialect)
   3442  1.1  mrg         putc (c, asm_out_file);
   3443  1.1  mrg       *dialect = 0;
   3444  1.1  mrg       break;
   3445  1.1  mrg     default:
   3446  1.1  mrg       gcc_unreachable ();
   3447  1.1  mrg     }
   3448  1.1  mrg 
   3449  1.1  mrg   return p;
   3450  1.1  mrg }
   3451  1.1  mrg #endif
   3452  1.1  mrg 
   3453  1.1  mrg /* Output text from TEMPLATE to the assembler output file,
   3454  1.1  mrg    obeying %-directions to substitute operands taken from
   3455  1.1  mrg    the vector OPERANDS.
   3456  1.1  mrg 
   3457  1.1  mrg    %N (for N a digit) means print operand N in usual manner.
   3458  1.1  mrg    %lN means require operand N to be a CODE_LABEL or LABEL_REF
   3459  1.1  mrg       and print the label name with no punctuation.
   3460  1.1  mrg    %cN means require operand N to be a constant
   3461  1.1  mrg       and print the constant expression with no punctuation.
   3462  1.1  mrg    %aN means expect operand N to be a memory address
   3463  1.1  mrg       (not a memory reference!) and print a reference
   3464  1.1  mrg       to that address.
   3465  1.1  mrg    %nN means expect operand N to be a constant
   3466  1.1  mrg       and print a constant expression for minus the value
   3467  1.1  mrg       of the operand, with no other punctuation.  */
   3468  1.1  mrg 
   3469  1.1  mrg void
   3470  1.1  mrg output_asm_insn (const char *templ, rtx *operands)
   3471  1.1  mrg {
   3472  1.1  mrg   const char *p;
   3473  1.1  mrg   int c;
   3474  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3475  1.1  mrg   int dialect = 0;
   3476  1.1  mrg #endif
   3477  1.1  mrg   int oporder[MAX_RECOG_OPERANDS];
   3478  1.1  mrg   char opoutput[MAX_RECOG_OPERANDS];
   3479  1.1  mrg   int ops = 0;
   3480  1.1  mrg 
   3481  1.1  mrg   /* An insn may return a null string template
   3482  1.1  mrg      in a case where no assembler code is needed.  */
   3483  1.1  mrg   if (*templ == 0)
   3484  1.1  mrg     return;
   3485  1.1  mrg 
   3486  1.1  mrg   memset (opoutput, 0, sizeof opoutput);
   3487  1.1  mrg   p = templ;
   3488  1.1  mrg   putc ('\t', asm_out_file);
   3489  1.1  mrg 
   3490  1.1  mrg #ifdef ASM_OUTPUT_OPCODE
   3491  1.1  mrg   ASM_OUTPUT_OPCODE (asm_out_file, p);
   3492  1.1  mrg #endif
   3493  1.1  mrg 
   3494  1.1  mrg   while ((c = *p++))
   3495  1.1  mrg     switch (c)
   3496  1.1  mrg       {
   3497  1.1  mrg       case '\n':
   3498  1.1  mrg 	if (flag_verbose_asm)
   3499  1.1  mrg 	  output_asm_operand_names (operands, oporder, ops);
   3500  1.1  mrg 	if (flag_print_asm_name)
   3501  1.1  mrg 	  output_asm_name ();
   3502  1.1  mrg 
   3503  1.1  mrg 	ops = 0;
   3504  1.1  mrg 	memset (opoutput, 0, sizeof opoutput);
   3505  1.1  mrg 
   3506  1.1  mrg 	putc (c, asm_out_file);
   3507  1.1  mrg #ifdef ASM_OUTPUT_OPCODE
   3508  1.1  mrg 	while ((c = *p) == '\t')
   3509  1.1  mrg 	  {
   3510  1.1  mrg 	    putc (c, asm_out_file);
   3511  1.1  mrg 	    p++;
   3512  1.1  mrg 	  }
   3513  1.1  mrg 	ASM_OUTPUT_OPCODE (asm_out_file, p);
   3514  1.1  mrg #endif
   3515  1.1  mrg 	break;
   3516  1.1  mrg 
   3517  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3518  1.1  mrg       case '{':
   3519  1.1  mrg       case '}':
   3520  1.1  mrg       case '|':
   3521  1.1  mrg 	p = do_assembler_dialects (p, &dialect);
   3522  1.1  mrg 	break;
   3523  1.1  mrg #endif
   3524  1.1  mrg 
   3525  1.1  mrg       case '%':
   3526  1.1  mrg 	/* %% outputs a single %.  %{, %} and %| print {, } and | respectively
   3527  1.1  mrg 	   if ASSEMBLER_DIALECT defined and these characters have a special
   3528  1.1  mrg 	   meaning as dialect delimiters.*/
   3529  1.1  mrg 	if (*p == '%'
   3530  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3531  1.1  mrg 	    || *p == '{' || *p == '}' || *p == '|'
   3532  1.1  mrg #endif
   3533  1.1  mrg 	    )
   3534  1.1  mrg 	  {
   3535  1.1  mrg 	    putc (*p, asm_out_file);
   3536  1.1  mrg 	    p++;
   3537  1.1  mrg 	  }
   3538  1.1  mrg 	/* %= outputs a number which is unique to each insn in the entire
   3539  1.1  mrg 	   compilation.  This is useful for making local labels that are
   3540  1.1  mrg 	   referred to more than once in a given insn.  */
   3541  1.1  mrg 	else if (*p == '=')
   3542  1.1  mrg 	  {
   3543  1.1  mrg 	    p++;
   3544  1.1  mrg 	    fprintf (asm_out_file, "%d", insn_counter);
   3545  1.1  mrg 	  }
   3546  1.1  mrg 	/* % followed by a letter and some digits
   3547  1.1  mrg 	   outputs an operand in a special way depending on the letter.
   3548  1.1  mrg 	   Letters `acln' are implemented directly.
   3549  1.1  mrg 	   Other letters are passed to `output_operand' so that
   3550  1.1  mrg 	   the TARGET_PRINT_OPERAND hook can define them.  */
   3551  1.1  mrg 	else if (ISALPHA (*p))
   3552  1.1  mrg 	  {
   3553  1.1  mrg 	    int letter = *p++;
   3554  1.1  mrg 	    unsigned long opnum;
   3555  1.1  mrg 	    char *endptr;
   3556  1.1  mrg 
   3557  1.1  mrg 	    opnum = strtoul (p, &endptr, 10);
   3558  1.1  mrg 
   3559  1.1  mrg 	    if (endptr == p)
   3560  1.1  mrg 	      output_operand_lossage ("operand number missing "
   3561  1.1  mrg 				      "after %%-letter");
   3562  1.1  mrg 	    else if (this_is_asm_operands && opnum >= insn_noperands)
   3563  1.1  mrg 	      output_operand_lossage ("operand number out of range");
   3564  1.1  mrg 	    else if (letter == 'l')
   3565  1.1  mrg 	      output_asm_label (operands[opnum]);
   3566  1.1  mrg 	    else if (letter == 'a')
   3567  1.1  mrg 	      output_address (VOIDmode, operands[opnum]);
   3568  1.1  mrg 	    else if (letter == 'c')
   3569  1.1  mrg 	      {
   3570  1.1  mrg 		if (CONSTANT_ADDRESS_P (operands[opnum]))
   3571  1.1  mrg 		  output_addr_const (asm_out_file, operands[opnum]);
   3572  1.1  mrg 		else
   3573  1.1  mrg 		  output_operand (operands[opnum], 'c');
   3574  1.1  mrg 	      }
   3575  1.1  mrg 	    else if (letter == 'n')
   3576  1.1  mrg 	      {
   3577  1.1  mrg 		if (CONST_INT_P (operands[opnum]))
   3578  1.1  mrg 		  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
   3579  1.1  mrg 			   - INTVAL (operands[opnum]));
   3580  1.1  mrg 		else
   3581  1.1  mrg 		  {
   3582  1.1  mrg 		    putc ('-', asm_out_file);
   3583  1.1  mrg 		    output_addr_const (asm_out_file, operands[opnum]);
   3584  1.1  mrg 		  }
   3585  1.1  mrg 	      }
   3586  1.1  mrg 	    else
   3587  1.1  mrg 	      output_operand (operands[opnum], letter);
   3588  1.1  mrg 
   3589  1.1  mrg 	    if (!opoutput[opnum])
   3590  1.1  mrg 	      oporder[ops++] = opnum;
   3591  1.1  mrg 	    opoutput[opnum] = 1;
   3592  1.1  mrg 
   3593  1.1  mrg 	    p = endptr;
   3594  1.1  mrg 	    c = *p;
   3595  1.1  mrg 	  }
   3596  1.1  mrg 	/* % followed by a digit outputs an operand the default way.  */
   3597  1.1  mrg 	else if (ISDIGIT (*p))
   3598  1.1  mrg 	  {
   3599  1.1  mrg 	    unsigned long opnum;
   3600  1.1  mrg 	    char *endptr;
   3601  1.1  mrg 
   3602  1.1  mrg 	    opnum = strtoul (p, &endptr, 10);
   3603  1.1  mrg 	    if (this_is_asm_operands && opnum >= insn_noperands)
   3604  1.1  mrg 	      output_operand_lossage ("operand number out of range");
   3605  1.1  mrg 	    else
   3606  1.1  mrg 	      output_operand (operands[opnum], 0);
   3607  1.1  mrg 
   3608  1.1  mrg 	    if (!opoutput[opnum])
   3609  1.1  mrg 	      oporder[ops++] = opnum;
   3610  1.1  mrg 	    opoutput[opnum] = 1;
   3611  1.1  mrg 
   3612  1.1  mrg 	    p = endptr;
   3613  1.1  mrg 	    c = *p;
   3614  1.1  mrg 	  }
   3615  1.1  mrg 	/* % followed by punctuation: output something for that
   3616  1.1  mrg 	   punctuation character alone, with no operand.  The
   3617  1.1  mrg 	   TARGET_PRINT_OPERAND hook decides what is actually done.  */
   3618  1.1  mrg 	else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p))
   3619  1.1  mrg 	  output_operand (NULL_RTX, *p++);
   3620  1.1  mrg 	else
   3621  1.1  mrg 	  output_operand_lossage ("invalid %%-code");
   3622  1.1  mrg 	break;
   3623  1.1  mrg 
   3624  1.1  mrg       default:
   3625  1.1  mrg 	putc (c, asm_out_file);
   3626  1.1  mrg       }
   3627  1.1  mrg 
   3628  1.1  mrg   /* Try to keep the asm a bit more readable.  */
   3629  1.1  mrg   if ((flag_verbose_asm || flag_print_asm_name) && strlen (templ) < 9)
   3630  1.1  mrg     putc ('\t', asm_out_file);
   3631  1.1  mrg 
   3632  1.1  mrg   /* Write out the variable names for operands, if we know them.  */
   3633  1.1  mrg   if (flag_verbose_asm)
   3634  1.1  mrg     output_asm_operand_names (operands, oporder, ops);
   3635  1.1  mrg   if (flag_print_asm_name)
   3636  1.1  mrg     output_asm_name ();
   3637  1.1  mrg 
   3638  1.1  mrg   putc ('\n', asm_out_file);
   3639  1.1  mrg }
   3640  1.1  mrg 
   3641  1.1  mrg /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
   3643  1.1  mrg 
   3644  1.1  mrg void
   3645  1.1  mrg output_asm_label (rtx x)
   3646  1.1  mrg {
   3647  1.1  mrg   char buf[256];
   3648  1.1  mrg 
   3649  1.1  mrg   if (GET_CODE (x) == LABEL_REF)
   3650  1.1  mrg     x = label_ref_label (x);
   3651  1.1  mrg   if (LABEL_P (x)
   3652  1.1  mrg       || (NOTE_P (x)
   3653  1.1  mrg 	  && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL))
   3654  1.1  mrg     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   3655  1.1  mrg   else
   3656  1.1  mrg     output_operand_lossage ("'%%l' operand isn't a label");
   3657  1.1  mrg 
   3658  1.1  mrg   assemble_name (asm_out_file, buf);
   3659  1.1  mrg }
   3660  1.1  mrg 
   3661  1.1  mrg /* Marks SYMBOL_REFs in x as referenced through use of assemble_external.  */
   3662  1.1  mrg 
   3663  1.1  mrg void
   3664  1.1  mrg mark_symbol_refs_as_used (rtx x)
   3665  1.1  mrg {
   3666  1.1  mrg   subrtx_iterator::array_type array;
   3667  1.1  mrg   FOR_EACH_SUBRTX (iter, array, x, ALL)
   3668  1.1  mrg     {
   3669  1.1  mrg       const_rtx x = *iter;
   3670  1.1  mrg       if (GET_CODE (x) == SYMBOL_REF)
   3671  1.1  mrg 	if (tree t = SYMBOL_REF_DECL (x))
   3672  1.1  mrg 	  assemble_external (t);
   3673  1.1  mrg     }
   3674  1.1  mrg }
   3675  1.1  mrg 
   3676  1.1  mrg /* Print operand X using machine-dependent assembler syntax.
   3677  1.1  mrg    CODE is a non-digit that preceded the operand-number in the % spec,
   3678  1.1  mrg    such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char
   3679  1.1  mrg    between the % and the digits.
   3680  1.1  mrg    When CODE is a non-letter, X is 0.
   3681  1.1  mrg 
   3682  1.1  mrg    The meanings of the letters are machine-dependent and controlled
   3683  1.1  mrg    by TARGET_PRINT_OPERAND.  */
   3684  1.1  mrg 
   3685  1.1  mrg void
   3686  1.1  mrg output_operand (rtx x, int code ATTRIBUTE_UNUSED)
   3687  1.1  mrg {
   3688  1.1  mrg   if (x && GET_CODE (x) == SUBREG)
   3689  1.1  mrg     x = alter_subreg (&x, true);
   3690  1.1  mrg 
   3691  1.1  mrg   /* X must not be a pseudo reg.  */
   3692  1.1  mrg   if (!targetm.no_register_allocation)
   3693  1.1  mrg     gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
   3694  1.1  mrg 
   3695  1.1  mrg   targetm.asm_out.print_operand (asm_out_file, x, code);
   3696  1.1  mrg 
   3697  1.1  mrg   if (x == NULL_RTX)
   3698  1.1  mrg     return;
   3699  1.1  mrg 
   3700  1.1  mrg   mark_symbol_refs_as_used (x);
   3701  1.1  mrg }
   3702  1.1  mrg 
   3703  1.1  mrg /* Print a memory reference operand for address X using
   3704  1.1  mrg    machine-dependent assembler syntax.  */
   3705  1.1  mrg 
   3706  1.1  mrg void
   3707  1.1  mrg output_address (machine_mode mode, rtx x)
   3708  1.1  mrg {
   3709  1.1  mrg   bool changed = false;
   3710  1.1  mrg   walk_alter_subreg (&x, &changed);
   3711  1.1  mrg   targetm.asm_out.print_operand_address (asm_out_file, mode, x);
   3712  1.1  mrg }
   3713  1.1  mrg 
   3714  1.1  mrg /* Print an integer constant expression in assembler syntax.
   3716  1.1  mrg    Addition and subtraction are the only arithmetic
   3717  1.1  mrg    that may appear in these expressions.  */
   3718  1.1  mrg 
   3719  1.1  mrg void
   3720  1.1  mrg output_addr_const (FILE *file, rtx x)
   3721  1.1  mrg {
   3722  1.1  mrg   char buf[256];
   3723  1.1  mrg 
   3724  1.1  mrg  restart:
   3725  1.1  mrg   switch (GET_CODE (x))
   3726  1.1  mrg     {
   3727  1.1  mrg     case PC:
   3728  1.1  mrg       putc ('.', file);
   3729  1.1  mrg       break;
   3730  1.1  mrg 
   3731  1.1  mrg     case SYMBOL_REF:
   3732  1.1  mrg       if (SYMBOL_REF_DECL (x))
   3733  1.1  mrg 	assemble_external (SYMBOL_REF_DECL (x));
   3734  1.1  mrg #ifdef ASM_OUTPUT_SYMBOL_REF
   3735  1.1  mrg       ASM_OUTPUT_SYMBOL_REF (file, x);
   3736  1.1  mrg #else
   3737  1.1  mrg       assemble_name (file, XSTR (x, 0));
   3738  1.1  mrg #endif
   3739  1.1  mrg       break;
   3740  1.1  mrg 
   3741  1.1  mrg     case LABEL_REF:
   3742  1.1  mrg       x = label_ref_label (x);
   3743  1.1  mrg       /* Fall through.  */
   3744  1.1  mrg     case CODE_LABEL:
   3745  1.1  mrg       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   3746  1.1  mrg #ifdef ASM_OUTPUT_LABEL_REF
   3747  1.1  mrg       ASM_OUTPUT_LABEL_REF (file, buf);
   3748  1.1  mrg #else
   3749  1.1  mrg       assemble_name (file, buf);
   3750  1.1  mrg #endif
   3751  1.1  mrg       break;
   3752  1.1  mrg 
   3753  1.1  mrg     case CONST_INT:
   3754  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
   3755  1.1  mrg       break;
   3756  1.1  mrg 
   3757  1.1  mrg     case CONST:
   3758  1.1  mrg       /* This used to output parentheses around the expression,
   3759  1.1  mrg 	 but that does not work on the 386 (either ATT or BSD assembler).  */
   3760  1.1  mrg       output_addr_const (file, XEXP (x, 0));
   3761  1.1  mrg       break;
   3762  1.1  mrg 
   3763  1.1  mrg     case CONST_WIDE_INT:
   3764  1.1  mrg       /* We do not know the mode here so we have to use a round about
   3765  1.1  mrg 	 way to build a wide-int to get it printed properly.  */
   3766  1.1  mrg       {
   3767  1.1  mrg 	wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0),
   3768  1.1  mrg 					   CONST_WIDE_INT_NUNITS (x),
   3769  1.1  mrg 					   CONST_WIDE_INT_NUNITS (x)
   3770  1.1  mrg 					   * HOST_BITS_PER_WIDE_INT,
   3771  1.1  mrg 					   false);
   3772  1.1  mrg 	print_decs (w, file);
   3773  1.1  mrg       }
   3774  1.1  mrg       break;
   3775  1.1  mrg 
   3776  1.1  mrg     case CONST_DOUBLE:
   3777  1.1  mrg       if (CONST_DOUBLE_AS_INT_P (x))
   3778  1.1  mrg 	{
   3779  1.1  mrg 	  /* We can use %d if the number is one word and positive.  */
   3780  1.1  mrg 	  if (CONST_DOUBLE_HIGH (x))
   3781  1.1  mrg 	    fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
   3782  1.1  mrg 		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
   3783  1.1  mrg 		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
   3784  1.1  mrg 	  else if (CONST_DOUBLE_LOW (x) < 0)
   3785  1.1  mrg 	    fprintf (file, HOST_WIDE_INT_PRINT_HEX,
   3786  1.1  mrg 		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
   3787  1.1  mrg 	  else
   3788  1.1  mrg 	    fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
   3789  1.1  mrg 	}
   3790  1.1  mrg       else
   3791  1.1  mrg 	/* We can't handle floating point constants;
   3792  1.1  mrg 	   PRINT_OPERAND must handle them.  */
   3793  1.1  mrg 	output_operand_lossage ("floating constant misused");
   3794  1.1  mrg       break;
   3795  1.1  mrg 
   3796  1.1  mrg     case CONST_FIXED:
   3797  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
   3798  1.1  mrg       break;
   3799  1.1  mrg 
   3800  1.1  mrg     case PLUS:
   3801  1.1  mrg       /* Some assemblers need integer constants to appear last (eg masm).  */
   3802  1.1  mrg       if (CONST_INT_P (XEXP (x, 0)))
   3803  1.1  mrg 	{
   3804  1.1  mrg 	  output_addr_const (file, XEXP (x, 1));
   3805  1.1  mrg 	  if (INTVAL (XEXP (x, 0)) >= 0)
   3806  1.1  mrg 	    fprintf (file, "+");
   3807  1.1  mrg 	  output_addr_const (file, XEXP (x, 0));
   3808  1.1  mrg 	}
   3809  1.1  mrg       else
   3810  1.1  mrg 	{
   3811  1.1  mrg 	  output_addr_const (file, XEXP (x, 0));
   3812  1.1  mrg 	  if (!CONST_INT_P (XEXP (x, 1))
   3813  1.1  mrg 	      || INTVAL (XEXP (x, 1)) >= 0)
   3814  1.1  mrg 	    fprintf (file, "+");
   3815  1.1  mrg 	  output_addr_const (file, XEXP (x, 1));
   3816  1.1  mrg 	}
   3817  1.1  mrg       break;
   3818  1.1  mrg 
   3819  1.1  mrg     case MINUS:
   3820  1.1  mrg       /* Avoid outputting things like x-x or x+5-x,
   3821  1.1  mrg 	 since some assemblers can't handle that.  */
   3822  1.1  mrg       x = simplify_subtraction (x);
   3823  1.1  mrg       if (GET_CODE (x) != MINUS)
   3824  1.1  mrg 	goto restart;
   3825  1.1  mrg 
   3826  1.1  mrg       output_addr_const (file, XEXP (x, 0));
   3827  1.1  mrg       fprintf (file, "-");
   3828  1.1  mrg       if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
   3829  1.1  mrg 	  || GET_CODE (XEXP (x, 1)) == PC
   3830  1.1  mrg 	  || GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
   3831  1.1  mrg 	output_addr_const (file, XEXP (x, 1));
   3832  1.1  mrg       else
   3833  1.1  mrg 	{
   3834  1.1  mrg 	  fputs (targetm.asm_out.open_paren, file);
   3835  1.1  mrg 	  output_addr_const (file, XEXP (x, 1));
   3836  1.1  mrg 	  fputs (targetm.asm_out.close_paren, file);
   3837  1.1  mrg 	}
   3838  1.1  mrg       break;
   3839  1.1  mrg 
   3840  1.1  mrg     case ZERO_EXTEND:
   3841  1.1  mrg     case SIGN_EXTEND:
   3842  1.1  mrg     case SUBREG:
   3843  1.1  mrg     case TRUNCATE:
   3844  1.1  mrg       output_addr_const (file, XEXP (x, 0));
   3845  1.1  mrg       break;
   3846  1.1  mrg 
   3847  1.1  mrg     default:
   3848  1.1  mrg       if (targetm.asm_out.output_addr_const_extra (file, x))
   3849  1.1  mrg 	break;
   3850  1.1  mrg 
   3851  1.1  mrg       output_operand_lossage ("invalid expression as operand");
   3852  1.1  mrg     }
   3853  1.1  mrg }
   3854  1.1  mrg 
   3855  1.1  mrg /* Output a quoted string.  */
   3857  1.1  mrg 
   3858  1.1  mrg void
   3859  1.1  mrg output_quoted_string (FILE *asm_file, const char *string)
   3860  1.1  mrg {
   3861  1.1  mrg #ifdef OUTPUT_QUOTED_STRING
   3862  1.1  mrg   OUTPUT_QUOTED_STRING (asm_file, string);
   3863  1.1  mrg #else
   3864  1.1  mrg   char c;
   3865  1.1  mrg 
   3866  1.1  mrg   putc ('\"', asm_file);
   3867  1.1  mrg   while ((c = *string++) != 0)
   3868  1.1  mrg     {
   3869  1.1  mrg       if (ISPRINT (c))
   3870  1.1  mrg 	{
   3871  1.1  mrg 	  if (c == '\"' || c == '\\')
   3872  1.1  mrg 	    putc ('\\', asm_file);
   3873  1.1  mrg 	  putc (c, asm_file);
   3874  1.1  mrg 	}
   3875  1.1  mrg       else
   3876  1.1  mrg 	fprintf (asm_file, "\\%03o", (unsigned char) c);
   3877  1.1  mrg     }
   3878  1.1  mrg   putc ('\"', asm_file);
   3879  1.1  mrg #endif
   3880  1.1  mrg }
   3881  1.1  mrg 
   3882  1.1  mrg /* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */
   3884  1.1  mrg 
   3885  1.1  mrg void
   3886  1.1  mrg fprint_whex (FILE *f, unsigned HOST_WIDE_INT value)
   3887  1.1  mrg {
   3888  1.1  mrg   char buf[2 + CHAR_BIT * sizeof (value) / 4];
   3889  1.1  mrg   if (value == 0)
   3890  1.1  mrg     putc ('0', f);
   3891  1.1  mrg   else
   3892  1.1  mrg     {
   3893  1.1  mrg       char *p = buf + sizeof (buf);
   3894  1.1  mrg       do
   3895  1.1  mrg         *--p = "0123456789abcdef"[value % 16];
   3896  1.1  mrg       while ((value /= 16) != 0);
   3897  1.1  mrg       *--p = 'x';
   3898  1.1  mrg       *--p = '0';
   3899  1.1  mrg       fwrite (p, 1, buf + sizeof (buf) - p, f);
   3900  1.1  mrg     }
   3901  1.1  mrg }
   3902  1.1  mrg 
   3903  1.1  mrg /* Internal function that prints an unsigned long in decimal in reverse.
   3904  1.1  mrg    The output string IS NOT null-terminated. */
   3905  1.1  mrg 
   3906  1.1  mrg static int
   3907  1.1  mrg sprint_ul_rev (char *s, unsigned long value)
   3908  1.1  mrg {
   3909  1.1  mrg   int i = 0;
   3910  1.1  mrg   do
   3911  1.1  mrg     {
   3912  1.1  mrg       s[i] = "0123456789"[value % 10];
   3913  1.1  mrg       value /= 10;
   3914  1.1  mrg       i++;
   3915  1.1  mrg       /* alternate version, without modulo */
   3916  1.1  mrg       /* oldval = value; */
   3917  1.1  mrg       /* value /= 10; */
   3918  1.1  mrg       /* s[i] = "0123456789" [oldval - 10*value]; */
   3919  1.1  mrg       /* i++ */
   3920  1.1  mrg     }
   3921  1.1  mrg   while (value != 0);
   3922  1.1  mrg   return i;
   3923  1.1  mrg }
   3924  1.1  mrg 
   3925  1.1  mrg /* Write an unsigned long as decimal to a file, fast. */
   3926  1.1  mrg 
   3927  1.1  mrg void
   3928  1.1  mrg fprint_ul (FILE *f, unsigned long value)
   3929  1.1  mrg {
   3930  1.1  mrg   /* python says: len(str(2**64)) == 20 */
   3931  1.1  mrg   char s[20];
   3932  1.1  mrg   int i;
   3933  1.1  mrg 
   3934  1.1  mrg   i = sprint_ul_rev (s, value);
   3935  1.1  mrg 
   3936  1.1  mrg   /* It's probably too small to bother with string reversal and fputs. */
   3937  1.1  mrg   do
   3938  1.1  mrg     {
   3939  1.1  mrg       i--;
   3940  1.1  mrg       putc (s[i], f);
   3941  1.1  mrg     }
   3942  1.1  mrg   while (i != 0);
   3943  1.1  mrg }
   3944  1.1  mrg 
   3945  1.1  mrg /* Write an unsigned long as decimal to a string, fast.
   3946  1.1  mrg    s must be wide enough to not overflow, at least 21 chars.
   3947  1.1  mrg    Returns the length of the string (without terminating '\0'). */
   3948  1.1  mrg 
   3949  1.1  mrg int
   3950  1.1  mrg sprint_ul (char *s, unsigned long value)
   3951  1.1  mrg {
   3952  1.1  mrg   int len = sprint_ul_rev (s, value);
   3953  1.1  mrg   s[len] = '\0';
   3954  1.1  mrg 
   3955  1.1  mrg   std::reverse (s, s + len);
   3956  1.1  mrg   return len;
   3957  1.1  mrg }
   3958  1.1  mrg 
   3959  1.1  mrg /* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
   3960  1.1  mrg    %R prints the value of REGISTER_PREFIX.
   3961  1.1  mrg    %L prints the value of LOCAL_LABEL_PREFIX.
   3962  1.1  mrg    %U prints the value of USER_LABEL_PREFIX.
   3963  1.1  mrg    %I prints the value of IMMEDIATE_PREFIX.
   3964  1.1  mrg    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
   3965  1.1  mrg    Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%.
   3966  1.1  mrg 
   3967  1.1  mrg    We handle alternate assembler dialects here, just like output_asm_insn.  */
   3968  1.1  mrg 
   3969  1.1  mrg void
   3970  1.1  mrg asm_fprintf (FILE *file, const char *p, ...)
   3971  1.1  mrg {
   3972  1.1  mrg   char buf[10];
   3973  1.1  mrg   char *q, c;
   3974  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3975  1.1  mrg   int dialect = 0;
   3976  1.1  mrg #endif
   3977  1.1  mrg   va_list argptr;
   3978  1.1  mrg 
   3979  1.1  mrg   va_start (argptr, p);
   3980  1.1  mrg 
   3981  1.1  mrg   buf[0] = '%';
   3982  1.1  mrg 
   3983  1.1  mrg   while ((c = *p++))
   3984  1.1  mrg     switch (c)
   3985  1.1  mrg       {
   3986  1.1  mrg #ifdef ASSEMBLER_DIALECT
   3987  1.1  mrg       case '{':
   3988  1.1  mrg       case '}':
   3989  1.1  mrg       case '|':
   3990  1.1  mrg 	p = do_assembler_dialects (p, &dialect);
   3991  1.1  mrg 	break;
   3992  1.1  mrg #endif
   3993  1.1  mrg 
   3994  1.1  mrg       case '%':
   3995  1.1  mrg 	c = *p++;
   3996  1.1  mrg 	q = &buf[1];
   3997  1.1  mrg 	while (strchr ("-+ #0", c))
   3998  1.1  mrg 	  {
   3999  1.1  mrg 	    *q++ = c;
   4000  1.1  mrg 	    c = *p++;
   4001  1.1  mrg 	  }
   4002  1.1  mrg 	while (ISDIGIT (c) || c == '.')
   4003  1.1  mrg 	  {
   4004  1.1  mrg 	    *q++ = c;
   4005  1.1  mrg 	    c = *p++;
   4006  1.1  mrg 	  }
   4007  1.1  mrg 	switch (c)
   4008  1.1  mrg 	  {
   4009  1.1  mrg 	  case '%':
   4010  1.1  mrg 	    putc ('%', file);
   4011  1.1  mrg 	    break;
   4012  1.1  mrg 
   4013  1.1  mrg 	  case 'd':  case 'i':  case 'u':
   4014  1.1  mrg 	  case 'x':  case 'X':  case 'o':
   4015  1.1  mrg 	  case 'c':
   4016  1.1  mrg 	    *q++ = c;
   4017  1.1  mrg 	    *q = 0;
   4018  1.1  mrg 	    fprintf (file, buf, va_arg (argptr, int));
   4019  1.1  mrg 	    break;
   4020  1.1  mrg 
   4021  1.1  mrg 	  case 'w':
   4022  1.1  mrg 	    /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and
   4023  1.1  mrg 	       'o' cases, but we do not check for those cases.  It
   4024  1.1  mrg 	       means that the value is a HOST_WIDE_INT, which may be
   4025  1.1  mrg 	       either `long' or `long long'.  */
   4026  1.1  mrg 	    memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT));
   4027  1.1  mrg 	    q += strlen (HOST_WIDE_INT_PRINT);
   4028  1.1  mrg 	    *q++ = *p++;
   4029  1.1  mrg 	    *q = 0;
   4030  1.1  mrg 	    fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
   4031  1.1  mrg 	    break;
   4032  1.1  mrg 
   4033  1.1  mrg 	  case 'l':
   4034  1.1  mrg 	    *q++ = c;
   4035  1.1  mrg #ifdef HAVE_LONG_LONG
   4036  1.1  mrg 	    if (*p == 'l')
   4037  1.1  mrg 	      {
   4038  1.1  mrg 		*q++ = *p++;
   4039  1.1  mrg 		*q++ = *p++;
   4040  1.1  mrg 		*q = 0;
   4041  1.1  mrg 		fprintf (file, buf, va_arg (argptr, long long));
   4042  1.1  mrg 	      }
   4043  1.1  mrg 	    else
   4044  1.1  mrg #endif
   4045  1.1  mrg 	      {
   4046  1.1  mrg 		*q++ = *p++;
   4047  1.1  mrg 		*q = 0;
   4048  1.1  mrg 		fprintf (file, buf, va_arg (argptr, long));
   4049  1.1  mrg 	      }
   4050  1.1  mrg 
   4051  1.1  mrg 	    break;
   4052  1.1  mrg 
   4053  1.1  mrg 	  case 's':
   4054  1.1  mrg 	    *q++ = c;
   4055  1.1  mrg 	    *q = 0;
   4056  1.1  mrg 	    fprintf (file, buf, va_arg (argptr, char *));
   4057  1.1  mrg 	    break;
   4058  1.1  mrg 
   4059  1.1  mrg 	  case 'O':
   4060  1.1  mrg #ifdef ASM_OUTPUT_OPCODE
   4061  1.1  mrg 	    ASM_OUTPUT_OPCODE (asm_out_file, p);
   4062  1.1  mrg #endif
   4063  1.1  mrg 	    break;
   4064  1.1  mrg 
   4065  1.1  mrg 	  case 'R':
   4066  1.1  mrg #ifdef REGISTER_PREFIX
   4067  1.1  mrg 	    fprintf (file, "%s", REGISTER_PREFIX);
   4068  1.1  mrg #endif
   4069  1.1  mrg 	    break;
   4070  1.1  mrg 
   4071  1.1  mrg 	  case 'I':
   4072  1.1  mrg #ifdef IMMEDIATE_PREFIX
   4073  1.1  mrg 	    fprintf (file, "%s", IMMEDIATE_PREFIX);
   4074  1.1  mrg #endif
   4075  1.1  mrg 	    break;
   4076  1.1  mrg 
   4077  1.1  mrg 	  case 'L':
   4078  1.1  mrg #ifdef LOCAL_LABEL_PREFIX
   4079  1.1  mrg 	    fprintf (file, "%s", LOCAL_LABEL_PREFIX);
   4080  1.1  mrg #endif
   4081  1.1  mrg 	    break;
   4082  1.1  mrg 
   4083  1.1  mrg 	  case 'U':
   4084  1.1  mrg 	    fputs (user_label_prefix, file);
   4085  1.1  mrg 	    break;
   4086  1.1  mrg 
   4087  1.1  mrg #ifdef ASM_FPRINTF_EXTENSIONS
   4088  1.1  mrg 	    /* Uppercase letters are reserved for general use by asm_fprintf
   4089  1.1  mrg 	       and so are not available to target specific code.  In order to
   4090  1.1  mrg 	       prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
   4091  1.1  mrg 	       they are defined here.  As they get turned into real extensions
   4092  1.1  mrg 	       to asm_fprintf they should be removed from this list.  */
   4093  1.1  mrg 	  case 'A': case 'B': case 'C': case 'D': case 'E':
   4094  1.1  mrg 	  case 'F': case 'G': case 'H': case 'J': case 'K':
   4095  1.1  mrg 	  case 'M': case 'N': case 'P': case 'Q': case 'S':
   4096  1.1  mrg 	  case 'T': case 'V': case 'W': case 'Y': case 'Z':
   4097  1.1  mrg 	    break;
   4098  1.1  mrg 
   4099  1.1  mrg 	  ASM_FPRINTF_EXTENSIONS (file, argptr, p)
   4100  1.1  mrg #endif
   4101  1.1  mrg 	  default:
   4102  1.1  mrg 	    gcc_unreachable ();
   4103  1.1  mrg 	  }
   4104  1.1  mrg 	break;
   4105  1.1  mrg 
   4106  1.1  mrg       default:
   4107  1.1  mrg 	putc (c, file);
   4108  1.1  mrg       }
   4109  1.1  mrg   va_end (argptr);
   4110  1.1  mrg }
   4111  1.1  mrg 
   4112  1.1  mrg /* Return nonzero if this function has no function calls.  */
   4114  1.1  mrg 
   4115  1.1  mrg int
   4116  1.1  mrg leaf_function_p (void)
   4117  1.1  mrg {
   4118  1.1  mrg   rtx_insn *insn;
   4119  1.1  mrg 
   4120  1.1  mrg   /* Ensure we walk the entire function body.  */
   4121  1.1  mrg   gcc_assert (!in_sequence_p ());
   4122  1.1  mrg 
   4123  1.1  mrg   /* Some back-ends (e.g. s390) want leaf functions to stay leaf
   4124  1.1  mrg      functions even if they call mcount.  */
   4125  1.1  mrg   if (crtl->profile && !targetm.keep_leaf_when_profiled ())
   4126  1.1  mrg     return 0;
   4127  1.1  mrg 
   4128  1.1  mrg   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4129  1.1  mrg     {
   4130  1.1  mrg       if (CALL_P (insn)
   4131  1.1  mrg 	  && ! SIBLING_CALL_P (insn)
   4132  1.1  mrg 	  && ! FAKE_CALL_P (insn))
   4133  1.1  mrg 	return 0;
   4134  1.1  mrg       if (NONJUMP_INSN_P (insn)
   4135  1.1  mrg 	  && GET_CODE (PATTERN (insn)) == SEQUENCE
   4136  1.1  mrg 	  && CALL_P (XVECEXP (PATTERN (insn), 0, 0))
   4137  1.1  mrg 	  && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
   4138  1.1  mrg 	return 0;
   4139  1.1  mrg     }
   4140  1.1  mrg 
   4141  1.1  mrg   return 1;
   4142  1.1  mrg }
   4143  1.1  mrg 
   4144  1.1  mrg /* Return 1 if branch is a forward branch.
   4145  1.1  mrg    Uses insn_shuid array, so it works only in the final pass.  May be used by
   4146  1.1  mrg    output templates to customary add branch prediction hints.
   4147  1.1  mrg  */
   4148  1.1  mrg int
   4149  1.1  mrg final_forward_branch_p (rtx_insn *insn)
   4150  1.1  mrg {
   4151  1.1  mrg   int insn_id, label_id;
   4152  1.1  mrg 
   4153  1.1  mrg   gcc_assert (uid_shuid);
   4154  1.1  mrg   insn_id = INSN_SHUID (insn);
   4155  1.1  mrg   label_id = INSN_SHUID (JUMP_LABEL (insn));
   4156  1.1  mrg   /* We've hit some insns that does not have id information available.  */
   4157  1.1  mrg   gcc_assert (insn_id && label_id);
   4158  1.1  mrg   return insn_id < label_id;
   4159  1.1  mrg }
   4160  1.1  mrg 
   4161  1.1  mrg /* On some machines, a function with no call insns
   4162  1.1  mrg    can run faster if it doesn't create its own register window.
   4163  1.1  mrg    When output, the leaf function should use only the "output"
   4164  1.1  mrg    registers.  Ordinarily, the function would be compiled to use
   4165  1.1  mrg    the "input" registers to find its arguments; it is a candidate
   4166  1.1  mrg    for leaf treatment if it uses only the "input" registers.
   4167  1.1  mrg    Leaf function treatment means renumbering so the function
   4168  1.1  mrg    uses the "output" registers instead.  */
   4169  1.1  mrg 
   4170  1.1  mrg #ifdef LEAF_REGISTERS
   4171  1.1  mrg 
   4172  1.1  mrg /* Return 1 if this function uses only the registers that can be
   4173  1.1  mrg    safely renumbered.  */
   4174  1.1  mrg 
   4175  1.1  mrg int
   4176  1.1  mrg only_leaf_regs_used (void)
   4177  1.1  mrg {
   4178  1.1  mrg   int i;
   4179  1.1  mrg   const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
   4180  1.1  mrg 
   4181  1.1  mrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   4182  1.1  mrg     if ((df_regs_ever_live_p (i) || global_regs[i])
   4183  1.1  mrg 	&& ! permitted_reg_in_leaf_functions[i])
   4184  1.1  mrg       return 0;
   4185  1.1  mrg 
   4186  1.1  mrg   if (crtl->uses_pic_offset_table
   4187  1.1  mrg       && pic_offset_table_rtx != 0
   4188  1.1  mrg       && REG_P (pic_offset_table_rtx)
   4189  1.1  mrg       && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
   4190  1.1  mrg     return 0;
   4191  1.1  mrg 
   4192  1.1  mrg   return 1;
   4193  1.1  mrg }
   4194  1.1  mrg 
   4195  1.1  mrg /* Scan all instructions and renumber all registers into those
   4196  1.1  mrg    available in leaf functions.  */
   4197  1.1  mrg 
   4198  1.1  mrg static void
   4199  1.1  mrg leaf_renumber_regs (rtx_insn *first)
   4200  1.1  mrg {
   4201  1.1  mrg   rtx_insn *insn;
   4202  1.1  mrg 
   4203  1.1  mrg   /* Renumber only the actual patterns.
   4204  1.1  mrg      The reg-notes can contain frame pointer refs,
   4205  1.1  mrg      and renumbering them could crash, and should not be needed.  */
   4206  1.1  mrg   for (insn = first; insn; insn = NEXT_INSN (insn))
   4207  1.1  mrg     if (INSN_P (insn))
   4208  1.1  mrg       leaf_renumber_regs_insn (PATTERN (insn));
   4209  1.1  mrg }
   4210  1.1  mrg 
   4211  1.1  mrg /* Scan IN_RTX and its subexpressions, and renumber all regs into those
   4212  1.1  mrg    available in leaf functions.  */
   4213  1.1  mrg 
   4214  1.1  mrg void
   4215  1.1  mrg leaf_renumber_regs_insn (rtx in_rtx)
   4216  1.1  mrg {
   4217  1.1  mrg   int i, j;
   4218  1.1  mrg   const char *format_ptr;
   4219  1.1  mrg 
   4220  1.1  mrg   if (in_rtx == 0)
   4221  1.1  mrg     return;
   4222  1.1  mrg 
   4223  1.1  mrg   /* Renumber all input-registers into output-registers.
   4224  1.1  mrg      renumbered_regs would be 1 for an output-register;
   4225  1.1  mrg      they  */
   4226  1.1  mrg 
   4227  1.1  mrg   if (REG_P (in_rtx))
   4228  1.1  mrg     {
   4229  1.1  mrg       int newreg;
   4230  1.1  mrg 
   4231  1.1  mrg       /* Don't renumber the same reg twice.  */
   4232  1.1  mrg       if (in_rtx->used)
   4233  1.1  mrg 	return;
   4234  1.1  mrg 
   4235  1.1  mrg       newreg = REGNO (in_rtx);
   4236  1.1  mrg       /* Don't try to renumber pseudo regs.  It is possible for a pseudo reg
   4237  1.1  mrg 	 to reach here as part of a REG_NOTE.  */
   4238  1.1  mrg       if (newreg >= FIRST_PSEUDO_REGISTER)
   4239  1.1  mrg 	{
   4240  1.1  mrg 	  in_rtx->used = 1;
   4241  1.1  mrg 	  return;
   4242  1.1  mrg 	}
   4243  1.1  mrg       newreg = LEAF_REG_REMAP (newreg);
   4244  1.1  mrg       gcc_assert (newreg >= 0);
   4245  1.1  mrg       df_set_regs_ever_live (REGNO (in_rtx), false);
   4246  1.1  mrg       df_set_regs_ever_live (newreg, true);
   4247  1.1  mrg       SET_REGNO (in_rtx, newreg);
   4248  1.1  mrg       in_rtx->used = 1;
   4249  1.1  mrg       return;
   4250  1.1  mrg     }
   4251  1.1  mrg 
   4252  1.1  mrg   if (INSN_P (in_rtx))
   4253  1.1  mrg     {
   4254  1.1  mrg       /* Inside a SEQUENCE, we find insns.
   4255  1.1  mrg 	 Renumber just the patterns of these insns,
   4256  1.1  mrg 	 just as we do for the top-level insns.  */
   4257  1.1  mrg       leaf_renumber_regs_insn (PATTERN (in_rtx));
   4258  1.1  mrg       return;
   4259  1.1  mrg     }
   4260  1.1  mrg 
   4261  1.1  mrg   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
   4262  1.1  mrg 
   4263  1.1  mrg   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
   4264  1.1  mrg     switch (*format_ptr++)
   4265  1.1  mrg       {
   4266  1.1  mrg       case 'e':
   4267  1.1  mrg 	leaf_renumber_regs_insn (XEXP (in_rtx, i));
   4268  1.1  mrg 	break;
   4269  1.1  mrg 
   4270  1.1  mrg       case 'E':
   4271  1.1  mrg 	if (XVEC (in_rtx, i) != NULL)
   4272  1.1  mrg 	  for (j = 0; j < XVECLEN (in_rtx, i); j++)
   4273  1.1  mrg 	    leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
   4274  1.1  mrg 	break;
   4275  1.1  mrg 
   4276  1.1  mrg       case 'S':
   4277  1.1  mrg       case 's':
   4278  1.1  mrg       case '0':
   4279  1.1  mrg       case 'i':
   4280  1.1  mrg       case 'w':
   4281  1.1  mrg       case 'p':
   4282  1.1  mrg       case 'n':
   4283  1.1  mrg       case 'u':
   4284  1.1  mrg 	break;
   4285  1.1  mrg 
   4286  1.1  mrg       default:
   4287  1.1  mrg 	gcc_unreachable ();
   4288  1.1  mrg       }
   4289  1.1  mrg }
   4290  1.1  mrg #endif
   4291  1.1  mrg 
   4292  1.1  mrg /* Turn the RTL into assembly.  */
   4294  1.1  mrg static unsigned int
   4295  1.1  mrg rest_of_handle_final (void)
   4296  1.1  mrg {
   4297  1.1  mrg   const char *fnname = get_fnname_from_decl (current_function_decl);
   4298  1.1  mrg 
   4299  1.1  mrg   /* Turn debug markers into notes if the var-tracking pass has not
   4300  1.1  mrg      been invoked.  */
   4301  1.1  mrg   if (!flag_var_tracking && MAY_HAVE_DEBUG_MARKER_INSNS)
   4302  1.1  mrg     delete_vta_debug_insns (false);
   4303  1.1  mrg 
   4304  1.1  mrg   assemble_start_function (current_function_decl, fnname);
   4305  1.1  mrg   rtx_insn *first = get_insns ();
   4306  1.1  mrg   int seen = 0;
   4307  1.1  mrg   final_start_function_1 (&first, asm_out_file, &seen, optimize);
   4308  1.1  mrg   final_1 (first, asm_out_file, seen, optimize);
   4309  1.1  mrg   if (flag_ipa_ra
   4310  1.1  mrg       && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
   4311  1.1  mrg       /* Functions with naked attributes are supported only with basic asm
   4312  1.1  mrg 	 statements in the body, thus for supported use cases the information
   4313  1.1  mrg 	 on clobbered registers is not available.  */
   4314  1.1  mrg       && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
   4315  1.1  mrg     collect_fn_hard_reg_usage ();
   4316  1.1  mrg   final_end_function ();
   4317  1.1  mrg 
   4318  1.1  mrg   /* The IA-64 ".handlerdata" directive must be issued before the ".endp"
   4319  1.1  mrg      directive that closes the procedure descriptor.  Similarly, for x64 SEH.
   4320  1.1  mrg      Otherwise it's not strictly necessary, but it doesn't hurt either.  */
   4321  1.1  mrg   output_function_exception_table (crtl->has_bb_partition ? 1 : 0);
   4322  1.1  mrg 
   4323  1.1  mrg   assemble_end_function (current_function_decl, fnname);
   4324  1.1  mrg 
   4325  1.1  mrg   /* Free up reg info memory.  */
   4326  1.1  mrg   free_reg_info ();
   4327  1.1  mrg 
   4328  1.1  mrg   if (! quiet_flag)
   4329  1.1  mrg     fflush (asm_out_file);
   4330  1.1  mrg 
   4331  1.1  mrg   /* Write DBX symbols if requested.  */
   4332  1.1  mrg 
   4333  1.1  mrg   /* Note that for those inline functions where we don't initially
   4334  1.1  mrg      know for certain that we will be generating an out-of-line copy,
   4335  1.1  mrg      the first invocation of this routine (rest_of_compilation) will
   4336  1.1  mrg      skip over this code by doing a `goto exit_rest_of_compilation;'.
   4337  1.1  mrg      Later on, wrapup_global_declarations will (indirectly) call
   4338  1.1  mrg      rest_of_compilation again for those inline functions that need
   4339  1.1  mrg      to have out-of-line copies generated.  During that call, we
   4340  1.1  mrg      *will* be routed past here.  */
   4341  1.1  mrg 
   4342  1.1  mrg   timevar_push (TV_SYMOUT);
   4343  1.1  mrg   if (!DECL_IGNORED_P (current_function_decl))
   4344  1.1  mrg     debug_hooks->function_decl (current_function_decl);
   4345  1.1  mrg   timevar_pop (TV_SYMOUT);
   4346  1.1  mrg 
   4347  1.1  mrg   /* Release the blocks that are linked to DECL_INITIAL() to free the memory.  */
   4348  1.1  mrg   DECL_INITIAL (current_function_decl) = error_mark_node;
   4349  1.1  mrg 
   4350  1.1  mrg   if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
   4351  1.1  mrg       && targetm.have_ctors_dtors)
   4352  1.1  mrg     targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0),
   4353  1.1  mrg 				 decl_init_priority_lookup
   4354  1.1  mrg 				   (current_function_decl));
   4355  1.1  mrg   if (DECL_STATIC_DESTRUCTOR (current_function_decl)
   4356  1.1  mrg       && targetm.have_ctors_dtors)
   4357  1.1  mrg     targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0),
   4358  1.1  mrg 				decl_fini_priority_lookup
   4359  1.1  mrg 				  (current_function_decl));
   4360  1.1  mrg   return 0;
   4361  1.1  mrg }
   4362  1.1  mrg 
   4363  1.1  mrg namespace {
   4364  1.1  mrg 
   4365  1.1  mrg const pass_data pass_data_final =
   4366  1.1  mrg {
   4367  1.1  mrg   RTL_PASS, /* type */
   4368  1.1  mrg   "final", /* name */
   4369  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
   4370  1.1  mrg   TV_FINAL, /* tv_id */
   4371  1.1  mrg   0, /* properties_required */
   4372  1.1  mrg   0, /* properties_provided */
   4373  1.1  mrg   0, /* properties_destroyed */
   4374  1.1  mrg   0, /* todo_flags_start */
   4375  1.1  mrg   0, /* todo_flags_finish */
   4376  1.1  mrg };
   4377  1.1  mrg 
   4378  1.1  mrg class pass_final : public rtl_opt_pass
   4379  1.1  mrg {
   4380  1.1  mrg public:
   4381  1.1  mrg   pass_final (gcc::context *ctxt)
   4382  1.1  mrg     : rtl_opt_pass (pass_data_final, ctxt)
   4383  1.1  mrg   {}
   4384  1.1  mrg 
   4385  1.1  mrg   /* opt_pass methods: */
   4386  1.1  mrg   virtual unsigned int execute (function *) { return rest_of_handle_final (); }
   4387  1.1  mrg 
   4388  1.1  mrg }; // class pass_final
   4389  1.1  mrg 
   4390  1.1  mrg } // anon namespace
   4391  1.1  mrg 
   4392  1.1  mrg rtl_opt_pass *
   4393  1.1  mrg make_pass_final (gcc::context *ctxt)
   4394  1.1  mrg {
   4395  1.1  mrg   return new pass_final (ctxt);
   4396  1.1  mrg }
   4397  1.1  mrg 
   4398  1.1  mrg 
   4399  1.1  mrg static unsigned int
   4400  1.1  mrg rest_of_handle_shorten_branches (void)
   4401  1.1  mrg {
   4402  1.1  mrg   /* Shorten branches.  */
   4403  1.1  mrg   shorten_branches (get_insns ());
   4404  1.1  mrg   return 0;
   4405  1.1  mrg }
   4406  1.1  mrg 
   4407  1.1  mrg namespace {
   4408  1.1  mrg 
   4409  1.1  mrg const pass_data pass_data_shorten_branches =
   4410  1.1  mrg {
   4411  1.1  mrg   RTL_PASS, /* type */
   4412  1.1  mrg   "shorten", /* name */
   4413  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
   4414  1.1  mrg   TV_SHORTEN_BRANCH, /* tv_id */
   4415  1.1  mrg   0, /* properties_required */
   4416  1.1  mrg   0, /* properties_provided */
   4417  1.1  mrg   0, /* properties_destroyed */
   4418  1.1  mrg   0, /* todo_flags_start */
   4419  1.1  mrg   0, /* todo_flags_finish */
   4420  1.1  mrg };
   4421  1.1  mrg 
   4422  1.1  mrg class pass_shorten_branches : public rtl_opt_pass
   4423  1.1  mrg {
   4424  1.1  mrg public:
   4425  1.1  mrg   pass_shorten_branches (gcc::context *ctxt)
   4426  1.1  mrg     : rtl_opt_pass (pass_data_shorten_branches, ctxt)
   4427  1.1  mrg   {}
   4428  1.1  mrg 
   4429  1.1  mrg   /* opt_pass methods: */
   4430  1.1  mrg   virtual unsigned int execute (function *)
   4431  1.1  mrg     {
   4432  1.1  mrg       return rest_of_handle_shorten_branches ();
   4433  1.1  mrg     }
   4434  1.1  mrg 
   4435  1.1  mrg }; // class pass_shorten_branches
   4436  1.1  mrg 
   4437  1.1  mrg } // anon namespace
   4438  1.1  mrg 
   4439  1.1  mrg rtl_opt_pass *
   4440  1.1  mrg make_pass_shorten_branches (gcc::context *ctxt)
   4441  1.1  mrg {
   4442  1.1  mrg   return new pass_shorten_branches (ctxt);
   4443  1.1  mrg }
   4444  1.1  mrg 
   4445  1.1  mrg 
   4446  1.1  mrg static unsigned int
   4447  1.1  mrg rest_of_clean_state (void)
   4448  1.1  mrg {
   4449  1.1  mrg   rtx_insn *insn, *next;
   4450  1.1  mrg   FILE *final_output = NULL;
   4451  1.1  mrg   int save_unnumbered = flag_dump_unnumbered;
   4452  1.1  mrg   int save_noaddr = flag_dump_noaddr;
   4453  1.1  mrg 
   4454  1.1  mrg   if (flag_dump_final_insns)
   4455  1.1  mrg     {
   4456  1.1  mrg       final_output = fopen (flag_dump_final_insns, "a");
   4457  1.1  mrg       if (!final_output)
   4458  1.1  mrg 	{
   4459  1.1  mrg 	  error ("could not open final insn dump file %qs: %m",
   4460  1.1  mrg 		 flag_dump_final_insns);
   4461  1.1  mrg 	  flag_dump_final_insns = NULL;
   4462  1.1  mrg 	}
   4463  1.1  mrg       else
   4464  1.1  mrg 	{
   4465  1.1  mrg 	  flag_dump_noaddr = flag_dump_unnumbered = 1;
   4466  1.1  mrg 	  if (flag_compare_debug_opt || flag_compare_debug)
   4467  1.1  mrg 	    dump_flags |= TDF_NOUID | TDF_COMPARE_DEBUG;
   4468  1.1  mrg 	  dump_function_header (final_output, current_function_decl,
   4469  1.1  mrg 				dump_flags);
   4470  1.1  mrg 	  final_insns_dump_p = true;
   4471  1.1  mrg 
   4472  1.1  mrg 	  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   4473  1.1  mrg 	    if (LABEL_P (insn))
   4474  1.1  mrg 	      INSN_UID (insn) = CODE_LABEL_NUMBER (insn);
   4475  1.1  mrg 	    else
   4476  1.1  mrg 	      {
   4477  1.1  mrg 		if (NOTE_P (insn))
   4478  1.1  mrg 		  set_block_for_insn (insn, NULL);
   4479  1.1  mrg 		INSN_UID (insn) = 0;
   4480  1.1  mrg 	      }
   4481  1.1  mrg 	}
   4482  1.1  mrg     }
   4483  1.1  mrg 
   4484  1.1  mrg   /* It is very important to decompose the RTL instruction chain here:
   4485  1.1  mrg      debug information keeps pointing into CODE_LABEL insns inside the function
   4486  1.1  mrg      body.  If these remain pointing to the other insns, we end up preserving
   4487  1.1  mrg      whole RTL chain and attached detailed debug info in memory.  */
   4488  1.1  mrg   for (insn = get_insns (); insn; insn = next)
   4489  1.1  mrg     {
   4490  1.1  mrg       next = NEXT_INSN (insn);
   4491  1.1  mrg       SET_NEXT_INSN (insn) = NULL;
   4492  1.1  mrg       SET_PREV_INSN (insn) = NULL;
   4493  1.1  mrg 
   4494  1.1  mrg       rtx_insn *call_insn = insn;
   4495  1.1  mrg       if (NONJUMP_INSN_P (call_insn)
   4496  1.1  mrg 	  && GET_CODE (PATTERN (call_insn)) == SEQUENCE)
   4497  1.1  mrg 	{
   4498  1.1  mrg 	  rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (call_insn));
   4499  1.1  mrg 	  call_insn = seq->insn (0);
   4500  1.1  mrg 	}
   4501  1.1  mrg       if (CALL_P (call_insn))
   4502  1.1  mrg 	{
   4503  1.1  mrg 	  rtx note
   4504  1.1  mrg 	    = find_reg_note (call_insn, REG_CALL_ARG_LOCATION, NULL_RTX);
   4505  1.1  mrg 	  if (note)
   4506  1.1  mrg 	    remove_note (call_insn, note);
   4507  1.1  mrg 	}
   4508  1.1  mrg 
   4509  1.1  mrg       if (final_output
   4510  1.1  mrg 	  && (!NOTE_P (insn)
   4511  1.1  mrg 	      || (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
   4512  1.1  mrg 		  && NOTE_KIND (insn) != NOTE_INSN_BEGIN_STMT
   4513  1.1  mrg 		  && NOTE_KIND (insn) != NOTE_INSN_INLINE_ENTRY
   4514  1.1  mrg 		  && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
   4515  1.1  mrg 		  && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
   4516  1.1  mrg 		  && NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL)))
   4517  1.1  mrg 	print_rtl_single (final_output, insn);
   4518  1.1  mrg     }
   4519  1.1  mrg 
   4520  1.1  mrg   if (final_output)
   4521  1.1  mrg     {
   4522  1.1  mrg       flag_dump_noaddr = save_noaddr;
   4523  1.1  mrg       flag_dump_unnumbered = save_unnumbered;
   4524  1.1  mrg       final_insns_dump_p = false;
   4525  1.1  mrg 
   4526  1.1  mrg       if (fclose (final_output))
   4527  1.1  mrg 	{
   4528  1.1  mrg 	  error ("could not close final insn dump file %qs: %m",
   4529  1.1  mrg 		 flag_dump_final_insns);
   4530  1.1  mrg 	  flag_dump_final_insns = NULL;
   4531  1.1  mrg 	}
   4532  1.1  mrg     }
   4533  1.1  mrg 
   4534  1.1  mrg   flag_rerun_cse_after_global_opts = 0;
   4535  1.1  mrg   reload_completed = 0;
   4536  1.1  mrg   epilogue_completed = 0;
   4537  1.1  mrg #ifdef STACK_REGS
   4538  1.1  mrg   regstack_completed = 0;
   4539  1.1  mrg #endif
   4540  1.1  mrg 
   4541  1.1  mrg   /* Clear out the insn_length contents now that they are no
   4542  1.1  mrg      longer valid.  */
   4543  1.1  mrg   init_insn_lengths ();
   4544  1.1  mrg 
   4545  1.1  mrg   /* Show no temporary slots allocated.  */
   4546  1.1  mrg   init_temp_slots ();
   4547  1.1  mrg 
   4548  1.1  mrg   free_bb_for_insn ();
   4549  1.1  mrg 
   4550  1.1  mrg   if (cfun->gimple_df)
   4551  1.1  mrg     delete_tree_ssa (cfun);
   4552  1.1  mrg 
   4553  1.1  mrg   /* We can reduce stack alignment on call site only when we are sure that
   4554  1.1  mrg      the function body just produced will be actually used in the final
   4555  1.1  mrg      executable.  */
   4556  1.1  mrg   if (flag_ipa_stack_alignment
   4557  1.1  mrg       && decl_binds_to_current_def_p (current_function_decl))
   4558  1.1  mrg     {
   4559  1.1  mrg       unsigned int pref = crtl->preferred_stack_boundary;
   4560  1.1  mrg       if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
   4561  1.1  mrg         pref = crtl->stack_alignment_needed;
   4562  1.1  mrg       cgraph_node::rtl_info (current_function_decl)
   4563  1.1  mrg 	->preferred_incoming_stack_boundary = pref;
   4564  1.1  mrg     }
   4565  1.1  mrg 
   4566  1.1  mrg   /* Make sure volatile mem refs aren't considered valid operands for
   4567  1.1  mrg      arithmetic insns.  We must call this here if this is a nested inline
   4568  1.1  mrg      function, since the above code leaves us in the init_recog state,
   4569  1.1  mrg      and the function context push/pop code does not save/restore volatile_ok.
   4570  1.1  mrg 
   4571  1.1  mrg      ??? Maybe it isn't necessary for expand_start_function to call this
   4572  1.1  mrg      anymore if we do it here?  */
   4573  1.1  mrg 
   4574  1.1  mrg   init_recog_no_volatile ();
   4575  1.1  mrg 
   4576  1.1  mrg   /* We're done with this function.  Free up memory if we can.  */
   4577  1.1  mrg   free_after_parsing (cfun);
   4578  1.1  mrg   free_after_compilation (cfun);
   4579  1.1  mrg   return 0;
   4580  1.1  mrg }
   4581  1.1  mrg 
   4582  1.1  mrg namespace {
   4583  1.1  mrg 
   4584  1.1  mrg const pass_data pass_data_clean_state =
   4585  1.1  mrg {
   4586  1.1  mrg   RTL_PASS, /* type */
   4587  1.1  mrg   "*clean_state", /* name */
   4588  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
   4589  1.1  mrg   TV_FINAL, /* tv_id */
   4590  1.1  mrg   0, /* properties_required */
   4591  1.1  mrg   0, /* properties_provided */
   4592  1.1  mrg   PROP_rtl, /* properties_destroyed */
   4593  1.1  mrg   0, /* todo_flags_start */
   4594  1.1  mrg   0, /* todo_flags_finish */
   4595  1.1  mrg };
   4596  1.1  mrg 
   4597  1.1  mrg class pass_clean_state : public rtl_opt_pass
   4598  1.1  mrg {
   4599  1.1  mrg public:
   4600  1.1  mrg   pass_clean_state (gcc::context *ctxt)
   4601  1.1  mrg     : rtl_opt_pass (pass_data_clean_state, ctxt)
   4602  1.1  mrg   {}
   4603  1.1  mrg 
   4604  1.1  mrg   /* opt_pass methods: */
   4605  1.1  mrg   virtual unsigned int execute (function *)
   4606  1.1  mrg     {
   4607  1.1  mrg       return rest_of_clean_state ();
   4608  1.1  mrg     }
   4609  1.1  mrg 
   4610  1.1  mrg }; // class pass_clean_state
   4611  1.1  mrg 
   4612  1.1  mrg } // anon namespace
   4613  1.1  mrg 
   4614  1.1  mrg rtl_opt_pass *
   4615  1.1  mrg make_pass_clean_state (gcc::context *ctxt)
   4616  1.1  mrg {
   4617  1.1  mrg   return new pass_clean_state (ctxt);
   4618  1.1  mrg }
   4619  1.1  mrg 
   4620  1.1  mrg /* Return true if INSN is a call to the current function.  */
   4621  1.1  mrg 
   4622  1.1  mrg static bool
   4623  1.1  mrg self_recursive_call_p (rtx_insn *insn)
   4624  1.1  mrg {
   4625  1.1  mrg   tree fndecl = get_call_fndecl (insn);
   4626  1.1  mrg   return (fndecl == current_function_decl
   4627  1.1  mrg 	  && decl_binds_to_current_def_p (fndecl));
   4628  1.1  mrg }
   4629  1.1  mrg 
   4630  1.1  mrg /* Collect hard register usage for the current function.  */
   4631  1.1  mrg 
   4632  1.1  mrg static void
   4633  1.1  mrg collect_fn_hard_reg_usage (void)
   4634  1.1  mrg {
   4635  1.1  mrg   rtx_insn *insn;
   4636  1.1  mrg #ifdef STACK_REGS
   4637  1.1  mrg   int i;
   4638  1.1  mrg #endif
   4639  1.1  mrg   struct cgraph_rtl_info *node;
   4640  1.1  mrg   HARD_REG_SET function_used_regs;
   4641  1.1  mrg 
   4642  1.1  mrg   /* ??? To be removed when all the ports have been fixed.  */
   4643  1.1  mrg   if (!targetm.call_fusage_contains_non_callee_clobbers)
   4644  1.1  mrg     return;
   4645  1.1  mrg 
   4646  1.1  mrg   /* Be conservative - mark fixed and global registers as used.  */
   4647  1.1  mrg   function_used_regs = fixed_reg_set;
   4648  1.1  mrg 
   4649  1.1  mrg #ifdef STACK_REGS
   4650  1.1  mrg   /* Handle STACK_REGS conservatively, since the df-framework does not
   4651  1.1  mrg      provide accurate information for them.  */
   4652  1.1  mrg 
   4653  1.1  mrg   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   4654  1.1  mrg     SET_HARD_REG_BIT (function_used_regs, i);
   4655  1.1  mrg #endif
   4656  1.1  mrg 
   4657  1.1  mrg   for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
   4658  1.1  mrg     {
   4659  1.1  mrg       HARD_REG_SET insn_used_regs;
   4660  1.1  mrg 
   4661  1.1  mrg       if (!NONDEBUG_INSN_P (insn))
   4662  1.1  mrg 	continue;
   4663  1.1  mrg 
   4664  1.1  mrg       if (CALL_P (insn)
   4665  1.1  mrg 	  && !self_recursive_call_p (insn))
   4666  1.1  mrg 	function_used_regs
   4667           	  |= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
   4668           
   4669                 find_all_hard_reg_sets (insn, &insn_used_regs, false);
   4670                 function_used_regs |= insn_used_regs;
   4671           
   4672                 if (hard_reg_set_subset_p (crtl->abi->full_and_partial_reg_clobbers (),
   4673           				 function_used_regs))
   4674           	return;
   4675               }
   4676           
   4677             /* Mask out fully-saved registers, so that they don't affect equality
   4678                comparisons between function_abis.  */
   4679             function_used_regs &= crtl->abi->full_and_partial_reg_clobbers ();
   4680           
   4681             node = cgraph_node::rtl_info (current_function_decl);
   4682             gcc_assert (node != NULL);
   4683           
   4684             node->function_used_regs = function_used_regs;
   4685           }
   4686