OSDN Git Service

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