OSDN Git Service

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