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