OSDN Git Service

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