OSDN Git Service

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