OSDN Git Service

Undo previous change.
[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 #ifdef REGISTER_CONSTRAINTS
1662         if (! constrain_operands (insn_code_number, 1))
1663           fatal_insn_not_found (insn);
1664 #endif
1665
1666         /* Some target machines need to prescan each insn before
1667            it is output.  */
1668
1669 #ifdef FINAL_PRESCAN_INSN
1670         FINAL_PRESCAN_INSN (insn, recog_operand,
1671                             insn_n_operands[insn_code_number]);
1672 #endif
1673
1674 #ifdef HAVE_cc0
1675         cc_prev_status = cc_status;
1676
1677         /* Update `cc_status' for this instruction.
1678            The instruction's output routine may change it further.
1679            If the output routine for a jump insn needs to depend
1680            on the cc status, it should look at cc_prev_status.  */
1681
1682         NOTICE_UPDATE_CC (body, insn);
1683 #endif
1684
1685         debug_insn = insn;
1686
1687         /* If the proper template needs to be chosen by some C code,
1688            run that code and get the real template.  */
1689
1690         template = insn_template[insn_code_number];
1691         if (template == 0)
1692           {
1693             template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
1694
1695             /* If the C code returns 0, it means that it is a jump insn
1696                which follows a deleted test insn, and that test insn
1697                needs to be reinserted.  */
1698             if (template == 0)
1699               {
1700                 if (prev_nonnote_insn (insn) != last_ignored_compare)
1701                   abort ();
1702                 new_block = 0;
1703                 return prev_nonnote_insn (insn);
1704               }
1705           }
1706
1707         /* If the template is the string "#", it means that this insn must
1708            be split.  */
1709         if (template[0] == '#' && template[1] == '\0')
1710           {
1711             rtx new = try_split (body, insn, 0);
1712
1713             /* If we didn't split the insn, go away.  */
1714             if (new == insn && PATTERN (new) == body)
1715               abort ();
1716               
1717             new_block = 0;
1718             return new;
1719           }
1720         
1721         if (prescan > 0)
1722           break;
1723
1724         /* Output assembler code from the template.  */
1725
1726         output_asm_insn (template, recog_operand);
1727
1728 #if 0
1729         /* It's not at all clear why we did this and doing so interferes
1730            with tests we'd like to do to use REG_WAS_0 notes, so let's try
1731            with this out.  */
1732
1733         /* Mark this insn as having been output.  */
1734         INSN_DELETED_P (insn) = 1;
1735 #endif
1736
1737         debug_insn = 0;
1738       }
1739     }
1740   return NEXT_INSN (insn);
1741 }
1742 \f
1743 /* Output debugging info to the assembler file FILE
1744    based on the NOTE-insn INSN, assumed to be a line number.  */
1745
1746 static void
1747 output_source_line (file, insn)
1748      FILE *file;
1749      rtx insn;
1750 {
1751   char ltext_label_name[100];
1752   register char *filename = NOTE_SOURCE_FILE (insn);
1753
1754   last_linenum = NOTE_LINE_NUMBER (insn);
1755
1756   if (write_symbols != NO_DEBUG)
1757     {
1758 #ifdef SDB_DEBUGGING_INFO
1759       if (write_symbols == SDB_DEBUG
1760 #if 0 /* People like having line numbers even in wrong file!  */
1761           /* COFF can't handle multiple source files--lose, lose.  */
1762           && !strcmp (filename, main_input_filename)
1763 #endif
1764           /* COFF relative line numbers must be positive.  */
1765           && last_linenum > sdb_begin_function_line)
1766         {
1767 #ifdef ASM_OUTPUT_SOURCE_LINE
1768           ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
1769 #else
1770           fprintf (file, "\t.ln\t%d\n",
1771                    ((sdb_begin_function_line > -1)
1772                     ? last_linenum - sdb_begin_function_line : 1));
1773 #endif
1774         }
1775 #endif
1776
1777 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
1778       if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
1779         dbxout_source_line (file, filename, NOTE_LINE_NUMBER (insn));
1780 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
1781
1782 #ifdef DWARF_DEBUGGING_INFO
1783       if (write_symbols == DWARF_DEBUG)
1784         dwarfout_line (filename, NOTE_LINE_NUMBER (insn));
1785 #endif
1786     }
1787 }
1788 \f
1789 /* If X is a SUBREG, replace it with a REG or a MEM,
1790    based on the thing it is a subreg of.  */
1791
1792 rtx
1793 alter_subreg (x)
1794      register rtx x;
1795 {
1796   register rtx y = SUBREG_REG (x);
1797   if (GET_CODE (y) == SUBREG)
1798     y = alter_subreg (y);
1799
1800   if (GET_CODE (y) == REG)
1801     {
1802       /* If the containing reg really gets a hard reg, so do we.  */
1803       PUT_CODE (x, REG);
1804       REGNO (x) = REGNO (y) + SUBREG_WORD (x);
1805     }
1806   else if (GET_CODE (y) == MEM)
1807     {
1808       register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
1809 #if BYTES_BIG_ENDIAN
1810       offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
1811                  - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
1812 #endif
1813       PUT_CODE (x, MEM);
1814       MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
1815       XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
1816     }
1817
1818   return x;
1819 }
1820
1821 /* Do alter_subreg on all the SUBREGs contained in X.  */
1822
1823 static rtx
1824 walk_alter_subreg (x)
1825      rtx x;
1826 {
1827   switch (GET_CODE (x))
1828     {
1829     case PLUS:
1830     case MULT:
1831       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
1832       XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1));
1833       break;
1834
1835     case MEM:
1836       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
1837       break;
1838
1839     case SUBREG:
1840       return alter_subreg (x);
1841     }
1842
1843   return x;
1844 }
1845 \f
1846 #ifdef HAVE_cc0
1847
1848 /* Given BODY, the body of a jump instruction, alter the jump condition
1849    as required by the bits that are set in cc_status.flags.
1850    Not all of the bits there can be handled at this level in all cases.
1851
1852    The value is normally 0.
1853    1 means that the condition has become always true.
1854    -1 means that the condition has become always false.
1855    2 means that COND has been altered.  */
1856
1857 static int
1858 alter_cond (cond)
1859      register rtx cond;
1860 {
1861   int value = 0;
1862
1863   if (cc_status.flags & CC_REVERSED)
1864     {
1865       value = 2;
1866       PUT_CODE (cond, swap_condition (GET_CODE (cond)));
1867     }
1868
1869   if (cc_status.flags & CC_INVERTED)
1870     {
1871       value = 2;
1872       PUT_CODE (cond, reverse_condition (GET_CODE (cond)));
1873     }
1874
1875   if (cc_status.flags & CC_NOT_POSITIVE)
1876     switch (GET_CODE (cond))
1877       {
1878       case LE:
1879       case LEU:
1880       case GEU:
1881         /* Jump becomes unconditional.  */
1882         return 1;
1883
1884       case GT:
1885       case GTU:
1886       case LTU:
1887         /* Jump becomes no-op.  */
1888         return -1;
1889
1890       case GE:
1891         PUT_CODE (cond, EQ);
1892         value = 2;
1893         break;
1894
1895       case LT:
1896         PUT_CODE (cond, NE);
1897         value = 2;
1898         break;
1899       }
1900
1901   if (cc_status.flags & CC_NOT_NEGATIVE)
1902     switch (GET_CODE (cond))
1903       {
1904       case GE:
1905       case GEU:
1906         /* Jump becomes unconditional.  */
1907         return 1;
1908
1909       case LT:
1910       case LTU:
1911         /* Jump becomes no-op.  */
1912         return -1;
1913
1914       case LE:
1915       case LEU:
1916         PUT_CODE (cond, EQ);
1917         value = 2;
1918         break;
1919
1920       case GT:
1921       case GTU:
1922         PUT_CODE (cond, NE);
1923         value = 2;
1924         break;
1925       }
1926
1927   if (cc_status.flags & CC_NO_OVERFLOW)
1928     switch (GET_CODE (cond))
1929       {
1930       case GEU:
1931         /* Jump becomes unconditional.  */
1932         return 1;
1933
1934       case LEU:
1935         PUT_CODE (cond, EQ);
1936         value = 2;
1937         break;
1938
1939       case GTU:
1940         PUT_CODE (cond, NE);
1941         value = 2;
1942         break;
1943
1944       case LTU:
1945         /* Jump becomes no-op.  */
1946         return -1;
1947       }
1948
1949   if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N))
1950     switch (GET_CODE (cond))
1951       {
1952       case LE:
1953       case LEU:
1954       case GE:
1955       case GEU:
1956       case LT:
1957       case LTU:
1958       case GT:
1959       case GTU:
1960         abort ();
1961
1962       case NE:
1963         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
1964         value = 2;
1965         break;
1966
1967       case EQ:
1968         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE);
1969         value = 2;
1970         break;
1971       }
1972
1973   if (cc_status.flags & CC_NOT_SIGNED)
1974     /* The flags are valid if signed condition operators are converted
1975        to unsigned.  */
1976     switch (GET_CODE (cond))
1977       {
1978       case LE:
1979         PUT_CODE (cond, LEU);
1980         value = 2;
1981         break;
1982
1983       case LT:
1984         PUT_CODE (cond, LTU);
1985         value = 2;
1986         break;
1987
1988       case GT:
1989         PUT_CODE (cond, GTU);
1990         value = 2;
1991         break;
1992
1993       case GE:
1994         PUT_CODE (cond, GEU);
1995         value = 2;
1996         break;
1997       }
1998
1999   return value;
2000 }
2001 #endif
2002 \f
2003 /* Report inconsistency between the assembler template and the operands.
2004    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
2005
2006 void
2007 output_operand_lossage (str)
2008      char *str;
2009 {
2010   if (this_is_asm_operands)
2011     error_for_asm (this_is_asm_operands, "invalid `asm': %s", str);
2012   else
2013     abort ();
2014 }
2015 \f
2016 /* Output of assembler code from a template, and its subroutines.  */
2017
2018 /* Output text from TEMPLATE to the assembler output file,
2019    obeying %-directions to substitute operands taken from
2020    the vector OPERANDS.
2021
2022    %N (for N a digit) means print operand N in usual manner.
2023    %lN means require operand N to be a CODE_LABEL or LABEL_REF
2024       and print the label name with no punctuation.
2025    %cN means require operand N to be a constant
2026       and print the constant expression with no punctuation.
2027    %aN means expect operand N to be a memory address
2028       (not a memory reference!) and print a reference
2029       to that address.
2030    %nN means expect operand N to be a constant
2031       and print a constant expression for minus the value
2032       of the operand, with no other punctuation.  */
2033
2034 void
2035 output_asm_insn (template, operands)
2036      char *template;
2037      rtx *operands;
2038 {
2039   register char *p;
2040   register int c;
2041
2042   /* An insn may return a null string template
2043      in a case where no assembler code is needed.  */
2044   if (*template == 0)
2045     return;
2046
2047   p = template;
2048   putc ('\t', asm_out_file);
2049
2050 #ifdef ASM_OUTPUT_OPCODE
2051   ASM_OUTPUT_OPCODE (asm_out_file, p);
2052 #endif
2053
2054   while (c = *p++)
2055     {
2056 #ifdef ASM_OUTPUT_OPCODE
2057       if (c == '\n')
2058         {
2059           putc (c, asm_out_file);
2060           while ((c = *p) == '\t')
2061             {
2062               putc (c, asm_out_file);
2063               p++;
2064             }
2065           ASM_OUTPUT_OPCODE (asm_out_file, p);
2066         }
2067       else
2068 #endif
2069       if (c != '%')
2070         putc (c, asm_out_file);
2071       else
2072         {
2073           /* %% outputs a single %.  */
2074           if (*p == '%')
2075             {
2076               p++;
2077               putc (c, asm_out_file);
2078             }
2079           /* %= outputs a number which is unique to each insn in the entire
2080              compilation.  This is useful for making local labels that are
2081              referred to more than once in a given insn.  */
2082           else if (*p == '=')
2083             {
2084               p++;
2085               fprintf (asm_out_file, "%d", insn_counter);
2086             }
2087           /* % followed by a letter and some digits
2088              outputs an operand in a special way depending on the letter.
2089              Letters `acln' are implemented directly.
2090              Other letters are passed to `output_operand' so that
2091              the PRINT_OPERAND macro can define them.  */
2092           else if ((*p >= 'a' && *p <= 'z')
2093                    || (*p >= 'A' && *p <= 'Z'))
2094             {
2095               int letter = *p++;
2096               c = atoi (p);
2097
2098               if (! (*p >= '0' && *p <= '9'))
2099                 output_operand_lossage ("operand number missing after %-letter");
2100               else if (this_is_asm_operands && c >= (unsigned) insn_noperands)
2101                 output_operand_lossage ("operand number out of range");
2102               else if (letter == 'l')
2103                 output_asm_label (operands[c]);
2104               else if (letter == 'a')
2105                 output_address (operands[c]);
2106               else if (letter == 'c')
2107                 {
2108                   if (CONSTANT_ADDRESS_P (operands[c]))
2109                     output_addr_const (asm_out_file, operands[c]);
2110                   else
2111                     output_operand (operands[c], 'c');
2112                 }
2113               else if (letter == 'n')
2114                 {
2115                   if (GET_CODE (operands[c]) == CONST_INT)
2116                     fprintf (asm_out_file,
2117 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2118                              "%d",
2119 #else
2120                              "%ld",
2121 #endif
2122                              - INTVAL (operands[c]));
2123                   else
2124                     {
2125                       putc ('-', asm_out_file);
2126                       output_addr_const (asm_out_file, operands[c]);
2127                     }
2128                 }
2129               else
2130                 output_operand (operands[c], letter);
2131
2132               while ((c = *p) >= '0' && c <= '9') p++;
2133             }
2134           /* % followed by a digit outputs an operand the default way.  */
2135           else if (*p >= '0' && *p <= '9')
2136             {
2137               c = atoi (p);
2138               if (this_is_asm_operands && c >= (unsigned) insn_noperands)
2139                 output_operand_lossage ("operand number out of range");
2140               else
2141                 output_operand (operands[c], 0);
2142               while ((c = *p) >= '0' && c <= '9') p++;
2143             }
2144           /* % followed by punctuation: output something for that
2145              punctuation character alone, with no operand.
2146              The PRINT_OPERAND macro decides what is actually done.  */
2147 #ifdef PRINT_OPERAND_PUNCT_VALID_P
2148           else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
2149             output_operand (NULL_RTX, *p++);
2150 #endif
2151           else
2152             output_operand_lossage ("invalid %%-code");
2153         }
2154     }
2155
2156   if (flag_print_asm_name)
2157     {
2158       /* Annotate the assembly with a comment describing the pattern and
2159          alternative used.  */
2160       if (debug_insn)
2161         {
2162           register int num = INSN_CODE (debug_insn);
2163           fprintf (asm_out_file, " %s %d %s", 
2164                    ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
2165           if (insn_n_alternatives[num] > 1)
2166             fprintf (asm_out_file, "/%d", which_alternative + 1);
2167
2168           /* Clear this so only the first assembler insn
2169              of any rtl insn will get the special comment for -dp.  */
2170           debug_insn = 0;
2171         }
2172     }
2173
2174   putc ('\n', asm_out_file);
2175 }
2176 \f
2177 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
2178
2179 void
2180 output_asm_label (x)
2181      rtx x;
2182 {
2183   char buf[256];
2184
2185   if (GET_CODE (x) == LABEL_REF)
2186     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2187   else if (GET_CODE (x) == CODE_LABEL)
2188     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2189   else
2190     output_operand_lossage ("`%l' operand isn't a label");
2191
2192   assemble_name (asm_out_file, buf);
2193 }
2194
2195 /* Print operand X using machine-dependent assembler syntax.
2196    The macro PRINT_OPERAND is defined just to control this function.
2197    CODE is a non-digit that preceded the operand-number in the % spec,
2198    such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char
2199    between the % and the digits.
2200    When CODE is a non-letter, X is 0.
2201
2202    The meanings of the letters are machine-dependent and controlled
2203    by PRINT_OPERAND.  */
2204
2205 static void
2206 output_operand (x, code)
2207      rtx x;
2208      int code;
2209 {
2210   if (x && GET_CODE (x) == SUBREG)
2211     x = alter_subreg (x);
2212
2213   /* If X is a pseudo-register, abort now rather than writing trash to the
2214      assembler file.  */
2215
2216   if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
2217     abort ();
2218
2219   PRINT_OPERAND (asm_out_file, x, code);
2220 }
2221
2222 /* Print a memory reference operand for address X
2223    using machine-dependent assembler syntax.
2224    The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */
2225
2226 void
2227 output_address (x)
2228      rtx x;
2229 {
2230   walk_alter_subreg (x);
2231   PRINT_OPERAND_ADDRESS (asm_out_file, x);
2232 }
2233 \f
2234 /* Print an integer constant expression in assembler syntax.
2235    Addition and subtraction are the only arithmetic
2236    that may appear in these expressions.  */
2237
2238 void
2239 output_addr_const (file, x)
2240      FILE *file;
2241      rtx x;
2242 {
2243   char buf[256];
2244
2245  restart:
2246   switch (GET_CODE (x))
2247     {
2248     case PC:
2249       if (flag_pic)
2250         putc ('.', file);
2251       else
2252         abort ();
2253       break;
2254
2255     case SYMBOL_REF:
2256       assemble_name (file, XSTR (x, 0));
2257       break;
2258
2259     case LABEL_REF:
2260       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2261       assemble_name (file, buf);
2262       break;
2263
2264     case CODE_LABEL:
2265       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2266       assemble_name (file, buf);
2267       break;
2268
2269     case CONST_INT:
2270       fprintf (file,
2271 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2272                "%d",
2273 #else
2274                "%ld",
2275 #endif
2276                INTVAL (x));
2277       break;
2278
2279     case CONST:
2280       /* This used to output parentheses around the expression,
2281          but that does not work on the 386 (either ATT or BSD assembler).  */
2282       output_addr_const (file, XEXP (x, 0));
2283       break;
2284
2285     case CONST_DOUBLE:
2286       if (GET_MODE (x) == VOIDmode)
2287         {
2288           /* We can use %d if the number is one word and positive.  */
2289           if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2290             fprintf (file,
2291 #if HOST_BITS_PER_WIDE_INT == 64
2292 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
2293                  " 0x%lx%016lx",
2294 #else
2295                  " 0x%x%016x",
2296 #endif
2297 #else
2298 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
2299                  " 0x%lx%08lx",
2300 #else
2301                  " 0x%x%08x",
2302 #endif
2303 #endif
2304                      CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2305           else
2306             fprintf (file,
2307 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
2308                      "%d",
2309 #else
2310                      "%ld",
2311 #endif
2312                      CONST_DOUBLE_LOW (x));
2313         }
2314       else
2315         /* We can't handle floating point constants;
2316            PRINT_OPERAND must handle them.  */
2317         output_operand_lossage ("floating constant misused");
2318       break;
2319
2320     case PLUS:
2321       /* Some assemblers need integer constants to appear last (eg masm).  */
2322       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2323         {
2324           output_addr_const (file, XEXP (x, 1));
2325           if (INTVAL (XEXP (x, 0)) >= 0)
2326             fprintf (file, "+");
2327           output_addr_const (file, XEXP (x, 0));
2328         }
2329       else
2330         {
2331           output_addr_const (file, XEXP (x, 0));
2332           if (INTVAL (XEXP (x, 1)) >= 0)
2333             fprintf (file, "+");
2334           output_addr_const (file, XEXP (x, 1));
2335         }
2336       break;
2337
2338     case MINUS:
2339       /* Avoid outputting things like x-x or x+5-x,
2340          since some assemblers can't handle that.  */
2341       x = simplify_subtraction (x);
2342       if (GET_CODE (x) != MINUS)
2343         goto restart;
2344
2345       output_addr_const (file, XEXP (x, 0));
2346       fprintf (file, "-");
2347       if (GET_CODE (XEXP (x, 1)) == CONST_INT
2348           && INTVAL (XEXP (x, 1)) < 0)
2349         {
2350           fprintf (file, ASM_OPEN_PAREN);
2351           output_addr_const (file, XEXP (x, 1));
2352           fprintf (file, ASM_CLOSE_PAREN);
2353         }
2354       else
2355         output_addr_const (file, XEXP (x, 1));
2356       break;
2357
2358     case ZERO_EXTEND:
2359     case SIGN_EXTEND:
2360       output_addr_const (file, XEXP (x, 0));
2361       break;
2362
2363     default:
2364       output_operand_lossage ("invalid expression as operand");
2365     }
2366 }
2367 \f
2368 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
2369    %R prints the value of REGISTER_PREFIX.
2370    %L prints the value of LOCAL_LABEL_PREFIX.
2371    %U prints the value of USER_LABEL_PREFIX.
2372    %I prints the value of IMMEDIATE_PREFIX.
2373    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
2374    Also supported are %d, %x, %s, %e, %f, %g and %%.  */
2375
2376 void
2377 asm_fprintf (va_alist)
2378      va_dcl
2379 {
2380   va_list argptr;
2381   FILE *file;
2382   char buf[10];
2383   char *p, *q, c;
2384
2385   va_start (argptr);
2386
2387   file = va_arg (argptr, FILE *);
2388   p = va_arg (argptr, char *);
2389   buf[0] = '%';
2390
2391   while (c = *p++)
2392     switch (c)
2393       {
2394       case '%':
2395         c = *p++;
2396         q = &buf[1];
2397         while ((c >= '0' && c <= '9') || c == '.')
2398           {
2399             *q++ = c;
2400             c = *p++;
2401           }
2402         switch (c)
2403           {
2404           case '%':
2405             fprintf (file, "%%");
2406             break;
2407
2408           case 'd':  case 'i':  case 'u':
2409           case 'x':  case 'p':  case 'X':
2410           case 'o':
2411             *q++ = c;
2412             *q = 0;
2413             fprintf (file, buf, va_arg (argptr, int));
2414             break;
2415
2416           case 'e':
2417           case 'f':
2418           case 'g':
2419             *q++ = c;
2420             *q = 0;
2421             fprintf (file, buf, va_arg (argptr, double));
2422             break;
2423
2424           case 's':
2425             *q++ = c;
2426             *q = 0;
2427             fprintf (file, buf, va_arg (argptr, char *));
2428             break;
2429
2430           case 'O':
2431 #ifdef ASM_OUTPUT_OPCODE
2432             ASM_OUTPUT_OPCODE (asm_out_file, p);
2433 #endif
2434             break;
2435
2436           case 'R':
2437 #ifdef REGISTER_PREFIX
2438             fprintf (file, "%s", REGISTER_PREFIX);
2439 #endif
2440             break;
2441
2442           case 'I':
2443 #ifdef IMMEDIATE_PREFIX
2444             fprintf (file, "%s", IMMEDIATE_PREFIX);
2445 #endif
2446             break;
2447
2448           case 'L':
2449 #ifdef LOCAL_LABEL_PREFIX
2450             fprintf (file, "%s", LOCAL_LABEL_PREFIX);
2451 #endif
2452             break;
2453
2454           case 'U':
2455 #ifdef USER_LABEL_PREFIX
2456             fprintf (file, "%s", USER_LABEL_PREFIX);
2457 #endif
2458             break;
2459
2460           default:
2461             abort ();
2462           }
2463         break;
2464
2465       default:
2466         fputc (c, file);
2467       }
2468 }
2469 \f
2470 /* Split up a CONST_DOUBLE or integer constant rtx
2471    into two rtx's for single words,
2472    storing in *FIRST the word that comes first in memory in the target
2473    and in *SECOND the other.  */
2474
2475 void
2476 split_double (value, first, second)
2477      rtx value;
2478      rtx *first, *second;
2479 {
2480   if (GET_CODE (value) == CONST_INT)
2481     {
2482       /* The rule for using CONST_INT for a wider mode
2483          is that we regard the value as signed.
2484          So sign-extend it.  */
2485       rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx);
2486 #if WORDS_BIG_ENDIAN
2487       *first = high;
2488       *second = value;
2489 #else
2490       *first = value;
2491       *second = high;
2492 #endif
2493     }
2494   else if (GET_CODE (value) != CONST_DOUBLE)
2495     {
2496 #if WORDS_BIG_ENDIAN
2497       *first = const0_rtx;
2498       *second = value;
2499 #else
2500       *first = value;
2501       *second = const0_rtx;
2502 #endif
2503     }
2504   else if (GET_MODE (value) == VOIDmode
2505            /* This is the old way we did CONST_DOUBLE integers.  */
2506            || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT)
2507     {
2508       /* In an integer, the words are defined as most and least significant.
2509          So order them by the target's convention.  */
2510 #if WORDS_BIG_ENDIAN
2511       *first = GEN_INT (CONST_DOUBLE_HIGH (value));
2512       *second = GEN_INT (CONST_DOUBLE_LOW (value));
2513 #else
2514       *first = GEN_INT (CONST_DOUBLE_LOW (value));
2515       *second = GEN_INT (CONST_DOUBLE_HIGH (value));
2516 #endif
2517     }
2518   else
2519     {
2520       if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2521            || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
2522           && ! flag_pretend_float)
2523       abort ();
2524
2525 #if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN
2526       /* Host and target agree => no need to swap.  */
2527       *first = GEN_INT (CONST_DOUBLE_LOW (value));
2528       *second = GEN_INT (CONST_DOUBLE_HIGH (value));
2529 #else
2530       *second = GEN_INT (CONST_DOUBLE_LOW (value));
2531       *first = GEN_INT (CONST_DOUBLE_HIGH (value));
2532 #endif
2533     }
2534 }
2535 \f
2536 /* Return nonzero if this function has no function calls.  */
2537
2538 int
2539 leaf_function_p ()
2540 {
2541   rtx insn;
2542
2543   if (profile_flag || profile_block_flag)
2544     return 0;
2545
2546   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2547     {
2548       if (GET_CODE (insn) == CALL_INSN)
2549         return 0;
2550       if (GET_CODE (insn) == INSN
2551           && GET_CODE (PATTERN (insn)) == SEQUENCE
2552           && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)
2553         return 0;
2554     }
2555   for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2556     {
2557       if (GET_CODE (XEXP (insn, 0)) == CALL_INSN)
2558         return 0;
2559       if (GET_CODE (XEXP (insn, 0)) == INSN
2560           && GET_CODE (PATTERN (XEXP (insn, 0))) == SEQUENCE
2561           && GET_CODE (XVECEXP (PATTERN (XEXP (insn, 0)), 0, 0)) == CALL_INSN)
2562         return 0;
2563     }
2564
2565   return 1;
2566 }
2567
2568 /* On some machines, a function with no call insns
2569    can run faster if it doesn't create its own register window.
2570    When output, the leaf function should use only the "output"
2571    registers.  Ordinarily, the function would be compiled to use
2572    the "input" registers to find its arguments; it is a candidate
2573    for leaf treatment if it uses only the "input" registers.
2574    Leaf function treatment means renumbering so the function
2575    uses the "output" registers instead.  */
2576
2577 #ifdef LEAF_REGISTERS
2578
2579 static char permitted_reg_in_leaf_functions[] = LEAF_REGISTERS;
2580
2581 /* Return 1 if this function uses only the registers that can be
2582    safely renumbered.  */
2583
2584 int
2585 only_leaf_regs_used ()
2586 {
2587   int i;
2588
2589   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2590     {
2591       if ((regs_ever_live[i] || global_regs[i])
2592           && ! permitted_reg_in_leaf_functions[i])
2593         return 0;
2594     }
2595   return 1;
2596 }
2597
2598 /* Scan all instructions and renumber all registers into those
2599    available in leaf functions.  */
2600
2601 static void
2602 leaf_renumber_regs (first)
2603      rtx first;
2604 {
2605   rtx insn;
2606
2607   /* Renumber only the actual patterns.
2608      The reg-notes can contain frame pointer refs,
2609      and renumbering them could crash, and should not be needed.  */
2610   for (insn = first; insn; insn = NEXT_INSN (insn))
2611     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
2612       leaf_renumber_regs_insn (PATTERN (insn));
2613   for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2614     if (GET_RTX_CLASS (GET_CODE (XEXP (insn, 0))) == 'i')
2615       leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0)));
2616 }
2617
2618 /* Scan IN_RTX and its subexpressions, and renumber all regs into those
2619    available in leaf functions.  */
2620
2621 void
2622 leaf_renumber_regs_insn (in_rtx)
2623      register rtx in_rtx;
2624 {
2625   register int i, j;
2626   register char *format_ptr;
2627
2628   if (in_rtx == 0)
2629     return;
2630
2631   /* Renumber all input-registers into output-registers.
2632      renumbered_regs would be 1 for an output-register;
2633      they  */
2634
2635   if (GET_CODE (in_rtx) == REG)
2636     {
2637       int newreg;
2638
2639       /* Don't renumber the same reg twice.  */
2640       if (in_rtx->used)
2641         return;
2642
2643       newreg = REGNO (in_rtx);
2644       /* Don't try to renumber pseudo regs.  It is possible for a pseudo reg
2645          to reach here as part of a REG_NOTE.  */
2646       if (newreg >= FIRST_PSEUDO_REGISTER)
2647         {
2648           in_rtx->used = 1;
2649           return;
2650         }
2651       newreg = LEAF_REG_REMAP (newreg);
2652       if (newreg < 0)
2653         abort ();
2654       regs_ever_live[REGNO (in_rtx)] = 0;
2655       regs_ever_live[newreg] = 1;
2656       REGNO (in_rtx) = newreg;
2657       in_rtx->used = 1;
2658     }
2659
2660   if (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i')
2661     {
2662       /* Inside a SEQUENCE, we find insns.
2663          Renumber just the patterns of these insns,
2664          just as we do for the top-level insns.  */
2665       leaf_renumber_regs_insn (PATTERN (in_rtx));
2666       return;
2667     }
2668
2669   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
2670
2671   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
2672     switch (*format_ptr++)
2673       {
2674       case 'e':
2675         leaf_renumber_regs_insn (XEXP (in_rtx, i));
2676         break;
2677
2678       case 'E':
2679         if (NULL != XVEC (in_rtx, i))
2680           {
2681             for (j = 0; j < XVECLEN (in_rtx, i); j++)
2682               leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
2683           }
2684         break;
2685
2686       case 'S':
2687       case 's':
2688       case '0':
2689       case 'i':
2690       case 'w':
2691       case 'n':
2692       case 'u':
2693         break;
2694
2695       default:
2696         abort ();
2697       }
2698 }
2699 #endif