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