OSDN Git Service

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