OSDN Git Service

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