OSDN Git Service

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