OSDN Git Service

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