OSDN Git Service

61a90a95eff5fea75fc15aae406bdb553ea2d388
[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, 93, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 /* This is the final pass of the compiler.
22    It looks at the rtl code for a function and outputs assembler code.
23
24    Call `final_start_function' to output the assembler code for function entry,
25    `final' to output assembler code for some RTL code,
26    `final_end_function' to output assembler code for function exit.
27    If a function is compiled in several pieces, each piece is
28    output separately with `final'.
29
30    Some optimizations are also done at this level.
31    Move instructions that were made unnecessary by good register allocation
32    are detected and omitted from the output.  (Though most of these
33    are removed by the last jump pass.)
34
35    Instructions to set the condition codes are omitted when it can be
36    seen that the condition codes already had the desired values.
37
38    In some cases it is sufficient if the inherited condition codes
39    have related values, but this may require the following insn
40    (the one that tests the condition codes) to be modified.
41
42    The code for the function prologue and epilogue are generated
43    directly as assembler code by the macros FUNCTION_PROLOGUE and
44    FUNCTION_EPILOGUE.  Those instructions never exist as rtl.  */
45
46 #include "config.h"
47 #ifdef __STDC__
48 #include <stdarg.h>
49 #else
50 #include <varargs.h>
51 #endif
52 #include <stdio.h>
53 #include <ctype.h>
54
55 #include "tree.h"
56 #include "rtl.h"
57 #include "regs.h"
58 #include "insn-config.h"
59 #include "insn-flags.h"
60 #include "insn-attr.h"
61 #include "insn-codes.h"
62 #include "recog.h"
63 #include "conditions.h"
64 #include "flags.h"
65 #include "real.h"
66 #include "hard-reg-set.h"
67 #include "defaults.h"
68 #include "output.h"
69
70 /* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist.  */
71 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
72 #if defined (USG) || defined (NO_STAB_H)
73 #include "gstab.h"  /* If doing DBX on sysV, use our own stab.h.  */
74 #else
75 #include <stab.h>  /* On BSD, use the system's stab.h.  */
76 #endif /* not USG */
77 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
78
79 #ifdef XCOFF_DEBUGGING_INFO
80 #include "xcoffout.h"
81 #endif
82
83 /* .stabd code for line number.  */
84 #ifndef N_SLINE
85 #define N_SLINE 0x44
86 #endif
87
88 /* .stabs code for included file name.  */
89 #ifndef N_SOL
90 #define N_SOL 0x84
91 #endif
92
93 #ifndef INT_TYPE_SIZE
94 #define INT_TYPE_SIZE BITS_PER_WORD
95 #endif
96
97 /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist.  So define a
98    null default for it to save conditionalization later.  */
99 #ifndef CC_STATUS_INIT
100 #define CC_STATUS_INIT
101 #endif
102
103 /* How to start an assembler comment.  */
104 #ifndef ASM_COMMENT_START
105 #define ASM_COMMENT_START ";#"
106 #endif
107
108 /* Is the given character a logical line separator for the assembler?  */
109 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
110 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
111 #endif
112
113 /* Nonzero means this function is a leaf function, with no function calls. 
114    This variable exists to be examined in FUNCTION_PROLOGUE
115    and FUNCTION_EPILOGUE.  Always zero, unless set by some action.  */
116 int leaf_function;
117
118 /* Last insn processed by final_scan_insn.  */
119 static rtx debug_insn = 0;
120
121 /* Line number of last NOTE.  */
122 static int last_linenum;
123
124 /* Filename of last NOTE.  */
125 static char *last_filename;
126
127 /* Number of basic blocks seen so far;
128    used if profile_block_flag is set.  */
129 static int count_basic_blocks;
130
131 /* Nonzero while outputting an `asm' with operands.
132    This means that inconsistencies are the user's fault, so don't abort.
133    The precise value is the insn being output, to pass to error_for_asm.  */
134 static rtx this_is_asm_operands;
135
136 /* Number of operands of this insn, for an `asm' with operands.  */
137 static int insn_noperands;
138
139 /* Compare optimization flag.  */
140
141 static rtx last_ignored_compare = 0;
142
143 /* Flag indicating this insn is the start of a new basic block.  */
144
145 static int new_block = 1;
146
147 /* All the symbol-blocks (levels of scoping) in the compilation
148    are assigned sequence numbers in order of appearance of the
149    beginnings of the symbol-blocks.  Both final and dbxout do this,
150    and assume that they will both give the same number to each block.
151    Final uses these sequence numbers to generate assembler label names
152    LBBnnn and LBEnnn for the beginning and end of the symbol-block.
153    Dbxout uses the sequence numbers to generate references to the same labels
154    from the dbx debugging information.
155
156    Sdb records this level at the beginning of each function,
157    in order to find the current level when recursing down declarations.
158    It outputs the block beginning and endings
159    at the point in the asm file where the blocks would begin and end.  */
160
161 int next_block_index;
162
163 /* Assign a unique number to each insn that is output.
164    This can be used to generate unique local labels.  */
165
166 static int insn_counter = 0;
167
168 #ifdef HAVE_cc0
169 /* This variable contains machine-dependent flags (defined in tm.h)
170    set and examined by output routines
171    that describe how to interpret the condition codes properly.  */
172
173 CC_STATUS cc_status;
174
175 /* During output of an insn, this contains a copy of cc_status
176    from before the insn.  */
177
178 CC_STATUS cc_prev_status;
179 #endif
180
181 /* Indexed by hardware reg number, is 1 if that register is ever
182    used in the current function.
183
184    In life_analysis, or in stupid_life_analysis, this is set
185    up to record the hard regs used explicitly.  Reload adds
186    in the hard regs used for holding pseudo regs.  Final uses
187    it to generate the code in the function prologue and epilogue
188    to save and restore registers as needed.  */
189
190 char regs_ever_live[FIRST_PSEUDO_REGISTER];
191
192 /* Nonzero means current function must be given a frame pointer.
193    Set in stmt.c if anything is allocated on the stack there.
194    Set in reload1.c if anything is allocated on the stack there.  */
195
196 int frame_pointer_needed;
197
198 /* Assign unique numbers to labels generated for profiling.  */
199
200 int profile_label_no;
201
202 /* Length so far allocated in PENDING_BLOCKS.  */
203
204 static int max_block_depth;
205
206 /* Stack of sequence numbers of symbol-blocks of which we have seen the
207    beginning but not yet the end.  Sequence numbers are assigned at
208    the beginning; this stack allows us to find the sequence number
209    of a block that is ending.  */
210
211 static int *pending_blocks;
212
213 /* Number of elements currently in use in PENDING_BLOCKS.  */
214
215 static int block_depth;
216
217 /* Nonzero if have enabled APP processing of our assembler output.  */
218
219 static int app_on;
220
221 /* If we are outputting an insn sequence, this contains the sequence rtx.
222    Zero otherwise.  */
223
224 rtx final_sequence;
225
226 #ifdef ASSEMBLER_DIALECT
227
228 /* Number of the assembler dialect to use, starting at 0.  */
229 static int dialect_number;
230 #endif
231
232 /* Indexed by line number, nonzero if there is a note for that line.  */
233
234 static char *line_note_exists;
235
236 /* Linked list to hold line numbers for each basic block.  */
237
238 struct bb_list {
239   struct bb_list *next;         /* pointer to next basic block */
240   int line_num;                 /* line number */
241   int file_label_num;           /* LPBC<n> label # for stored filename */
242   int func_label_num;           /* LPBC<n> label # for stored function name */
243 };
244
245 static struct bb_list *bb_head  = 0;            /* Head of basic block list */
246 static struct bb_list **bb_tail = &bb_head;     /* Ptr to store next bb ptr */
247 static int bb_file_label_num    = -1;           /* Current label # for file */
248 static int bb_func_label_num    = -1;           /* Current label # for func */
249
250 /* Linked list to hold the strings for each file and function name output.  */
251
252 struct bb_str {
253   struct bb_str *next;          /* pointer to next string */
254   char *string;                 /* string */
255   int label_num;                /* label number */
256   int length;                   /* string length */
257 };
258
259 extern rtx peephole             PROTO((rtx));
260
261 static struct bb_str *sbb_head  = 0;            /* Head of string list.  */
262 static struct bb_str **sbb_tail = &sbb_head;    /* Ptr to store next bb str */
263 static int sbb_label_num        = 0;            /* Last label used */
264
265 static int asm_insn_count       PROTO((rtx));
266 static void profile_function    PROTO((FILE *));
267 static void profile_after_prologue PROTO((FILE *));
268 static void add_bb              PROTO((FILE *));
269 static int add_bb_string        PROTO((char *, int));
270 static void output_source_line  PROTO((FILE *, rtx));
271 static rtx walk_alter_subreg    PROTO((rtx));
272 static int alter_cond           PROTO((rtx));
273 static void output_operand      PROTO((rtx, int));
274 static void leaf_renumber_regs  PROTO((rtx));
275
276 extern char *getpwd ();
277 \f
278 /* Initialize data in final at the beginning of a compilation.  */
279
280 void
281 init_final (filename)
282      char *filename;
283 {
284   next_block_index = 2;
285   app_on = 0;
286   max_block_depth = 20;
287   pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks);
288   final_sequence = 0;
289
290 #ifdef ASSEMBLER_DIALECT
291   dialect_number = ASSEMBLER_DIALECT;
292 #endif
293 }
294
295 /* Called at end of source file,
296    to output the block-profiling table for this entire compilation.  */
297
298 void
299 end_final (filename)
300      char *filename;
301 {
302   int i;
303
304   if (profile_block_flag)
305     {
306       char name[20];
307       int align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
308       int size = (POINTER_SIZE / BITS_PER_UNIT) * count_basic_blocks;
309       int rounded = size;
310       struct bb_list *ptr;
311       struct bb_str *sptr;
312
313       rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
314       rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
315                  * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
316
317       data_section ();
318
319       /* Output the main header, of 10 words:
320          0:  1 if this file's initialized, else 0.
321          1:  address of file name (LPBX1).
322          2:  address of table of counts (LPBX2).
323          3:  number of counts in the table.
324          4:  always 0, for compatibility with Sun.
325
326          The following are GNU extensions:
327
328          5:  address of table of start addrs of basic blocks (LPBX3).
329          6:  Number of bytes in this header.
330          7:  address of table of function names (LPBX4).
331          8:  address of table of line numbers (LPBX5) or 0.
332          9:  address of table of file names (LPBX6) or 0.  */
333
334       ASM_OUTPUT_ALIGN (asm_out_file, align);
335
336       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 0);
337       /* zero word */
338       assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
339
340       /* address of filename */
341       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 1);
342       assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
343
344       /* address of count table */
345       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
346       assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
347
348       /* count of the # of basic blocks */
349       assemble_integer (GEN_INT (count_basic_blocks), UNITS_PER_WORD, 1);
350
351       /* zero word (link field) */
352       assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
353
354       /* address of basic block start address table */
355       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3);
356       assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
357
358       /* byte count for extended structure.  */
359       assemble_integer (GEN_INT (10 * UNITS_PER_WORD), UNITS_PER_WORD, 1);
360
361       /* address of function name table */
362       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 4);
363       assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
364
365       /* address of line number and filename tables if debugging.  */
366       if (write_symbols != NO_DEBUG)
367         {
368           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 5);
369           assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
370           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 6);
371           assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
372         }
373       else
374         {
375           assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
376           assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
377         }
378
379       /* Output the file name changing the suffix to .d for Sun tcov
380          compatibility.  */
381       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 1);
382       {
383         char *cwd = getpwd ();
384         int len = strlen (filename) + strlen (cwd) + 1;
385         char *data_file = (char *) alloca (len + 4);
386
387         strcpy (data_file, cwd);
388         strcat (data_file, "/");
389         strcat (data_file, filename);
390         strip_off_ending (data_file, len);
391         strcat (data_file, ".d");
392         assemble_string (data_file, strlen (data_file) + 1);
393       }
394
395       /* Make space for the table of counts.  */
396       if (flag_no_common || size == 0)
397         {
398           /* Realign data section.  */
399           ASM_OUTPUT_ALIGN (asm_out_file, align);
400           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 2);
401           if (size != 0)
402             assemble_zeros (size);
403         }
404       else
405         {
406           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
407 #ifdef ASM_OUTPUT_SHARED_LOCAL
408           if (flag_shared_data)
409             ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
410           else
411 #endif
412 #ifdef ASM_OUTPUT_ALIGNED_LOCAL
413             ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
414                                       BIGGEST_ALIGNMENT);
415 #else
416             ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
417 #endif
418         }
419
420       /* Output any basic block strings */
421       readonly_data_section ();
422       if (sbb_head)
423         {
424           ASM_OUTPUT_ALIGN (asm_out_file, align);
425           for (sptr = sbb_head; sptr != 0; sptr = sptr->next)
426             {
427               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBC", sptr->label_num);
428               assemble_string (sptr->string, sptr->length);
429             }
430         }
431
432       /* Output the table of addresses.  */
433       /* Realign in new section */
434       ASM_OUTPUT_ALIGN (asm_out_file, align);
435       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 3);
436       for (i = 0; i < count_basic_blocks; i++)
437         {
438           ASM_GENERATE_INTERNAL_LABEL (name, "LPB", i);
439           assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name),
440                             UNITS_PER_WORD, 1);
441         }
442
443       /* Output the table of function names.  */
444       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 4);
445       for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
446         {
447           if (ptr->func_label_num >= 0)
448             {
449               ASM_GENERATE_INTERNAL_LABEL (name, "LPBC", ptr->func_label_num);
450               assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name),
451                                 UNITS_PER_WORD, 1);
452             }
453           else
454             assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
455         }
456
457       for ( ; i < count_basic_blocks; i++)
458         assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
459
460       if (write_symbols != NO_DEBUG)
461         {
462           /* Output the table of line numbers.  */
463           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 5);
464           for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
465             assemble_integer (GEN_INT (ptr->line_num), UNITS_PER_WORD, 1);
466
467           for ( ; i < count_basic_blocks; i++)
468             assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
469
470           /* Output the table of file names.  */
471           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 6);
472           for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
473             {
474               if (ptr->file_label_num >= 0)
475                 {
476                   ASM_GENERATE_INTERNAL_LABEL (name, "LPBC", ptr->file_label_num);
477                   assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name),
478                                     UNITS_PER_WORD, 1);
479                 }
480               else
481                 assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
482             }
483
484           for ( ; i < count_basic_blocks; i++)
485             assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
486         }
487
488       /* End with the address of the table of addresses,
489          so we can find it easily, as the last word in the file's text.  */
490       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3);
491       assemble_integer (gen_rtx (SYMBOL_REF, Pmode, name), UNITS_PER_WORD, 1);
492     }
493 }
494
495 /* Enable APP processing of subsequent output.
496    Used before the output from an `asm' statement.  */
497
498 void
499 app_enable ()
500 {
501   if (! app_on)
502     {
503       fprintf (asm_out_file, ASM_APP_ON);
504       app_on = 1;
505     }
506 }
507
508 /* Disable APP processing of subsequent output.
509    Called from varasm.c before most kinds of output.  */
510
511 void
512 app_disable ()
513 {
514   if (app_on)
515     {
516       fprintf (asm_out_file, ASM_APP_OFF);
517       app_on = 0;
518     }
519 }
520 \f
521 /* Return the number of slots filled in the current 
522    delayed branch sequence (we don't count the insn needing the
523    delay slot).   Zero if not in a delayed branch sequence.  */
524
525 #ifdef DELAY_SLOTS
526 int
527 dbr_sequence_length ()
528 {
529   if (final_sequence != 0)
530     return XVECLEN (final_sequence, 0) - 1;
531   else
532     return 0;
533 }
534 #endif
535 \f
536 /* The next two pages contain routines used to compute the length of an insn
537    and to shorten branches.  */
538
539 /* Arrays for insn lengths, and addresses.  The latter is referenced by
540    `insn_current_length'.  */
541
542 static short *insn_lengths;
543 int *insn_addresses;
544
545 /* Address of insn being processed.  Used by `insn_current_length'.  */
546 int insn_current_address;
547
548 /* Indicate that branch shortening hasn't yet been done.  */
549
550 void
551 init_insn_lengths ()
552 {
553   insn_lengths = 0;
554 }
555
556 /* Obtain the current length of an insn.  If branch shortening has been done,
557    get its actual length.  Otherwise, get its maximum length.  */
558
559 int
560 get_attr_length (insn)
561      rtx insn;
562 {
563 #ifdef HAVE_ATTR_length
564   rtx body;
565   int i;
566   int length = 0;
567
568   if (insn_lengths)
569     return insn_lengths[INSN_UID (insn)];
570   else
571     switch (GET_CODE (insn))
572       {
573       case NOTE:
574       case BARRIER:
575       case CODE_LABEL:
576         return 0;
577
578       case CALL_INSN:
579         length = insn_default_length (insn);
580         break;
581
582       case JUMP_INSN:
583         body = PATTERN (insn);
584         if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
585           {
586             /* This only takes room if jump tables go into the text section.  */
587 #if !defined(READONLY_DATA_SECTION) || defined(JUMP_TABLES_IN_TEXT_SECTION)
588             length = (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
589                       * GET_MODE_SIZE (GET_MODE (body)));
590
591             /* Be pessimistic and assume worst-case alignment.  */
592             length += (GET_MODE_SIZE (GET_MODE (body)) - 1);
593 #else
594             return 0;
595 #endif
596           }
597         else
598           length = insn_default_length (insn);
599         break;
600
601       case INSN:
602         body = PATTERN (insn);
603         if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
604           return 0;
605
606         else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
607           length = asm_insn_count (body) * insn_default_length (insn);
608         else if (GET_CODE (body) == SEQUENCE)
609           for (i = 0; i < XVECLEN (body, 0); i++)
610             length += get_attr_length (XVECEXP (body, 0, i));
611         else
612           length = insn_default_length (insn);
613       }
614
615 #ifdef ADJUST_INSN_LENGTH
616   ADJUST_INSN_LENGTH (insn, length);
617 #endif
618   return length;
619 #else /* not HAVE_ATTR_length */
620   return 0;
621 #endif /* not HAVE_ATTR_length */
622 }
623 \f
624 /* Make a pass over all insns and compute their actual lengths by shortening
625    any branches of variable length if possible.  */
626
627 /* Give a default value for the lowest address in a function.  */
628
629 #ifndef FIRST_INSN_ADDRESS
630 #define FIRST_INSN_ADDRESS 0
631 #endif
632
633 void
634 shorten_branches (first)
635      rtx first;
636 {
637 #ifdef HAVE_ATTR_length
638   rtx insn;
639   int something_changed = 1;
640   int max_uid = 0;
641   char *varying_length;
642   rtx body;
643   int uid;
644
645   /* Compute maximum UID and allocate arrays.  */
646   for (insn = first; insn; insn = NEXT_INSN (insn))
647     if (INSN_UID (insn) > max_uid)
648       max_uid = INSN_UID (insn);
649
650   max_uid++;
651   insn_lengths = (short *) oballoc (max_uid * sizeof (short));
652   insn_addresses = (int *) oballoc (max_uid * sizeof (int));
653   varying_length = (char *) oballoc (max_uid * sizeof (char));
654
655   /* Compute initial lengths, addresses, and varying flags for each insn.  */
656   for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
657        insn != 0;
658        insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
659     {
660       uid = INSN_UID (insn);
661       insn_addresses[uid] = insn_current_address;
662       insn_lengths[uid] = 0;
663       varying_length[uid] = 0;
664       
665       if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER
666           || GET_CODE (insn) == CODE_LABEL)
667         continue;
668
669       body = PATTERN (insn);
670       if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
671         {
672           /* This only takes room if read-only data goes into the text
673              section.  */
674 #if !defined(READONLY_DATA_SECTION) || defined(JUMP_TABLES_IN_TEXT_SECTION)
675           int unitsize = GET_MODE_SIZE (GET_MODE (body));
676
677           insn_lengths[uid] = (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
678                                * GET_MODE_SIZE (GET_MODE (body)));
679
680           /* Account for possible alignment.  */
681           insn_lengths[uid]
682             += unitsize - (insn_current_address & (unitsize - 1));
683 #else
684           ;
685 #endif
686         }
687       else if (asm_noperands (body) >= 0)
688         insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn);
689       else if (GET_CODE (body) == SEQUENCE)
690         {
691           int i;
692           int const_delay_slots;
693 #ifdef DELAY_SLOTS
694           const_delay_slots = const_num_delay_slots (XVECEXP (body, 0, 0));
695 #else
696           const_delay_slots = 0;
697 #endif
698           /* Inside a delay slot sequence, we do not do any branch shortening
699              if the shortening could change the number of delay slots
700              of the branch. */
701           for (i = 0; i < XVECLEN (body, 0); i++)
702             {
703               rtx inner_insn = XVECEXP (body, 0, i);
704               int inner_uid = INSN_UID (inner_insn);
705               int inner_length;
706
707               if (asm_noperands (PATTERN (XVECEXP (body, 0, i))) >= 0)
708                 inner_length = (asm_insn_count (PATTERN (inner_insn))
709                                 * insn_default_length (inner_insn));
710               else
711                 inner_length = insn_default_length (inner_insn);
712               
713               insn_lengths[inner_uid] = inner_length;
714               if (const_delay_slots)
715                 {
716                   if ((varying_length[inner_uid]
717                        = insn_variable_length_p (inner_insn)) != 0)
718                     varying_length[uid] = 1;
719                   insn_addresses[inner_uid] = (insn_current_address +
720                                                insn_lengths[uid]);
721                 }
722               else
723                 varying_length[inner_uid] = 0;
724               insn_lengths[uid] += inner_length;
725             }
726         }
727       else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER)
728         {
729           insn_lengths[uid] = insn_default_length (insn);
730           varying_length[uid] = insn_variable_length_p (insn);
731         }
732
733       /* If needed, do any adjustment.  */
734 #ifdef ADJUST_INSN_LENGTH
735       ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
736 #endif
737     }
738
739   /* Now loop over all the insns finding varying length insns.  For each,
740      get the current insn length.  If it has changed, reflect the change.
741      When nothing changes for a full pass, we are done.  */
742
743   while (something_changed)
744     {
745       something_changed = 0;
746       for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
747            insn != 0;
748            insn = NEXT_INSN (insn))
749         {
750           int new_length;
751           int tmp_length;
752
753           uid = INSN_UID (insn);
754           insn_addresses[uid] = insn_current_address;
755           if (! varying_length[uid])
756             {
757               insn_current_address += insn_lengths[uid];
758               continue;
759             }
760           if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
761             {
762               int i;
763               
764               body = PATTERN (insn);
765               new_length = 0;
766               for (i = 0; i < XVECLEN (body, 0); i++)
767                 {
768                   rtx inner_insn = XVECEXP (body, 0, i);
769                   int inner_uid = INSN_UID (inner_insn);
770                   int inner_length;
771
772                   insn_addresses[inner_uid] = insn_current_address;
773
774                   /* insn_current_length returns 0 for insns with a
775                      non-varying length.  */
776                   if (! varying_length[inner_uid])
777                     inner_length = insn_lengths[inner_uid];
778                   else
779                     inner_length = insn_current_length (inner_insn);
780
781                   if (inner_length != insn_lengths[inner_uid])
782                     {
783                       insn_lengths[inner_uid] = inner_length;
784                       something_changed = 1;
785                     }
786                   insn_current_address += insn_lengths[inner_uid];
787                   new_length += inner_length;
788                 }
789             }
790           else
791             {
792               new_length = insn_current_length (insn);
793               insn_current_address += new_length;
794             }
795
796 #ifdef SHORTEN_WITH_ADJUST_INSN_LENGTH
797 #ifdef ADJUST_INSN_LENGTH
798           /* If needed, do any adjustment.  */
799           tmp_length = new_length;
800           ADJUST_INSN_LENGTH (insn, new_length);
801           insn_current_address += (new_length - tmp_length);
802 #endif
803 #endif
804
805           if (new_length != insn_lengths[uid])
806             {
807               insn_lengths[uid] = new_length;
808               something_changed = 1;
809             }
810         }
811     }
812 #endif /* HAVE_ATTR_length */
813 }
814
815 #ifdef HAVE_ATTR_length
816 /* Given the body of an INSN known to be generated by an ASM statement, return
817    the number of machine instructions likely to be generated for this insn.
818    This is used to compute its length.  */
819
820 static int
821 asm_insn_count (body)
822      rtx body;
823 {
824   char *template;
825   int count = 1;
826
827   if (GET_CODE (body) == ASM_INPUT)
828     template = XSTR (body, 0);
829   else
830     template = decode_asm_operands (body, NULL_PTR, NULL_PTR,
831                                     NULL_PTR, NULL_PTR);
832
833   for ( ; *template; template++)
834     if (IS_ASM_LOGICAL_LINE_SEPARATOR(*template) || *template == '\n')
835       count++;
836
837   return count;
838 }
839 #endif
840 \f
841 /* Output assembler code for the start of a function,
842    and initialize some of the variables in this file
843    for the new function.  The label for the function and associated
844    assembler pseudo-ops have already been output in `assemble_start_function'.
845
846    FIRST is the first insn of the rtl for the function being compiled.
847    FILE is the file to write assembler code to.
848    OPTIMIZE is nonzero if we should eliminate redundant
849      test and compare insns.  */
850
851 void
852 final_start_function (first, file, optimize)
853      rtx first;
854      FILE *file;
855      int optimize;
856 {
857   block_depth = 0;
858
859   this_is_asm_operands = 0;
860
861 #ifdef NON_SAVING_SETJMP
862   /* A function that calls setjmp should save and restore all the
863      call-saved registers on a system where longjmp clobbers them.  */
864   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
865     {
866       int i;
867
868       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
869         if (!call_used_regs[i] && !call_fixed_regs[i])
870           regs_ever_live[i] = 1;
871     }
872 #endif
873   
874   /* Initial line number is supposed to be output
875      before the function's prologue and label
876      so that the function's address will not appear to be
877      in the last statement of the preceding function.  */
878   if (NOTE_LINE_NUMBER (first) != NOTE_INSN_DELETED)
879     {
880       if (write_symbols == SDB_DEBUG)
881         /* For sdb, let's not, but say we did.
882            We need to set last_linenum for sdbout_function_begin,
883            but we can't have an actual line number before the .bf symbol.
884            (sdb_begin_function_line is not set,
885            and other compilers don't do it.)  */
886         last_linenum = NOTE_LINE_NUMBER (first);
887 #ifdef XCOFF_DEBUGGING_INFO
888       else if (write_symbols == XCOFF_DEBUG)
889         {
890           last_linenum = NOTE_LINE_NUMBER (first);
891           xcoffout_output_first_source_line (file, last_linenum);
892         }
893 #endif    
894       else
895         output_source_line (file, first);
896     }
897
898 #ifdef LEAF_REG_REMAP
899   if (leaf_function)
900     leaf_renumber_regs (first);
901 #endif
902
903   /* The Sun386i and perhaps other machines don't work right
904      if the profiling code comes after the prologue.  */
905 #ifdef PROFILE_BEFORE_PROLOGUE
906   if (profile_flag)
907     profile_function (file);
908 #endif /* PROFILE_BEFORE_PROLOGUE */
909
910 #ifdef FUNCTION_PROLOGUE
911   /* First output the function prologue: code to set up the stack frame.  */
912   FUNCTION_PROLOGUE (file, get_frame_size ());
913 #endif
914
915 #if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
916   if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
917     next_block_index = 1;
918 #endif
919
920   /* If the machine represents the prologue as RTL, the profiling code must
921      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
922 #ifdef HAVE_prologue
923   if (! HAVE_prologue)
924 #endif
925     profile_after_prologue (file);
926
927   profile_label_no++;
928
929   /* If we are doing basic block profiling, remember a printable version
930      of the function name.  */
931   if (profile_block_flag)
932     {
933       char *junk = "function";
934       bb_func_label_num =
935         add_bb_string ((*decl_printable_name) (current_function_decl, &junk), FALSE);
936     }
937 }
938
939 static void
940 profile_after_prologue (file)
941      FILE *file;
942 {
943 #ifdef FUNCTION_BLOCK_PROFILER
944   if (profile_block_flag)
945     {
946       FUNCTION_BLOCK_PROFILER (file, profile_label_no);
947     }
948 #endif /* FUNCTION_BLOCK_PROFILER */
949
950 #ifndef PROFILE_BEFORE_PROLOGUE
951   if (profile_flag)
952     profile_function (file);
953 #endif /* not PROFILE_BEFORE_PROLOGUE */
954 }
955
956 static void
957 profile_function (file)
958      FILE *file;
959 {
960   int align = MIN (BIGGEST_ALIGNMENT, POINTER_SIZE);
961   int sval = current_function_returns_struct;
962   int cxt = current_function_needs_context;
963
964   data_section ();
965   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
966   ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no);
967   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
968
969   text_section ();
970
971 #ifdef STRUCT_VALUE_INCOMING_REGNUM
972   if (sval)
973     ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM);
974 #else
975 #ifdef STRUCT_VALUE_REGNUM
976   if (sval)
977     ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM);
978 #endif
979 #endif
980
981 #if 0
982 #ifdef STATIC_CHAIN_INCOMING_REGNUM
983   if (cxt)
984     ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_INCOMING_REGNUM);
985 #else
986 #ifdef STATIC_CHAIN_REGNUM
987   if (cxt)
988     ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM);
989 #endif
990 #endif
991 #endif                          /* 0 */
992
993   FUNCTION_PROFILER (file, profile_label_no);
994
995 #if 0
996 #ifdef STATIC_CHAIN_INCOMING_REGNUM
997   if (cxt)
998     ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM);
999 #else
1000 #ifdef STATIC_CHAIN_REGNUM
1001   if (cxt)
1002     ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_REGNUM);
1003 #endif
1004 #endif
1005 #endif                          /* 0 */
1006
1007 #ifdef STRUCT_VALUE_INCOMING_REGNUM
1008   if (sval)
1009     ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM);
1010 #else
1011 #ifdef STRUCT_VALUE_REGNUM
1012   if (sval)
1013     ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM);
1014 #endif
1015 #endif
1016 }
1017
1018 /* Output assembler code for the end of a function.
1019    For clarity, args are same as those of `final_start_function'
1020    even though not all of them are needed.  */
1021
1022 void
1023 final_end_function (first, file, optimize)
1024      rtx first;
1025      FILE *file;
1026      int optimize;
1027 {
1028   if (app_on)
1029     {
1030       fprintf (file, ASM_APP_OFF);
1031       app_on = 0;
1032     }
1033
1034 #ifdef SDB_DEBUGGING_INFO
1035   if (write_symbols == SDB_DEBUG)
1036     sdbout_end_function (last_linenum);
1037 #endif
1038
1039 #ifdef DWARF_DEBUGGING_INFO
1040   if (write_symbols == DWARF_DEBUG)
1041     dwarfout_end_function ();
1042 #endif
1043
1044 #ifdef XCOFF_DEBUGGING_INFO
1045   if (write_symbols == XCOFF_DEBUG)
1046     xcoffout_end_function (file, last_linenum);
1047 #endif
1048
1049 #ifdef FUNCTION_EPILOGUE
1050   /* Finally, output the function epilogue:
1051      code to restore the stack frame and return to the caller.  */
1052   FUNCTION_EPILOGUE (file, get_frame_size ());
1053 #endif
1054
1055 #ifdef SDB_DEBUGGING_INFO
1056   if (write_symbols == SDB_DEBUG)
1057     sdbout_end_epilogue ();
1058 #endif
1059
1060 #ifdef DWARF_DEBUGGING_INFO
1061   if (write_symbols == DWARF_DEBUG)
1062     dwarfout_end_epilogue ();
1063 #endif
1064
1065 #ifdef XCOFF_DEBUGGING_INFO
1066   if (write_symbols == XCOFF_DEBUG)
1067     xcoffout_end_epilogue (file);
1068 #endif
1069
1070   bb_func_label_num = -1;       /* not in function, nuke label # */
1071
1072   /* If FUNCTION_EPILOGUE is not defined, then the function body
1073      itself contains return instructions wherever needed.  */
1074 }
1075 \f
1076 /* Add a block to the linked list that remembers the current line/file/function
1077    for basic block profiling.  Emit the label in front of the basic block and
1078    the instructions that increment the count field.  */
1079
1080 static void
1081 add_bb (file)
1082      FILE *file;
1083 {
1084   struct bb_list *ptr = (struct bb_list *) permalloc (sizeof (struct bb_list));
1085
1086   /* Add basic block to linked list.  */
1087   ptr->next = 0;
1088   ptr->line_num = last_linenum;
1089   ptr->file_label_num = bb_file_label_num;
1090   ptr->func_label_num = bb_func_label_num;
1091   *bb_tail = ptr;
1092   bb_tail = &ptr->next;
1093
1094   /* Enable the table of basic-block use counts
1095      to point at the code it applies to.  */
1096   ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);
1097
1098   /* Before first insn of this basic block, increment the
1099      count of times it was entered.  */
1100 #ifdef BLOCK_PROFILER
1101   BLOCK_PROFILER (file, count_basic_blocks);
1102   CC_STATUS_INIT;
1103 #endif
1104
1105   new_block = 0;
1106   count_basic_blocks++;
1107 }
1108
1109 /* Add a string to be used for basic block profiling.  */
1110
1111 static int
1112 add_bb_string (string, perm_p)
1113      char *string;
1114      int perm_p;
1115 {
1116   int len;
1117   struct bb_str *ptr = 0;
1118
1119   if (!string)
1120     {
1121       string = "<unknown>";
1122       perm_p = TRUE;
1123     }
1124
1125   /* Allocate a new string if the current string isn't permanent.  If
1126      the string is permanent search for the same string in other
1127      allocations.  */
1128
1129   len = strlen (string) + 1;
1130   if (!perm_p)
1131     {
1132       char *p = (char *) permalloc (len);
1133       bcopy (string, p, len);
1134       string = p;
1135     }
1136   else
1137     for (ptr = sbb_head; ptr != (struct bb_str *)0; ptr = ptr->next)
1138       if (ptr->string == string)
1139         break;
1140
1141   /* Allocate a new string block if we need to.  */
1142   if (!ptr)
1143     {
1144       ptr = (struct bb_str *) permalloc (sizeof (*ptr));
1145       ptr->next = 0;
1146       ptr->length = len;
1147       ptr->label_num = sbb_label_num++;
1148       ptr->string = string;
1149       *sbb_tail = ptr;
1150       sbb_tail = &ptr->next;
1151     }
1152
1153   return ptr->label_num;
1154 }
1155
1156 \f
1157 /* Output assembler code for some insns: all or part of a function.
1158    For description of args, see `final_start_function', above.
1159
1160    PRESCAN is 1 if we are not really outputting,
1161      just scanning as if we were outputting.
1162    Prescanning deletes and rearranges insns just like ordinary output.
1163    PRESCAN is -2 if we are outputting after having prescanned.
1164    In this case, don't try to delete or rearrange insns
1165    because that has already been done.
1166    Prescanning is done only on certain machines.  */
1167
1168 void
1169 final (first, file, optimize, prescan)
1170      rtx first;
1171      FILE *file;
1172      int optimize;
1173      int prescan;
1174 {
1175   register rtx insn;
1176   int max_line = 0;
1177
1178   last_ignored_compare = 0;
1179   new_block = 1;
1180
1181   /* Make a map indicating which line numbers appear in this function.
1182      When producing SDB debugging info, delete troublesome line number
1183      notes from inlined functions in other files as well as duplicate
1184      line number notes.  */
1185 #ifdef SDB_DEBUGGING_INFO
1186   if (write_symbols == SDB_DEBUG)
1187     {
1188       rtx last = 0;
1189       for (insn = first; insn; insn = NEXT_INSN (insn))
1190         if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1191           {
1192             if ((RTX_INTEGRATED_P (insn)
1193                  && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
1194                  || (last != 0
1195                      && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
1196                      && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
1197               {
1198                 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
1199                 NOTE_SOURCE_FILE (insn) = 0;
1200                 continue;
1201               }
1202             last = insn;
1203             if (NOTE_LINE_NUMBER (insn) > max_line)
1204               max_line = NOTE_LINE_NUMBER (insn);
1205           }
1206     }
1207   else
1208 #endif
1209     {
1210       for (insn = first; insn; insn = NEXT_INSN (insn))
1211         if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)
1212           max_line = NOTE_LINE_NUMBER (insn);
1213     }
1214
1215   line_note_exists = (char *) oballoc (max_line + 1);
1216   bzero (line_note_exists, max_line + 1);
1217
1218   for (insn = first; insn; insn = NEXT_INSN (insn))
1219     if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1220       line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
1221
1222   init_recog ();
1223
1224   CC_STATUS_INIT;
1225
1226   /* Output the insns.  */
1227   for (insn = NEXT_INSN (first); insn;)
1228     insn = final_scan_insn (insn, file, optimize, prescan, 0);
1229
1230   /* Do basic-block profiling here
1231      if the last insn was a conditional branch.  */
1232   if (profile_block_flag && new_block)
1233     add_bb (file);
1234 }
1235 \f
1236 /* The final scan for one insn, INSN.
1237    Args are same as in `final', except that INSN
1238    is the insn being scanned.
1239    Value returned is the next insn to be scanned.
1240
1241    NOPEEPHOLES is the flag to disallow peephole processing (currently
1242    used for within delayed branch sequence output).  */
1243
1244 rtx
1245 final_scan_insn (insn, file, optimize, prescan, nopeepholes)
1246      rtx insn;
1247      FILE *file;
1248      int optimize;
1249      int prescan;
1250      int nopeepholes;
1251 {
1252   register int i;
1253   insn_counter++;
1254
1255   /* Ignore deleted insns.  These can occur when we split insns (due to a
1256      template of "#") while not optimizing.  */
1257   if (INSN_DELETED_P (insn))
1258     return NEXT_INSN (insn);
1259
1260   switch (GET_CODE (insn))
1261     {
1262     case NOTE:
1263       if (prescan > 0)
1264         break;
1265
1266       /* Align the beginning of a loop, for higher speed
1267          on certain machines.  */
1268
1269       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG && optimize > 0)
1270         {
1271 #ifdef ASM_OUTPUT_LOOP_ALIGN
1272           rtx next = next_nonnote_insn (insn);
1273           if (next && GET_CODE (next) == CODE_LABEL)
1274             {
1275               ASM_OUTPUT_LOOP_ALIGN (asm_out_file);
1276             }
1277 #endif
1278           break;
1279         }
1280       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
1281         break;
1282
1283       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
1284         {
1285 #ifdef FUNCTION_END_PROLOGUE
1286           FUNCTION_END_PROLOGUE (file);
1287 #endif
1288           profile_after_prologue (file);
1289           break;
1290         }
1291
1292 #ifdef FUNCTION_BEGIN_EPILOGUE
1293       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
1294         {
1295           FUNCTION_BEGIN_EPILOGUE (file);
1296           break;
1297         }
1298 #endif
1299
1300       if (write_symbols == NO_DEBUG)
1301         break;
1302       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
1303         {
1304 #ifdef SDB_DEBUGGING_INFO
1305           if (write_symbols == SDB_DEBUG)
1306             sdbout_begin_function (last_linenum);
1307 #endif
1308 #ifdef XCOFF_DEBUGGING_INFO
1309           if (write_symbols == XCOFF_DEBUG)
1310             xcoffout_begin_function (file, last_linenum);
1311 #endif
1312 #ifdef DWARF_DEBUGGING_INFO
1313           if (write_symbols == DWARF_DEBUG)
1314             dwarfout_begin_function ();
1315 #endif
1316           break;
1317         }
1318       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
1319         break;                  /* An insn that was "deleted" */
1320       if (app_on)
1321         {
1322           fprintf (file, ASM_APP_OFF);
1323           app_on = 0;
1324         }
1325       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
1326           && (debug_info_level == DINFO_LEVEL_NORMAL
1327               || debug_info_level == DINFO_LEVEL_VERBOSE
1328 #ifdef DWARF_DEBUGGING_INFO
1329               || write_symbols == DWARF_DEBUG
1330 #endif
1331              )
1332          )
1333         {
1334           /* Beginning of a symbol-block.  Assign it a sequence number
1335              and push the number onto the stack PENDING_BLOCKS.  */
1336
1337           if (block_depth == max_block_depth)
1338             {
1339               /* PENDING_BLOCKS is full; make it longer.  */
1340               max_block_depth *= 2;
1341               pending_blocks
1342                 = (int *) xrealloc (pending_blocks,
1343                                     max_block_depth * sizeof (int));
1344             }
1345           pending_blocks[block_depth++] = next_block_index;
1346
1347           /* Output debugging info about the symbol-block beginning.  */
1348
1349 #ifdef SDB_DEBUGGING_INFO
1350           if (write_symbols == SDB_DEBUG)
1351             sdbout_begin_block (file, last_linenum, next_block_index);
1352 #endif
1353 #ifdef XCOFF_DEBUGGING_INFO
1354           if (write_symbols == XCOFF_DEBUG)
1355             xcoffout_begin_block (file, last_linenum, next_block_index);
1356 #endif
1357 #ifdef DBX_DEBUGGING_INFO
1358           if (write_symbols == DBX_DEBUG)
1359             ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index);
1360 #endif
1361 #ifdef DWARF_DEBUGGING_INFO
1362           if (write_symbols == DWARF_DEBUG && block_depth > 1)
1363             dwarfout_begin_block (next_block_index);
1364 #endif
1365
1366           next_block_index++;
1367         }
1368       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
1369                && (debug_info_level == DINFO_LEVEL_NORMAL
1370                    || debug_info_level == DINFO_LEVEL_VERBOSE
1371 #ifdef DWARF_DEBUGGING_INFO
1372                    || write_symbols == DWARF_DEBUG
1373 #endif
1374                   )
1375               )
1376         {
1377           /* End of a symbol-block.  Pop its sequence number off
1378              PENDING_BLOCKS and output debugging info based on that.  */
1379
1380           --block_depth;
1381
1382 #ifdef XCOFF_DEBUGGING_INFO
1383           if (write_symbols == XCOFF_DEBUG && block_depth >= 0)
1384             xcoffout_end_block (file, last_linenum, pending_blocks[block_depth]);
1385 #endif
1386 #ifdef DBX_DEBUGGING_INFO
1387           if (write_symbols == DBX_DEBUG && block_depth >= 0)
1388             ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",
1389                                        pending_blocks[block_depth]);
1390 #endif
1391 #ifdef SDB_DEBUGGING_INFO
1392           if (write_symbols == SDB_DEBUG && block_depth >= 0)
1393             sdbout_end_block (file, last_linenum, pending_blocks[block_depth]);
1394 #endif
1395 #ifdef DWARF_DEBUGGING_INFO
1396           if (write_symbols == DWARF_DEBUG && block_depth >= 1)
1397             dwarfout_end_block (pending_blocks[block_depth]);
1398 #endif
1399         }
1400       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL
1401                && (debug_info_level == DINFO_LEVEL_NORMAL
1402                    || debug_info_level == DINFO_LEVEL_VERBOSE))
1403         {
1404 #ifdef DWARF_DEBUGGING_INFO
1405           if (write_symbols == DWARF_DEBUG)
1406             dwarfout_label (insn);
1407 #endif
1408         }
1409       else if (NOTE_LINE_NUMBER (insn) > 0)
1410         /* This note is a line-number.  */
1411         {
1412           register rtx note;
1413
1414 #if 0 /* This is what we used to do.  */
1415           output_source_line (file, insn);
1416 #endif
1417           int note_after = 0;
1418
1419           /* If there is anything real after this note,
1420              output it.  If another line note follows, omit this one.  */
1421           for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
1422             {
1423               if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
1424                 break;
1425               /* These types of notes can be significant
1426                  so make sure the preceding line number stays.  */
1427               else if (GET_CODE (note) == NOTE
1428                        && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
1429                            || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
1430                            || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
1431                 break;
1432               else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
1433                 {
1434                   /* Another line note follows; we can delete this note
1435                      if no intervening line numbers have notes elsewhere.  */
1436                   int num;
1437                   for (num = NOTE_LINE_NUMBER (insn) + 1;
1438                        num < NOTE_LINE_NUMBER (note);
1439                        num++)
1440                     if (line_note_exists[num])
1441                       break;
1442
1443                   if (num >= NOTE_LINE_NUMBER (note))
1444                     note_after = 1;
1445                   break;
1446                 }
1447             }
1448
1449           /* Output this line note
1450              if it is the first or the last line note in a row.  */
1451           if (!note_after)
1452             output_source_line (file, insn);
1453         }
1454       break;
1455
1456     case BARRIER:
1457 #ifdef ASM_OUTPUT_ALIGN_CODE
1458       /* Don't litter the assembler output with needless alignments.  A
1459          BARRIER will be placed at the end of every function if HAVE_epilogue
1460          is true.  */    
1461       if (NEXT_INSN (insn))
1462         ASM_OUTPUT_ALIGN_CODE (file);
1463 #endif
1464       break;
1465
1466     case CODE_LABEL:
1467       CC_STATUS_INIT;
1468       if (prescan > 0)
1469         break;
1470       new_block = 1;
1471 #ifdef SDB_DEBUGGING_INFO
1472       if (write_symbols == SDB_DEBUG && LABEL_NAME (insn))
1473         sdbout_label (insn);
1474 #endif
1475 #ifdef DWARF_DEBUGGING_INFO
1476       if (write_symbols == DWARF_DEBUG && LABEL_NAME (insn))
1477         dwarfout_label (insn);
1478 #endif
1479       if (app_on)
1480         {
1481           fprintf (file, ASM_APP_OFF);
1482           app_on = 0;
1483         }
1484       if (NEXT_INSN (insn) != 0
1485           && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
1486         {
1487           rtx nextbody = PATTERN (NEXT_INSN (insn));
1488
1489           /* If this label is followed by a jump-table,
1490              make sure we put the label in the read-only section.  Also
1491              possibly write the label and jump table together.  */
1492
1493           if (GET_CODE (nextbody) == ADDR_VEC
1494               || GET_CODE (nextbody) == ADDR_DIFF_VEC)
1495             {
1496 #ifndef JUMP_TABLES_IN_TEXT_SECTION
1497               readonly_data_section ();
1498 #ifdef READONLY_DATA_SECTION
1499               ASM_OUTPUT_ALIGN (file,
1500                                 exact_log2 (BIGGEST_ALIGNMENT
1501                                             / BITS_PER_UNIT));
1502 #endif /* READONLY_DATA_SECTION */
1503 #else /* JUMP_TABLES_IN_TEXT_SECTION */
1504               text_section ();
1505 #endif /* JUMP_TABLES_IN_TEXT_SECTION */
1506 #ifdef ASM_OUTPUT_CASE_LABEL
1507               ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
1508                                      NEXT_INSN (insn));
1509 #else
1510               ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
1511 #endif
1512               break;
1513             }
1514         }
1515
1516       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
1517       break;
1518
1519     default:
1520       {
1521         register rtx body = PATTERN (insn);
1522         int insn_code_number;
1523         char *template;
1524         rtx note;
1525
1526         /* An INSN, JUMP_INSN or CALL_INSN.
1527            First check for special kinds that recog doesn't recognize.  */
1528
1529         if (GET_CODE (body) == USE /* These are just declarations */
1530             || GET_CODE (body) == CLOBBER)
1531           break;
1532
1533 #ifdef HAVE_cc0
1534         /* If there is a REG_CC_SETTER note on this insn, it means that
1535            the setting of the condition code was done in the delay slot
1536            of the insn that branched here.  So recover the cc status
1537            from the insn that set it.  */
1538
1539         note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
1540         if (note)
1541           {
1542             NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));
1543             cc_prev_status = cc_status;
1544           }
1545 #endif
1546
1547         /* Detect insns that are really jump-tables
1548            and output them as such.  */
1549
1550         if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
1551           {
1552             register int vlen, idx;
1553
1554             if (prescan > 0)
1555               break;
1556
1557             if (app_on)
1558               {
1559                 fprintf (file, ASM_APP_OFF);
1560                 app_on = 0;
1561               }
1562
1563             vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
1564             for (idx = 0; idx < vlen; idx++)
1565               {
1566                 if (GET_CODE (body) == ADDR_VEC)
1567                   {
1568 #ifdef ASM_OUTPUT_ADDR_VEC_ELT
1569                     ASM_OUTPUT_ADDR_VEC_ELT
1570                       (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
1571 #else
1572                     abort ();
1573 #endif
1574                   }
1575                 else
1576                   {
1577 #ifdef ASM_OUTPUT_ADDR_DIFF_ELT
1578                     ASM_OUTPUT_ADDR_DIFF_ELT
1579                       (file,
1580                        CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
1581                        CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
1582 #else
1583                     abort ();
1584 #endif
1585                   }
1586               }
1587 #ifdef ASM_OUTPUT_CASE_END
1588             ASM_OUTPUT_CASE_END (file,
1589                                  CODE_LABEL_NUMBER (PREV_INSN (insn)),
1590                                  insn);
1591 #endif
1592
1593             text_section ();
1594
1595             break;
1596           }
1597
1598         /* Do basic-block profiling when we reach a new block.
1599            Done here to avoid jump tables.  */
1600         if (profile_block_flag && new_block)
1601           add_bb (file);
1602
1603         if (GET_CODE (body) == ASM_INPUT)
1604           {
1605             /* There's no telling what that did to the condition codes.  */
1606             CC_STATUS_INIT;
1607             if (prescan > 0)
1608               break;
1609             if (! app_on)
1610               {
1611                 fprintf (file, ASM_APP_ON);
1612                 app_on = 1;
1613               }
1614             fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));
1615             break;
1616           }
1617
1618         /* Detect `asm' construct with operands.  */
1619         if (asm_noperands (body) >= 0)
1620           {
1621             int noperands = asm_noperands (body);
1622             rtx *ops = (rtx *) alloca (noperands * sizeof (rtx));
1623             char *string;
1624
1625             /* There's no telling what that did to the condition codes.  */
1626             CC_STATUS_INIT;
1627             if (prescan > 0)
1628               break;
1629
1630             if (! app_on)
1631               {
1632                 fprintf (file, ASM_APP_ON);
1633                 app_on = 1;
1634               }
1635
1636             /* Get out the operand values.  */
1637             string = decode_asm_operands (body, ops, NULL_PTR,
1638                                           NULL_PTR, NULL_PTR);
1639             /* Inhibit aborts on what would otherwise be compiler bugs.  */
1640             insn_noperands = noperands;
1641             this_is_asm_operands = insn;
1642
1643             /* Output the insn using them.  */
1644             output_asm_insn (string, ops);
1645             this_is_asm_operands = 0;
1646             break;
1647           }
1648
1649         if (prescan <= 0 && app_on)
1650           {
1651             fprintf (file, ASM_APP_OFF);
1652             app_on = 0;
1653           }
1654
1655         if (GET_CODE (body) == SEQUENCE)
1656           {
1657             /* A delayed-branch sequence */
1658             register int i;
1659             rtx next;
1660
1661             if (prescan > 0)
1662               break;
1663             final_sequence = body;
1664
1665             /* The first insn in this SEQUENCE might be a JUMP_INSN that will
1666                force the restoration of a comparison that was previously
1667                thought unnecessary.  If that happens, cancel this sequence
1668                and cause that insn to be restored.  */
1669
1670             next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);
1671             if (next != XVECEXP (body, 0, 1))
1672               {
1673                 final_sequence = 0;
1674                 return next;
1675               }
1676
1677             for (i = 1; i < XVECLEN (body, 0); i++)
1678               final_scan_insn (XVECEXP (body, 0, i), file, 0, prescan, 1);
1679 #ifdef DBR_OUTPUT_SEQEND
1680             DBR_OUTPUT_SEQEND (file);
1681 #endif
1682             final_sequence = 0;
1683
1684             /* If the insn requiring the delay slot was a CALL_INSN, the
1685                insns in the delay slot are actually executed before the
1686                called function.  Hence we don't preserve any CC-setting
1687                actions in these insns and the CC must be marked as being
1688                clobbered by the function.  */
1689             if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)
1690               CC_STATUS_INIT;
1691
1692             /* Following a conditional branch sequence, we have a new basic
1693                block.  */
1694             if (profile_block_flag)
1695               {
1696                 rtx insn = XVECEXP (body, 0, 0);
1697                 rtx body = PATTERN (insn);
1698
1699                 if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
1700                      && GET_CODE (SET_SRC (body)) != LABEL_REF)
1701                     || (GET_CODE (insn) == JUMP_INSN
1702                         && GET_CODE (body) == PARALLEL
1703                         && GET_CODE (XVECEXP (body, 0, 0)) == SET
1704                         && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))
1705                   new_block = 1;
1706               }
1707             break;
1708           }
1709
1710         /* We have a real machine instruction as rtl.  */
1711
1712         body = PATTERN (insn);
1713
1714 #ifdef HAVE_cc0
1715         /* Check for redundant test and compare instructions
1716            (when the condition codes are already set up as desired).
1717            This is done only when optimizing; if not optimizing,
1718            it should be possible for the user to alter a variable
1719            with the debugger in between statements
1720            and the next statement should reexamine the variable
1721            to compute the condition codes.  */
1722
1723         if (optimize
1724             && GET_CODE (body) == SET
1725             && GET_CODE (SET_DEST (body)) == CC0
1726             && insn != last_ignored_compare)
1727           {
1728             if (GET_CODE (SET_SRC (body)) == SUBREG)
1729               SET_SRC (body) = alter_subreg (SET_SRC (body));
1730             else if (GET_CODE (SET_SRC (body)) == COMPARE)
1731               {
1732                 if (GET_CODE (XEXP (SET_SRC (body), 0)) == SUBREG)
1733                   XEXP (SET_SRC (body), 0)
1734                     = alter_subreg (XEXP (SET_SRC (body), 0));
1735                 if (GET_CODE (XEXP (SET_SRC (body), 1)) == SUBREG)
1736                   XEXP (SET_SRC (body), 1)
1737                     = alter_subreg (XEXP (SET_SRC (body), 1));
1738               }
1739             if ((cc_status.value1 != 0
1740                  && rtx_equal_p (SET_SRC (body), cc_status.value1))
1741                 || (cc_status.value2 != 0
1742                     && rtx_equal_p (SET_SRC (body), cc_status.value2)))
1743               {
1744                 /* Don't delete insn if it has an addressing side-effect.  */
1745                 if (! FIND_REG_INC_NOTE (insn, 0)
1746                     /* or if anything in it is volatile.  */
1747                     && ! volatile_refs_p (PATTERN (insn)))
1748                   {
1749                     /* We don't really delete the insn; just ignore it.  */
1750                     last_ignored_compare = insn;
1751                     break;
1752                   }
1753               }
1754           }
1755 #endif
1756
1757         /* Following a conditional branch, we have a new basic block.
1758            But if we are inside a sequence, the new block starts after the
1759            last insn of the sequence.  */
1760         if (profile_block_flag && final_sequence == 0
1761             && ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
1762                  && GET_CODE (SET_SRC (body)) != LABEL_REF)
1763                 || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL
1764                     && GET_CODE (XVECEXP (body, 0, 0)) == SET
1765                     && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)))
1766           new_block = 1;
1767
1768 #ifndef STACK_REGS
1769         /* Don't bother outputting obvious no-ops, even without -O.
1770            This optimization is fast and doesn't interfere with debugging.
1771            Don't do this if the insn is in a delay slot, since this
1772            will cause an improper number of delay insns to be written.  */
1773         if (final_sequence == 0
1774             && prescan >= 0
1775             && GET_CODE (insn) == INSN && GET_CODE (body) == SET
1776             && GET_CODE (SET_SRC (body)) == REG
1777             && GET_CODE (SET_DEST (body)) == REG
1778             && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
1779           break;
1780 #endif
1781
1782 #ifdef HAVE_cc0
1783         /* If this is a conditional branch, maybe modify it
1784            if the cc's are in a nonstandard state
1785            so that it accomplishes the same thing that it would
1786            do straightforwardly if the cc's were set up normally.  */
1787
1788         if (cc_status.flags != 0
1789             && GET_CODE (insn) == JUMP_INSN
1790             && GET_CODE (body) == SET
1791             && SET_DEST (body) == pc_rtx
1792             && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
1793             /* This is done during prescan; it is not done again
1794                in final scan when prescan has been done.  */
1795             && prescan >= 0)
1796           {
1797             /* This function may alter the contents of its argument
1798                and clear some of the cc_status.flags bits.
1799                It may also return 1 meaning condition now always true
1800                or -1 meaning condition now always false
1801                or 2 meaning condition nontrivial but altered.  */
1802             register int result = alter_cond (XEXP (SET_SRC (body), 0));
1803             /* If condition now has fixed value, replace the IF_THEN_ELSE
1804                with its then-operand or its else-operand.  */
1805             if (result == 1)
1806               SET_SRC (body) = XEXP (SET_SRC (body), 1);
1807             if (result == -1)
1808               SET_SRC (body) = XEXP (SET_SRC (body), 2);
1809
1810             /* The jump is now either unconditional or a no-op.
1811                If it has become a no-op, don't try to output it.
1812                (It would not be recognized.)  */
1813             if (SET_SRC (body) == pc_rtx)
1814               {
1815                 PUT_CODE (insn, NOTE);
1816                 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
1817                 NOTE_SOURCE_FILE (insn) = 0;
1818                 break;
1819               }
1820             else if (GET_CODE (SET_SRC (body)) == RETURN)
1821               /* Replace (set (pc) (return)) with (return).  */
1822               PATTERN (insn) = body = SET_SRC (body);
1823
1824             /* Rerecognize the instruction if it has changed.  */
1825             if (result != 0)
1826               INSN_CODE (insn) = -1;
1827           }
1828
1829         /* Make same adjustments to instructions that examine the
1830            condition codes without jumping (if this machine has them).  */
1831
1832         if (cc_status.flags != 0
1833             && GET_CODE (body) == SET)
1834           {
1835             switch (GET_CODE (SET_SRC (body)))
1836               {
1837               case GTU:
1838               case GT:
1839               case LTU:
1840               case LT:
1841               case GEU:
1842               case GE:
1843               case LEU:
1844               case LE:
1845               case EQ:
1846               case NE:
1847                 {
1848                   register int result;
1849                   if (XEXP (SET_SRC (body), 0) != cc0_rtx)
1850                     break;
1851                   result = alter_cond (SET_SRC (body));
1852                   if (result == 1)
1853                     validate_change (insn, &SET_SRC (body), const_true_rtx, 0);
1854                   else if (result == -1)
1855                     validate_change (insn, &SET_SRC (body), const0_rtx, 0);
1856                   else if (result == 2)
1857                     INSN_CODE (insn) = -1;
1858                 }
1859               }
1860           }
1861 #endif
1862
1863         /* Do machine-specific peephole optimizations if desired.  */
1864
1865         if (optimize && !flag_no_peephole && !nopeepholes)
1866           {
1867             rtx next = peephole (insn);
1868             /* When peepholing, if there were notes within the peephole,
1869                emit them before the peephole.  */
1870             if (next != 0 && next != NEXT_INSN (insn))
1871               {
1872                 rtx prev = PREV_INSN (insn);
1873                 rtx note;
1874
1875                 for (note = NEXT_INSN (insn); note != next;
1876                      note = NEXT_INSN (note))
1877                   final_scan_insn (note, file, optimize, prescan, nopeepholes);
1878
1879                 /* In case this is prescan, put the notes
1880                    in proper position for later rescan.  */
1881                 note = NEXT_INSN (insn);
1882                 PREV_INSN (note) = prev;
1883                 NEXT_INSN (prev) = note;
1884                 NEXT_INSN (PREV_INSN (next)) = insn;
1885                 PREV_INSN (insn) = PREV_INSN (next);
1886                 NEXT_INSN (insn) = next;
1887                 PREV_INSN (next) = insn;
1888               }
1889
1890             /* PEEPHOLE might have changed this.  */
1891             body = PATTERN (insn);
1892           }
1893
1894         /* Try to recognize the instruction.
1895            If successful, verify that the operands satisfy the
1896            constraints for the instruction.  Crash if they don't,
1897            since `reload' should have changed them so that they do.  */
1898
1899         insn_code_number = recog_memoized (insn);
1900         insn_extract (insn);
1901         for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1902           {
1903             if (GET_CODE (recog_operand[i]) == SUBREG)
1904               recog_operand[i] = alter_subreg (recog_operand[i]);
1905             else if (GET_CODE (recog_operand[i]) == PLUS
1906                      || GET_CODE (recog_operand[i]) == MULT)
1907               recog_operand[i] = walk_alter_subreg (recog_operand[i]);
1908           }
1909
1910         for (i = 0; i < insn_n_dups[insn_code_number]; i++)
1911           {
1912             if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
1913               *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
1914             else if (GET_CODE (*recog_dup_loc[i]) == PLUS
1915                      || GET_CODE (*recog_dup_loc[i]) == MULT)
1916               *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
1917           }
1918
1919 #ifdef REGISTER_CONSTRAINTS
1920         if (! constrain_operands (insn_code_number, 1))
1921           fatal_insn_not_found (insn);
1922 #endif
1923
1924         /* Some target machines need to prescan each insn before
1925            it is output.  */
1926
1927 #ifdef FINAL_PRESCAN_INSN
1928         FINAL_PRESCAN_INSN (insn, recog_operand,
1929                             insn_n_operands[insn_code_number]);
1930 #endif
1931
1932 #ifdef HAVE_cc0
1933         cc_prev_status = cc_status;
1934
1935         /* Update `cc_status' for this instruction.
1936            The instruction's output routine may change it further.
1937            If the output routine for a jump insn needs to depend
1938            on the cc status, it should look at cc_prev_status.  */
1939
1940         NOTICE_UPDATE_CC (body, insn);
1941 #endif
1942
1943         debug_insn = insn;
1944
1945         /* If the proper template needs to be chosen by some C code,
1946            run that code and get the real template.  */
1947
1948         template = insn_template[insn_code_number];
1949         if (template == 0)
1950           {
1951             template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
1952
1953             /* If the C code returns 0, it means that it is a jump insn
1954                which follows a deleted test insn, and that test insn
1955                needs to be reinserted.  */
1956             if (template == 0)
1957               {
1958                 if (prev_nonnote_insn (insn) != last_ignored_compare)
1959                   abort ();
1960                 new_block = 0;
1961                 return prev_nonnote_insn (insn);
1962               }
1963           }
1964
1965         /* If the template is the string "#", it means that this insn must
1966            be split.  */
1967         if (template[0] == '#' && template[1] == '\0')
1968           {
1969             rtx new = try_split (body, insn, 0);
1970
1971             /* If we didn't split the insn, go away.  */
1972             if (new == insn && PATTERN (new) == body)
1973               abort ();
1974               
1975             new_block = 0;
1976             return new;
1977           }
1978         
1979         if (prescan > 0)
1980           break;
1981
1982         /* Output assembler code from the template.  */
1983
1984         output_asm_insn (template, recog_operand);
1985
1986 #if 0
1987         /* It's not at all clear why we did this and doing so interferes
1988            with tests we'd like to do to use REG_WAS_0 notes, so let's try
1989            with this out.  */
1990
1991         /* Mark this insn as having been output.  */
1992         INSN_DELETED_P (insn) = 1;
1993 #endif
1994
1995         debug_insn = 0;
1996       }
1997     }
1998   return NEXT_INSN (insn);
1999 }
2000 \f
2001 /* Output debugging info to the assembler file FILE
2002    based on the NOTE-insn INSN, assumed to be a line number.  */
2003
2004 static void
2005 output_source_line (file, insn)
2006      FILE *file;
2007      rtx insn;
2008 {
2009   register char *filename = NOTE_SOURCE_FILE (insn);
2010
2011   /* Remember filename for basic block profiling.
2012      Filenames are allocated on the permanent obstack
2013      or are passed in ARGV, so we don't have to save
2014      the string.  */
2015
2016   if (profile_block_flag && last_filename != filename)
2017     bb_file_label_num = add_bb_string (filename, TRUE);
2018
2019   last_filename = filename;
2020   last_linenum = NOTE_LINE_NUMBER (insn);
2021
2022   if (write_symbols != NO_DEBUG)
2023     {
2024 #ifdef SDB_DEBUGGING_INFO
2025       if (write_symbols == SDB_DEBUG
2026 #if 0 /* People like having line numbers even in wrong file!  */
2027           /* COFF can't handle multiple source files--lose, lose.  */
2028           && !strcmp (filename, main_input_filename)
2029 #endif
2030           /* COFF relative line numbers must be positive.  */
2031           && last_linenum > sdb_begin_function_line)
2032         {
2033 #ifdef ASM_OUTPUT_SOURCE_LINE
2034           ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
2035 #else
2036           fprintf (file, "\t.ln\t%d\n",
2037                    ((sdb_begin_function_line > -1)
2038                     ? last_linenum - sdb_begin_function_line : 1));
2039 #endif
2040         }
2041 #endif
2042
2043 #if defined (DBX_DEBUGGING_INFO)
2044       if (write_symbols == DBX_DEBUG)
2045         dbxout_source_line (file, filename, NOTE_LINE_NUMBER (insn));
2046 #endif
2047
2048 #if defined (XCOFF_DEBUGGING_INFO)
2049       if (write_symbols == XCOFF_DEBUG)
2050         xcoffout_source_line (file, filename, insn);
2051 #endif
2052
2053 #ifdef DWARF_DEBUGGING_INFO
2054       if (write_symbols == DWARF_DEBUG)
2055         dwarfout_line (filename, NOTE_LINE_NUMBER (insn));
2056 #endif
2057     }
2058 }
2059 \f
2060 /* If X is a SUBREG, replace it with a REG or a MEM,
2061    based on the thing it is a subreg of.  */
2062
2063 rtx
2064 alter_subreg (x)
2065      register rtx x;
2066 {
2067   register rtx y = SUBREG_REG (x);
2068   if (GET_CODE (y) == SUBREG)
2069     y = alter_subreg (y);
2070
2071   if (GET_CODE (y) == REG)
2072     {
2073       /* If the containing reg really gets a hard reg, so do we.  */
2074       PUT_CODE (x, REG);
2075       REGNO (x) = REGNO (y) + SUBREG_WORD (x);
2076     }
2077   else if (GET_CODE (y) == MEM)
2078     {
2079       register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
2080 #if BYTES_BIG_ENDIAN
2081       offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
2082                  - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
2083 #endif
2084       PUT_CODE (x, MEM);
2085       MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
2086       XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
2087     }
2088
2089   return x;
2090 }
2091
2092 /* Do alter_subreg on all the SUBREGs contained in X.  */
2093
2094 static rtx
2095 walk_alter_subreg (x)
2096      rtx x;
2097 {
2098   switch (GET_CODE (x))
2099     {
2100     case PLUS:
2101     case MULT:
2102       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
2103       XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1));
2104       break;
2105
2106     case MEM:
2107       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
2108       break;
2109
2110     case SUBREG:
2111       return alter_subreg (x);
2112     }
2113
2114   return x;
2115 }
2116 \f
2117 #ifdef HAVE_cc0
2118
2119 /* Given BODY, the body of a jump instruction, alter the jump condition
2120    as required by the bits that are set in cc_status.flags.
2121    Not all of the bits there can be handled at this level in all cases.
2122
2123    The value is normally 0.
2124    1 means that the condition has become always true.
2125    -1 means that the condition has become always false.
2126    2 means that COND has been altered.  */
2127
2128 static int
2129 alter_cond (cond)
2130      register rtx cond;
2131 {
2132   int value = 0;
2133
2134   if (cc_status.flags & CC_REVERSED)
2135     {
2136       value = 2;
2137       PUT_CODE (cond, swap_condition (GET_CODE (cond)));
2138     }
2139
2140   if (cc_status.flags & CC_INVERTED)
2141     {
2142       value = 2;
2143       PUT_CODE (cond, reverse_condition (GET_CODE (cond)));
2144     }
2145
2146   if (cc_status.flags & CC_NOT_POSITIVE)
2147     switch (GET_CODE (cond))
2148       {
2149       case LE:
2150       case LEU:
2151       case GEU:
2152         /* Jump becomes unconditional.  */
2153         return 1;
2154
2155       case GT:
2156       case GTU:
2157       case LTU:
2158         /* Jump becomes no-op.  */
2159         return -1;
2160
2161       case GE:
2162         PUT_CODE (cond, EQ);
2163         value = 2;
2164         break;
2165
2166       case LT:
2167         PUT_CODE (cond, NE);
2168         value = 2;
2169         break;
2170       }
2171
2172   if (cc_status.flags & CC_NOT_NEGATIVE)
2173     switch (GET_CODE (cond))
2174       {
2175       case GE:
2176       case GEU:
2177         /* Jump becomes unconditional.  */
2178         return 1;
2179
2180       case LT:
2181       case LTU:
2182         /* Jump becomes no-op.  */
2183         return -1;
2184
2185       case LE:
2186       case LEU:
2187         PUT_CODE (cond, EQ);
2188         value = 2;
2189         break;
2190
2191       case GT:
2192       case GTU:
2193         PUT_CODE (cond, NE);
2194         value = 2;
2195         break;
2196       }
2197
2198   if (cc_status.flags & CC_NO_OVERFLOW)
2199     switch (GET_CODE (cond))
2200       {
2201       case GEU:
2202         /* Jump becomes unconditional.  */
2203         return 1;
2204
2205       case LEU:
2206         PUT_CODE (cond, EQ);
2207         value = 2;
2208         break;
2209
2210       case GTU:
2211         PUT_CODE (cond, NE);
2212         value = 2;
2213         break;
2214
2215       case LTU:
2216         /* Jump becomes no-op.  */
2217         return -1;
2218       }
2219
2220   if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N))
2221     switch (GET_CODE (cond))
2222       {
2223       case LE:
2224       case LEU:
2225       case GE:
2226       case GEU:
2227       case LT:
2228       case LTU:
2229       case GT:
2230       case GTU:
2231         abort ();
2232
2233       case NE:
2234         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
2235         value = 2;
2236         break;
2237
2238       case EQ:
2239         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE);
2240         value = 2;
2241         break;
2242       }
2243
2244   if (cc_status.flags & CC_NOT_SIGNED)
2245     /* The flags are valid if signed condition operators are converted
2246        to unsigned.  */
2247     switch (GET_CODE (cond))
2248       {
2249       case LE:
2250         PUT_CODE (cond, LEU);
2251         value = 2;
2252         break;
2253
2254       case LT:
2255         PUT_CODE (cond, LTU);
2256         value = 2;
2257         break;
2258
2259       case GT:
2260         PUT_CODE (cond, GTU);
2261         value = 2;
2262         break;
2263
2264       case GE:
2265         PUT_CODE (cond, GEU);
2266         value = 2;
2267         break;
2268       }
2269
2270   return value;
2271 }
2272 #endif
2273 \f
2274 /* Report inconsistency between the assembler template and the operands.
2275    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
2276
2277 void
2278 output_operand_lossage (str)
2279      char *str;
2280 {
2281   if (this_is_asm_operands)
2282     error_for_asm (this_is_asm_operands, "invalid `asm': %s", str);
2283   else
2284     abort ();
2285 }
2286 \f
2287 /* Output of assembler code from a template, and its subroutines.  */
2288
2289 /* Output text from TEMPLATE to the assembler output file,
2290    obeying %-directions to substitute operands taken from
2291    the vector OPERANDS.
2292
2293    %N (for N a digit) means print operand N in usual manner.
2294    %lN means require operand N to be a CODE_LABEL or LABEL_REF
2295       and print the label name with no punctuation.
2296    %cN means require operand N to be a constant
2297       and print the constant expression with no punctuation.
2298    %aN means expect operand N to be a memory address
2299       (not a memory reference!) and print a reference
2300       to that address.
2301    %nN means expect operand N to be a constant
2302       and print a constant expression for minus the value
2303       of the operand, with no other punctuation.  */
2304
2305 void
2306 output_asm_insn (template, operands)
2307      char *template;
2308      rtx *operands;
2309 {
2310   register char *p;
2311   register int c, i;
2312
2313   /* An insn may return a null string template
2314      in a case where no assembler code is needed.  */
2315   if (*template == 0)
2316     return;
2317
2318   p = template;
2319   putc ('\t', asm_out_file);
2320
2321 #ifdef ASM_OUTPUT_OPCODE
2322   ASM_OUTPUT_OPCODE (asm_out_file, p);
2323 #endif
2324
2325   while (c = *p++)
2326     switch (c)
2327       {
2328 #ifdef ASM_OUTPUT_OPCODE
2329       case '\n':
2330         putc (c, asm_out_file);
2331         while ((c = *p) == '\t')
2332           {
2333             putc (c, asm_out_file);
2334             p++;
2335           }
2336         ASM_OUTPUT_OPCODE (asm_out_file, p);
2337         break;
2338 #endif
2339
2340 #ifdef ASSEMBLER_DIALECT
2341       case '{':
2342         /* If we want the first dialect, do nothing.  Otherwise, skip
2343            DIALECT_NUMBER of strings ending with '|'.  */
2344         for (i = 0; i < dialect_number; i++)
2345           {
2346             while (*p && *p++ != '|')
2347               ;
2348
2349             if (*p == '|')
2350               p++;
2351           }
2352         break;
2353
2354       case '|':
2355         /* Skip to close brace.  */
2356         while (*p && *p++ != '}')
2357           ;
2358         break;
2359
2360       case '}':
2361         break;
2362 #endif
2363
2364       case '%':
2365         /* %% outputs a single %.  */
2366         if (*p == '%')
2367           {
2368             p++;
2369             putc (c, asm_out_file);
2370           }
2371         /* %= outputs a number which is unique to each insn in the entire
2372            compilation.  This is useful for making local labels that are
2373            referred to more than once in a given insn.  */
2374         else if (*p == '=')
2375           {
2376             p++;
2377             fprintf (asm_out_file, "%d", insn_counter);
2378           }
2379         /* % followed by a letter and some digits
2380            outputs an operand in a special way depending on the letter.
2381            Letters `acln' are implemented directly.
2382            Other letters are passed to `output_operand' so that
2383            the PRINT_OPERAND macro can define them.  */
2384         else if ((*p >= 'a' && *p <= 'z')
2385                  || (*p >= 'A' && *p <= 'Z'))
2386           {
2387             int letter = *p++;
2388             c = atoi (p);
2389
2390             if (! (*p >= '0' && *p <= '9'))
2391               output_operand_lossage ("operand number missing after %-letter");
2392             else if (this_is_asm_operands && c >= (unsigned) insn_noperands)
2393               output_operand_lossage ("operand number out of range");
2394             else if (letter == 'l')
2395               output_asm_label (operands[c]);
2396             else if (letter == 'a')
2397               output_address (operands[c]);
2398             else if (letter == 'c')
2399               {
2400                 if (CONSTANT_ADDRESS_P (operands[c]))
2401                   output_addr_const (asm_out_file, operands[c]);
2402                 else
2403                   output_operand (operands[c], 'c');
2404               }
2405             else if (letter == 'n')
2406               {
2407                 if (GET_CODE (operands[c]) == CONST_INT)
2408                   fprintf (asm_out_file,
2409 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2410                            "%d",
2411 #else
2412                            "%ld",
2413 #endif
2414                            - INTVAL (operands[c]));
2415                 else
2416                   {
2417                     putc ('-', asm_out_file);
2418                     output_addr_const (asm_out_file, operands[c]);
2419                   }
2420               }
2421             else
2422               output_operand (operands[c], letter);
2423             
2424             while ((c = *p) >= '0' && c <= '9') p++;
2425           }
2426         /* % followed by a digit outputs an operand the default way.  */
2427         else if (*p >= '0' && *p <= '9')
2428           {
2429             c = atoi (p);
2430             if (this_is_asm_operands && c >= (unsigned) insn_noperands)
2431               output_operand_lossage ("operand number out of range");
2432             else
2433               output_operand (operands[c], 0);
2434             while ((c = *p) >= '0' && c <= '9') p++;
2435           }
2436         /* % followed by punctuation: output something for that
2437            punctuation character alone, with no operand.
2438            The PRINT_OPERAND macro decides what is actually done.  */
2439 #ifdef PRINT_OPERAND_PUNCT_VALID_P
2440         else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
2441           output_operand (NULL_RTX, *p++);
2442 #endif
2443         else
2444           output_operand_lossage ("invalid %%-code");
2445         break;
2446
2447       default:
2448         putc (c, asm_out_file);
2449       }
2450
2451   if (flag_print_asm_name)
2452     {
2453       /* Annotate the assembly with a comment describing the pattern and
2454          alternative used.  */
2455       if (debug_insn)
2456         {
2457           register int num = INSN_CODE (debug_insn);
2458           fprintf (asm_out_file, " %s %d %s", 
2459                    ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
2460           if (insn_n_alternatives[num] > 1)
2461             fprintf (asm_out_file, "/%d", which_alternative + 1);
2462
2463           /* Clear this so only the first assembler insn
2464              of any rtl insn will get the special comment for -dp.  */
2465           debug_insn = 0;
2466         }
2467     }
2468
2469   putc ('\n', asm_out_file);
2470 }
2471 \f
2472 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
2473
2474 void
2475 output_asm_label (x)
2476      rtx x;
2477 {
2478   char buf[256];
2479
2480   if (GET_CODE (x) == LABEL_REF)
2481     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2482   else if (GET_CODE (x) == CODE_LABEL)
2483     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2484   else
2485     output_operand_lossage ("`%l' operand isn't a label");
2486
2487   assemble_name (asm_out_file, buf);
2488 }
2489
2490 /* Print operand X using machine-dependent assembler syntax.
2491    The macro PRINT_OPERAND is defined just to control this function.
2492    CODE is a non-digit that preceded the operand-number in the % spec,
2493    such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char
2494    between the % and the digits.
2495    When CODE is a non-letter, X is 0.
2496
2497    The meanings of the letters are machine-dependent and controlled
2498    by PRINT_OPERAND.  */
2499
2500 static void
2501 output_operand (x, code)
2502      rtx x;
2503      int code;
2504 {
2505   if (x && GET_CODE (x) == SUBREG)
2506     x = alter_subreg (x);
2507
2508   /* If X is a pseudo-register, abort now rather than writing trash to the
2509      assembler file.  */
2510
2511   if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
2512     abort ();
2513
2514   PRINT_OPERAND (asm_out_file, x, code);
2515 }
2516
2517 /* Print a memory reference operand for address X
2518    using machine-dependent assembler syntax.
2519    The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */
2520
2521 void
2522 output_address (x)
2523      rtx x;
2524 {
2525   walk_alter_subreg (x);
2526   PRINT_OPERAND_ADDRESS (asm_out_file, x);
2527 }
2528 \f
2529 /* Print an integer constant expression in assembler syntax.
2530    Addition and subtraction are the only arithmetic
2531    that may appear in these expressions.  */
2532
2533 void
2534 output_addr_const (file, x)
2535      FILE *file;
2536      rtx x;
2537 {
2538   char buf[256];
2539
2540  restart:
2541   switch (GET_CODE (x))
2542     {
2543     case PC:
2544       if (flag_pic)
2545         putc ('.', file);
2546       else
2547         abort ();
2548       break;
2549
2550     case SYMBOL_REF:
2551       assemble_name (file, XSTR (x, 0));
2552       break;
2553
2554     case LABEL_REF:
2555       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2556       assemble_name (file, buf);
2557       break;
2558
2559     case CODE_LABEL:
2560       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2561       assemble_name (file, buf);
2562       break;
2563
2564     case CONST_INT:
2565       fprintf (file,
2566 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2567                "%d",
2568 #else
2569                "%ld",
2570 #endif
2571                INTVAL (x));
2572       break;
2573
2574     case CONST:
2575       /* This used to output parentheses around the expression,
2576          but that does not work on the 386 (either ATT or BSD assembler).  */
2577       output_addr_const (file, XEXP (x, 0));
2578       break;
2579
2580     case CONST_DOUBLE:
2581       if (GET_MODE (x) == VOIDmode)
2582         {
2583           /* We can use %d if the number is one word and positive.  */
2584           if (CONST_DOUBLE_HIGH (x))
2585             fprintf (file,
2586 #if HOST_BITS_PER_WIDE_INT == 64
2587 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
2588                      "0x%lx%016lx",
2589 #else
2590                      "0x%x%016x",
2591 #endif
2592 #else
2593 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
2594                      "0x%lx%08lx",
2595 #else
2596                      "0x%x%08x",
2597 #endif
2598 #endif
2599                      CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2600           else if  (CONST_DOUBLE_LOW (x) < 0)
2601             fprintf (file,
2602 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2603                      "0x%x",
2604 #else
2605                      "0x%lx",
2606 #endif
2607                      CONST_DOUBLE_LOW (x));
2608           else
2609             fprintf (file,
2610 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2611                      "%d",
2612 #else
2613                      "%ld",
2614 #endif
2615                      CONST_DOUBLE_LOW (x));
2616         }
2617       else
2618         /* We can't handle floating point constants;
2619            PRINT_OPERAND must handle them.  */
2620         output_operand_lossage ("floating constant misused");
2621       break;
2622
2623     case PLUS:
2624       /* Some assemblers need integer constants to appear last (eg masm).  */
2625       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2626         {
2627           output_addr_const (file, XEXP (x, 1));
2628           if (INTVAL (XEXP (x, 0)) >= 0)
2629             fprintf (file, "+");
2630           output_addr_const (file, XEXP (x, 0));
2631         }
2632       else
2633         {
2634           output_addr_const (file, XEXP (x, 0));
2635           if (INTVAL (XEXP (x, 1)) >= 0)
2636             fprintf (file, "+");
2637           output_addr_const (file, XEXP (x, 1));
2638         }
2639       break;
2640
2641     case MINUS:
2642       /* Avoid outputting things like x-x or x+5-x,
2643          since some assemblers can't handle that.  */
2644       x = simplify_subtraction (x);
2645       if (GET_CODE (x) != MINUS)
2646         goto restart;
2647
2648       output_addr_const (file, XEXP (x, 0));
2649       fprintf (file, "-");
2650       if (GET_CODE (XEXP (x, 1)) == CONST_INT
2651           && INTVAL (XEXP (x, 1)) < 0)
2652         {
2653           fprintf (file, ASM_OPEN_PAREN);
2654           output_addr_const (file, XEXP (x, 1));
2655           fprintf (file, ASM_CLOSE_PAREN);
2656         }
2657       else
2658         output_addr_const (file, XEXP (x, 1));
2659       break;
2660
2661     case ZERO_EXTEND:
2662     case SIGN_EXTEND:
2663       output_addr_const (file, XEXP (x, 0));
2664       break;
2665
2666     default:
2667       output_operand_lossage ("invalid expression as operand");
2668     }
2669 }
2670 \f
2671 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
2672    %R prints the value of REGISTER_PREFIX.
2673    %L prints the value of LOCAL_LABEL_PREFIX.
2674    %U prints the value of USER_LABEL_PREFIX.
2675    %I prints the value of IMMEDIATE_PREFIX.
2676    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
2677    Also supported are %d, %x, %s, %e, %f, %g and %%.
2678
2679    We handle alternate assembler dialects here, just like output_asm_insn.  */
2680
2681 void
2682 asm_fprintf VPROTO((FILE *file, char *p, ...))
2683 {
2684 #ifndef __STDC__
2685   FILE *file;
2686   char *p;
2687 #endif
2688   va_list argptr;
2689   char buf[10];
2690   char *q, c;
2691   int i;
2692
2693   VA_START (argptr, p);
2694
2695 #ifndef __STDC__
2696   file = va_arg (argptr, FILE*);
2697   p = va_arg (argptr, char*);
2698 #endif
2699
2700   buf[0] = '%';
2701
2702   while (c = *p++)
2703     switch (c)
2704       {
2705 #ifdef ASSEMBLER_DIALECT
2706       case '{':
2707         /* If we want the first dialect, do nothing.  Otherwise, skip
2708            DIALECT_NUMBER of strings ending with '|'.  */
2709         for (i = 0; i < dialect_number; i++)
2710           {
2711             while (*p && *p++ != '|')
2712               ;
2713
2714             if (*p == '|')
2715               p++;
2716           }
2717         break;
2718
2719       case '|':
2720         /* Skip to close brace.  */
2721         while (*p && *p++ != '}')
2722           ;
2723         break;
2724
2725       case '}':
2726         break;
2727 #endif
2728
2729       case '%':
2730         c = *p++;
2731         q = &buf[1];
2732         while ((c >= '0' && c <= '9') || c == '.')
2733           {
2734             *q++ = c;
2735             c = *p++;
2736           }
2737         switch (c)
2738           {
2739           case '%':
2740             fprintf (file, "%%");
2741             break;
2742
2743           case 'd':  case 'i':  case 'u':
2744           case 'x':  case 'p':  case 'X':
2745           case 'o':
2746             *q++ = c;
2747             *q = 0;
2748             fprintf (file, buf, va_arg (argptr, int));
2749             break;
2750
2751           case 'w':
2752             /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases,
2753                but we do not check for those cases.  It means that the value
2754                is a HOST_WIDE_INT, which may be either `int' or `long'.  */
2755
2756 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
2757             *q++ = 'l';
2758 #endif
2759
2760             *q++ = *p++;
2761             *q = 0;
2762             fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
2763             break;
2764
2765           case 'l':
2766             *q++ = c;
2767             *q++ = *p++;
2768             *q = 0;
2769             fprintf (file, buf, va_arg (argptr, long));
2770             break;
2771
2772           case 'e':
2773           case 'f':
2774           case 'g':
2775             *q++ = c;
2776             *q = 0;
2777             fprintf (file, buf, va_arg (argptr, double));
2778             break;
2779
2780           case 's':
2781             *q++ = c;
2782             *q = 0;
2783             fprintf (file, buf, va_arg (argptr, char *));
2784             break;
2785
2786           case 'O':
2787 #ifdef ASM_OUTPUT_OPCODE
2788             ASM_OUTPUT_OPCODE (asm_out_file, p);
2789 #endif
2790             break;
2791
2792           case 'R':
2793 #ifdef REGISTER_PREFIX
2794             fprintf (file, "%s", REGISTER_PREFIX);
2795 #endif
2796             break;
2797
2798           case 'I':
2799 #ifdef IMMEDIATE_PREFIX
2800             fprintf (file, "%s", IMMEDIATE_PREFIX);
2801 #endif
2802             break;
2803
2804           case 'L':
2805 #ifdef LOCAL_LABEL_PREFIX
2806             fprintf (file, "%s", LOCAL_LABEL_PREFIX);
2807 #endif
2808             break;
2809
2810           case 'U':
2811 #ifdef USER_LABEL_PREFIX
2812             fprintf (file, "%s", USER_LABEL_PREFIX);
2813 #endif
2814             break;
2815
2816           default:
2817             abort ();
2818           }
2819         break;
2820
2821       default:
2822         fputc (c, file);
2823       }
2824 }
2825 \f
2826 /* Split up a CONST_DOUBLE or integer constant rtx
2827    into two rtx's for single words,
2828    storing in *FIRST the word that comes first in memory in the target
2829    and in *SECOND the other.  */
2830
2831 void
2832 split_double (value, first, second)
2833      rtx value;
2834      rtx *first, *second;
2835 {
2836   if (GET_CODE (value) == CONST_INT)
2837     {
2838       /* The rule for using CONST_INT for a wider mode
2839          is that we regard the value as signed.
2840          So sign-extend it.  */
2841       rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx);
2842 #if WORDS_BIG_ENDIAN
2843       *first = high;
2844       *second = value;
2845 #else
2846       *first = value;
2847       *second = high;
2848 #endif
2849     }
2850   else if (GET_CODE (value) != CONST_DOUBLE)
2851     {
2852 #if WORDS_BIG_ENDIAN
2853       *first = const0_rtx;
2854       *second = value;
2855 #else
2856       *first = value;
2857       *second = const0_rtx;
2858 #endif
2859     }
2860   else if (GET_MODE (value) == VOIDmode
2861            /* This is the old way we did CONST_DOUBLE integers.  */
2862            || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT)
2863     {
2864       /* In an integer, the words are defined as most and least significant.
2865          So order them by the target's convention.  */
2866 #if WORDS_BIG_ENDIAN
2867       *first = GEN_INT (CONST_DOUBLE_HIGH (value));
2868       *second = GEN_INT (CONST_DOUBLE_LOW (value));
2869 #else
2870       *first = GEN_INT (CONST_DOUBLE_LOW (value));
2871       *second = GEN_INT (CONST_DOUBLE_HIGH (value));
2872 #endif
2873     }
2874   else
2875     {
2876 #ifdef REAL_ARITHMETIC
2877       REAL_VALUE_TYPE r; long l[2];
2878       REAL_VALUE_FROM_CONST_DOUBLE (r, value);
2879
2880       /* Note, this converts the REAL_VALUE_TYPE to the target's
2881          format, splits up the floating point double and outputs
2882          exactly 32 bits of it into each of l[0] and l[1] --
2883          not necessarily BITS_PER_WORD bits. */
2884       REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2885
2886       *first = GEN_INT ((HOST_WIDE_INT) l[0]);
2887       *second = GEN_INT ((HOST_WIDE_INT) l[1]);
2888 #else
2889       if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2890            || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
2891           && ! flag_pretend_float)
2892       abort ();
2893
2894 #if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN
2895       /* Host and target agree => no need to swap.  */
2896       *first = GEN_INT (CONST_DOUBLE_LOW (value));
2897       *second = GEN_INT (CONST_DOUBLE_HIGH (value));
2898 #else
2899       *second = GEN_INT (CONST_DOUBLE_LOW (value));
2900       *first = GEN_INT (CONST_DOUBLE_HIGH (value));
2901 #endif
2902 #endif /* no REAL_ARITHMETIC */
2903     }
2904 }
2905 \f
2906 /* Return nonzero if this function has no function calls.  */
2907
2908 int
2909 leaf_function_p ()
2910 {
2911   rtx insn;
2912
2913   if (profile_flag || profile_block_flag)
2914     return 0;
2915
2916   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2917     {
2918       if (GET_CODE (insn) == CALL_INSN)
2919         return 0;
2920       if (GET_CODE (insn) == INSN
2921           && GET_CODE (PATTERN (insn)) == SEQUENCE
2922           && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)
2923         return 0;
2924     }
2925   for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2926     {
2927       if (GET_CODE (XEXP (insn, 0)) == CALL_INSN)
2928         return 0;
2929       if (GET_CODE (XEXP (insn, 0)) == INSN
2930           && GET_CODE (PATTERN (XEXP (insn, 0))) == SEQUENCE
2931           && GET_CODE (XVECEXP (PATTERN (XEXP (insn, 0)), 0, 0)) == CALL_INSN)
2932         return 0;
2933     }
2934
2935   return 1;
2936 }
2937
2938 /* On some machines, a function with no call insns
2939    can run faster if it doesn't create its own register window.
2940    When output, the leaf function should use only the "output"
2941    registers.  Ordinarily, the function would be compiled to use
2942    the "input" registers to find its arguments; it is a candidate
2943    for leaf treatment if it uses only the "input" registers.
2944    Leaf function treatment means renumbering so the function
2945    uses the "output" registers instead.  */
2946
2947 #ifdef LEAF_REGISTERS
2948
2949 static char permitted_reg_in_leaf_functions[] = LEAF_REGISTERS;
2950
2951 /* Return 1 if this function uses only the registers that can be
2952    safely renumbered.  */
2953
2954 int
2955 only_leaf_regs_used ()
2956 {
2957   int i;
2958
2959   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2960     {
2961       if ((regs_ever_live[i] || global_regs[i])
2962           && ! permitted_reg_in_leaf_functions[i])
2963         return 0;
2964     }
2965   return 1;
2966 }
2967
2968 /* Scan all instructions and renumber all registers into those
2969    available in leaf functions.  */
2970
2971 static void
2972 leaf_renumber_regs (first)
2973      rtx first;
2974 {
2975   rtx insn;
2976
2977   /* Renumber only the actual patterns.
2978      The reg-notes can contain frame pointer refs,
2979      and renumbering them could crash, and should not be needed.  */
2980   for (insn = first; insn; insn = NEXT_INSN (insn))
2981     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
2982       leaf_renumber_regs_insn (PATTERN (insn));
2983   for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2984     if (GET_RTX_CLASS (GET_CODE (XEXP (insn, 0))) == 'i')
2985       leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0)));
2986 }
2987
2988 /* Scan IN_RTX and its subexpressions, and renumber all regs into those
2989    available in leaf functions.  */
2990
2991 void
2992 leaf_renumber_regs_insn (in_rtx)
2993      register rtx in_rtx;
2994 {
2995   register int i, j;
2996   register char *format_ptr;
2997
2998   if (in_rtx == 0)
2999     return;
3000
3001   /* Renumber all input-registers into output-registers.
3002      renumbered_regs would be 1 for an output-register;
3003      they  */
3004
3005   if (GET_CODE (in_rtx) == REG)
3006     {
3007       int newreg;
3008
3009       /* Don't renumber the same reg twice.  */
3010       if (in_rtx->used)
3011         return;
3012
3013       newreg = REGNO (in_rtx);
3014       /* Don't try to renumber pseudo regs.  It is possible for a pseudo reg
3015          to reach here as part of a REG_NOTE.  */
3016       if (newreg >= FIRST_PSEUDO_REGISTER)
3017         {
3018           in_rtx->used = 1;
3019           return;
3020         }
3021       newreg = LEAF_REG_REMAP (newreg);
3022       if (newreg < 0)
3023         abort ();
3024       regs_ever_live[REGNO (in_rtx)] = 0;
3025       regs_ever_live[newreg] = 1;
3026       REGNO (in_rtx) = newreg;
3027       in_rtx->used = 1;
3028     }
3029
3030   if (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i')
3031     {
3032       /* Inside a SEQUENCE, we find insns.
3033          Renumber just the patterns of these insns,
3034          just as we do for the top-level insns.  */
3035       leaf_renumber_regs_insn (PATTERN (in_rtx));
3036       return;
3037     }
3038
3039   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
3040
3041   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
3042     switch (*format_ptr++)
3043       {
3044       case 'e':
3045         leaf_renumber_regs_insn (XEXP (in_rtx, i));
3046         break;
3047
3048       case 'E':
3049         if (NULL != XVEC (in_rtx, i))
3050           {
3051             for (j = 0; j < XVECLEN (in_rtx, i); j++)
3052               leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
3053           }
3054         break;
3055
3056       case 'S':
3057       case 's':
3058       case '0':
3059       case 'i':
3060       case 'w':
3061       case 'n':
3062       case 'u':
3063         break;
3064
3065       default:
3066         abort ();
3067       }
3068 }
3069 #endif