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