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

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