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