source: trunk/third/gcc/final.c @ 11288

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