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