OSDN Git Service

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