OSDN Git Service

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