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