OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / final.c
1 /* Convert RTL to assembler code and output it, for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
3    1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
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 in assembler by the target functions function_prologue and
45    function_epilogue.  Those instructions never exist as rtl.  */
46
47 #include "config.h"
48 #include "system.h"
49
50 #include "tree.h"
51 #include "rtl.h"
52 #include "tm_p.h"
53 #include "regs.h"
54 #include "insn-config.h"
55 #include "insn-attr.h"
56 #include "recog.h"
57 #include "conditions.h"
58 #include "flags.h"
59 #include "real.h"
60 #include "hard-reg-set.h"
61 #include "output.h"
62 #include "except.h"
63 #include "function.h"
64 #include "toplev.h"
65 #include "reload.h"
66 #include "intl.h"
67 #include "basic-block.h"
68 #include "target.h"
69 #include "debug.h"
70
71 #ifdef XCOFF_DEBUGGING_INFO
72 #include "xcoffout.h"           /* Needed for external data
73                                    declarations for e.g. AIX 4.x.  */
74 #endif
75
76 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
77 #include "dwarf2out.h"
78 #endif
79
80 /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist.  So define a
81    null default for it to save conditionalization later.  */
82 #ifndef CC_STATUS_INIT
83 #define CC_STATUS_INIT
84 #endif
85
86 /* How to start an assembler comment.  */
87 #ifndef ASM_COMMENT_START
88 #define ASM_COMMENT_START ";#"
89 #endif
90
91 /* Is the given character a logical line separator for the assembler?  */
92 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
93 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
94 #endif
95
96 #ifndef JUMP_TABLES_IN_TEXT_SECTION
97 #define JUMP_TABLES_IN_TEXT_SECTION 0
98 #endif
99
100 /* Last insn processed by final_scan_insn.  */
101 static rtx debug_insn;
102 rtx current_output_insn;
103
104 /* Line number of last NOTE.  */
105 static int last_linenum;
106
107 /* Highest line number in current block.  */
108 static int high_block_linenum;
109
110 /* Likewise for function.  */
111 static int high_function_linenum;
112
113 /* Filename of last NOTE.  */
114 static const char *last_filename;
115
116 /* Number of basic blocks seen so far;
117    used if profile_block_flag is set.  */
118 static int count_basic_blocks;
119
120 /* Number of instrumented arcs when profile_arc_flag is set.  */
121 extern int count_instrumented_edges;
122
123 extern int length_unit_log; /* This is defined in insn-attrtab.c.  */
124
125 /* Nonzero while outputting an `asm' with operands.
126    This means that inconsistencies are the user's fault, so don't abort.
127    The precise value is the insn being output, to pass to error_for_asm.  */
128 static rtx this_is_asm_operands;
129
130 /* Number of operands of this insn, for an `asm' with operands.  */
131 static unsigned int insn_noperands;
132
133 /* Compare optimization flag.  */
134
135 static rtx last_ignored_compare = 0;
136
137 /* Flag indicating this insn is the start of a new basic block.  */
138
139 static int new_block = 1;
140
141 /* Assign a unique number to each insn that is output.
142    This can be used to generate unique local labels.  */
143
144 static int insn_counter = 0;
145
146 #ifdef HAVE_cc0
147 /* This variable contains machine-dependent flags (defined in tm.h)
148    set and examined by output routines
149    that describe how to interpret the condition codes properly.  */
150
151 CC_STATUS cc_status;
152
153 /* During output of an insn, this contains a copy of cc_status
154    from before the insn.  */
155
156 CC_STATUS cc_prev_status;
157 #endif
158
159 /* Indexed by hardware reg number, is 1 if that register is ever
160    used in the current function.
161
162    In life_analysis, or in stupid_life_analysis, this is set
163    up to record the hard regs used explicitly.  Reload adds
164    in the hard regs used for holding pseudo regs.  Final uses
165    it to generate the code in the function prologue and epilogue
166    to save and restore registers as needed.  */
167
168 char regs_ever_live[FIRST_PSEUDO_REGISTER];
169
170 /* Nonzero means current function must be given a frame pointer.
171    Set in stmt.c if anything is allocated on the stack there.
172    Set in reload1.c if anything is allocated on the stack there.  */
173
174 int frame_pointer_needed;
175
176 /* Assign unique numbers to labels generated for profiling.  */
177
178 int profile_label_no;
179
180 /* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen.  */
181
182 static int block_depth;
183
184 /* Nonzero if have enabled APP processing of our assembler output.  */
185
186 static int app_on;
187
188 /* If we are outputting an insn sequence, this contains the sequence rtx.
189    Zero otherwise.  */
190
191 rtx final_sequence;
192
193 #ifdef ASSEMBLER_DIALECT
194
195 /* Number of the assembler dialect to use, starting at 0.  */
196 static int dialect_number;
197 #endif
198
199 /* Indexed by line number, nonzero if there is a note for that line.  */
200
201 static char *line_note_exists;
202
203 #ifdef HAVE_conditional_execution
204 /* Nonnull if the insn currently being emitted was a COND_EXEC pattern.  */
205 rtx current_insn_predicate;
206 #endif
207
208 /* Linked list to hold line numbers for each basic block.  */
209
210 struct bb_list
211 {
212   struct bb_list *next;         /* pointer to next basic block */
213   int line_num;                 /* line number */
214   int file_label_num;           /* LPBC<n> label # for stored filename */
215   int func_label_num;           /* LPBC<n> label # for stored function name */
216 };
217
218 static struct bb_list *bb_head  = 0;            /* Head of basic block list */
219 static struct bb_list **bb_tail = &bb_head;     /* Ptr to store next bb ptr */
220 static int bb_file_label_num    = -1;           /* Current label # for file */
221 static int bb_func_label_num    = -1;           /* Current label # for func */
222
223 /* Linked list to hold the strings for each file and function name output.  */
224
225 struct bb_str
226 {
227   struct bb_str *next;          /* pointer to next string */
228   const char *string;           /* string */
229   int label_num;                /* label number */
230   int length;                   /* string length */
231 };
232
233 static struct bb_str *sbb_head  = 0;            /* Head of string list.  */
234 static struct bb_str **sbb_tail = &sbb_head;    /* Ptr to store next bb str */
235 static int sbb_label_num        = 0;            /* Last label used */
236
237 #ifdef HAVE_ATTR_length
238 static int asm_insn_count       PARAMS ((rtx));
239 #endif
240 static void profile_function    PARAMS ((FILE *));
241 static void profile_after_prologue PARAMS ((FILE *));
242 static void add_bb              PARAMS ((FILE *));
243 static int add_bb_string        PARAMS ((const char *, int));
244 static void notice_source_line  PARAMS ((rtx));
245 static rtx walk_alter_subreg    PARAMS ((rtx));
246 static void output_asm_name     PARAMS ((void));
247 static void output_operand      PARAMS ((rtx, int));
248 #ifdef LEAF_REGISTERS
249 static void leaf_renumber_regs  PARAMS ((rtx));
250 #endif
251 #ifdef HAVE_cc0
252 static int alter_cond           PARAMS ((rtx));
253 #endif
254 #ifndef ADDR_VEC_ALIGN
255 static int final_addr_vec_align PARAMS ((rtx));
256 #endif
257 #ifdef HAVE_ATTR_length
258 static int align_fuzz           PARAMS ((rtx, rtx, int, unsigned));
259 #endif
260 \f
261 /* Initialize data in final at the beginning of a compilation.  */
262
263 void
264 init_final (filename)
265      const char *filename ATTRIBUTE_UNUSED;
266 {
267   app_on = 0;
268   final_sequence = 0;
269
270 #ifdef ASSEMBLER_DIALECT
271   dialect_number = ASSEMBLER_DIALECT;
272 #endif
273 }
274
275 /* Called at end of source file,
276    to output the block-profiling table for this entire compilation.  */
277
278 void
279 end_final (filename)
280      const char *filename;
281 {
282   int i;
283
284   if (profile_block_flag || profile_arc_flag)
285     {
286       char name[20];
287       int align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
288       int size, rounded;
289       struct bb_list *ptr;
290       struct bb_str *sptr;
291       int long_bytes = LONG_TYPE_SIZE / BITS_PER_UNIT;
292       int gcov_type_bytes = GCOV_TYPE_SIZE / BITS_PER_UNIT;
293       int pointer_bytes = POINTER_SIZE / BITS_PER_UNIT;
294
295       if (profile_block_flag)
296         size = long_bytes * count_basic_blocks;
297       else
298         size = gcov_type_bytes * count_instrumented_edges;
299       rounded = size;
300
301       rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
302       rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
303                  * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
304
305       data_section ();
306
307       /* Output the main header, of 11 words:
308          0:  1 if this file is initialized, else 0.
309          1:  address of file name (LPBX1).
310          2:  address of table of counts (LPBX2).
311          3:  number of counts in the table.
312          4:  always 0, for compatibility with Sun.
313
314          The following are GNU extensions:
315
316          5:  address of table of start addrs of basic blocks (LPBX3).
317          6:  Number of bytes in this header.
318          7:  address of table of function names (LPBX4).
319          8:  address of table of line numbers (LPBX5) or 0.
320          9:  address of table of file names (LPBX6) or 0.
321         10:  space reserved for basic block profiling.  */
322
323       ASM_OUTPUT_ALIGN (asm_out_file, align);
324
325       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 0);
326       /* zero word */
327       assemble_integer (const0_rtx, long_bytes, 1);
328
329       /* address of filename */
330       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 1);
331       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes, 1);
332
333       /* address of count table */
334       ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
335       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes, 1);
336
337       /* count of the # of basic blocks or # of instrumented arcs */
338       if (profile_block_flag)
339         assemble_integer (GEN_INT (count_basic_blocks), long_bytes, 1);
340       else
341         assemble_integer (GEN_INT (count_instrumented_edges), long_bytes, 1);
342
343       /* zero word (link field) */
344       assemble_integer (const0_rtx, pointer_bytes, 1);
345
346       /* address of basic block start address table */
347       if (profile_block_flag)
348         {
349           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3);
350           assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes,
351                             1);
352         }
353       else
354         assemble_integer (const0_rtx, pointer_bytes, 1);
355
356       /* byte count for extended structure.  */
357       assemble_integer (GEN_INT (11 * UNITS_PER_WORD), long_bytes, 1);
358
359       /* address of function name table */
360       if (profile_block_flag)
361         {
362           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 4);
363           assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes,
364                             1);
365         }
366       else
367         assemble_integer (const0_rtx, pointer_bytes, 1);
368
369       /* address of line number and filename tables if debugging.  */
370       if (write_symbols != NO_DEBUG && profile_block_flag)
371         {
372           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 5);
373           assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
374                             pointer_bytes, 1);
375           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 6);
376           assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
377                             pointer_bytes, 1);
378         }
379       else
380         {
381           assemble_integer (const0_rtx, pointer_bytes, 1);
382           assemble_integer (const0_rtx, pointer_bytes, 1);
383         }
384
385       /* space for extension ptr (link field) */
386       assemble_integer (const0_rtx, UNITS_PER_WORD, 1);
387
388       /* Output the file name changing the suffix to .d for Sun tcov
389          compatibility.  */
390       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 1);
391       {
392         char *cwd = getpwd ();
393         int len = strlen (filename) + strlen (cwd) + 1;
394         char *data_file = (char *) alloca (len + 4);
395
396         strcpy (data_file, cwd);
397         strcat (data_file, "/");
398         strcat (data_file, filename);
399         strip_off_ending (data_file, len);
400         if (profile_block_flag)
401           strcat (data_file, ".d");
402         else
403           strcat (data_file, ".da");
404         assemble_string (data_file, strlen (data_file) + 1);
405       }
406
407       /* Make space for the table of counts.  */
408       if (size == 0)
409         {
410           /* Realign data section.  */
411           ASM_OUTPUT_ALIGN (asm_out_file, align);
412           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 2);
413           if (size != 0)
414             assemble_zeros (size);
415         }
416       else
417         {
418           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
419 #ifdef ASM_OUTPUT_SHARED_LOCAL
420           if (flag_shared_data)
421             ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
422           else
423 #endif
424 #ifdef ASM_OUTPUT_ALIGNED_DECL_LOCAL
425             ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, NULL_TREE, name,
426                                            size, BIGGEST_ALIGNMENT);
427 #else
428 #ifdef ASM_OUTPUT_ALIGNED_LOCAL
429             ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
430                                       BIGGEST_ALIGNMENT);
431 #else
432             ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
433 #endif
434 #endif
435         }
436
437       /* Output any basic block strings */
438       if (profile_block_flag)
439         {
440           readonly_data_section ();
441           if (sbb_head)
442             {
443               ASM_OUTPUT_ALIGN (asm_out_file, align);
444               for (sptr = sbb_head; sptr != 0; sptr = sptr->next)
445                 {
446                   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBC",
447                                              sptr->label_num);
448                   assemble_string (sptr->string, sptr->length);
449                 }
450             }
451         }
452
453       /* Output the table of addresses.  */
454       if (profile_block_flag)
455         {
456           /* Realign in new section */
457           ASM_OUTPUT_ALIGN (asm_out_file, align);
458           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 3);
459           for (i = 0; i < count_basic_blocks; i++)
460             {
461               ASM_GENERATE_INTERNAL_LABEL (name, "LPB", i);
462               assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
463                                 pointer_bytes, 1);
464             }
465         }
466
467       /* Output the table of function names.  */
468       if (profile_block_flag)
469         {
470           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 4);
471           for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
472             {
473               if (ptr->func_label_num >= 0)
474                 {
475                   ASM_GENERATE_INTERNAL_LABEL (name, "LPBC",
476                                                ptr->func_label_num);
477                   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
478                                     pointer_bytes, 1);
479                 }
480               else
481                 assemble_integer (const0_rtx, pointer_bytes, 1);
482             }
483
484           for (; i < count_basic_blocks; i++)
485             assemble_integer (const0_rtx, pointer_bytes, 1);
486         }
487
488       if (write_symbols != NO_DEBUG && profile_block_flag)
489         {
490           /* Output the table of line numbers.  */
491           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 5);
492           for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
493             assemble_integer (GEN_INT (ptr->line_num), long_bytes, 1);
494
495           for (; i < count_basic_blocks; i++)
496             assemble_integer (const0_rtx, long_bytes, 1);
497
498           /* Output the table of file names.  */
499           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 6);
500           for ((ptr = bb_head), (i = 0); ptr != 0; (ptr = ptr->next), i++)
501             {
502               if (ptr->file_label_num >= 0)
503                 {
504                   ASM_GENERATE_INTERNAL_LABEL (name, "LPBC",
505                                                ptr->file_label_num);
506                   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name),
507                                     pointer_bytes, 1);
508                 }
509               else
510                 assemble_integer (const0_rtx, pointer_bytes, 1);
511             }
512
513           for (; i < count_basic_blocks; i++)
514             assemble_integer (const0_rtx, pointer_bytes, 1);
515         }
516
517       /* End with the address of the table of addresses,
518          so we can find it easily, as the last word in the file's text.  */
519       if (profile_block_flag)
520         {
521           ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 3);
522           assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes,
523                             1);
524         }
525     }
526 }
527
528 /* Default target function prologue and epilogue assembler output.
529   
530    If not overridden for epilogue code, then the function body itself
531    contains return instructions wherever needed.  */
532 void
533 default_function_pro_epilogue (file, size)
534      FILE *file ATTRIBUTE_UNUSED;
535      HOST_WIDE_INT size ATTRIBUTE_UNUSED;
536 {
537 }
538
539 /* Default target hook that outputs nothing to a stream.  */
540 void
541 no_asm_to_stream (file)
542      FILE *file ATTRIBUTE_UNUSED;
543 {
544 }
545
546 /* Enable APP processing of subsequent output.
547    Used before the output from an `asm' statement.  */
548
549 void
550 app_enable ()
551 {
552   if (! app_on)
553     {
554       fputs (ASM_APP_ON, asm_out_file);
555       app_on = 1;
556     }
557 }
558
559 /* Disable APP processing of subsequent output.
560    Called from varasm.c before most kinds of output.  */
561
562 void
563 app_disable ()
564 {
565   if (app_on)
566     {
567       fputs (ASM_APP_OFF, asm_out_file);
568       app_on = 0;
569     }
570 }
571 \f
572 /* Return the number of slots filled in the current
573    delayed branch sequence (we don't count the insn needing the
574    delay slot).   Zero if not in a delayed branch sequence.  */
575
576 #ifdef DELAY_SLOTS
577 int
578 dbr_sequence_length ()
579 {
580   if (final_sequence != 0)
581     return XVECLEN (final_sequence, 0) - 1;
582   else
583     return 0;
584 }
585 #endif
586 \f
587 /* The next two pages contain routines used to compute the length of an insn
588    and to shorten branches.  */
589
590 /* Arrays for insn lengths, and addresses.  The latter is referenced by
591    `insn_current_length'.  */
592
593 static short *insn_lengths;
594
595 #ifdef HAVE_ATTR_length
596 varray_type insn_addresses_;
597 #endif
598
599 /* Max uid for which the above arrays are valid.  */
600 static int insn_lengths_max_uid;
601
602 /* Address of insn being processed.  Used by `insn_current_length'.  */
603 int insn_current_address;
604
605 /* Address of insn being processed in previous iteration.  */
606 int insn_last_address;
607
608 /* konwn invariant alignment of insn being processed.  */
609 int insn_current_align;
610
611 /* After shorten_branches, for any insn, uid_align[INSN_UID (insn)]
612    gives the next following alignment insn that increases the known
613    alignment, or NULL_RTX if there is no such insn.
614    For any alignment obtained this way, we can again index uid_align with
615    its uid to obtain the next following align that in turn increases the
616    alignment, till we reach NULL_RTX; the sequence obtained this way
617    for each insn we'll call the alignment chain of this insn in the following
618    comments.  */
619
620 struct label_alignment
621 {
622   short alignment;
623   short max_skip;
624 };
625
626 static rtx *uid_align;
627 static int *uid_shuid;
628 static struct label_alignment *label_align;
629
630 /* Indicate that branch shortening hasn't yet been done.  */
631
632 void
633 init_insn_lengths ()
634 {
635   if (label_align)
636     {
637       free (label_align);
638       label_align = 0;
639     }
640   if (uid_shuid)
641     {
642       free (uid_shuid);
643       uid_shuid = 0;
644     }
645   if (insn_lengths)
646     {
647       free (insn_lengths);
648       insn_lengths = 0;
649       insn_lengths_max_uid = 0;
650     }
651 #ifdef HAVE_ATTR_length
652   INSN_ADDRESSES_FREE ();
653 #endif
654   if (uid_align)
655     {
656       free (uid_align);
657       uid_align = 0;
658     }
659 }
660
661 /* Obtain the current length of an insn.  If branch shortening has been done,
662    get its actual length.  Otherwise, get its maximum length.  */
663
664 int
665 get_attr_length (insn)
666      rtx insn ATTRIBUTE_UNUSED;
667 {
668 #ifdef HAVE_ATTR_length
669   rtx body;
670   int i;
671   int length = 0;
672
673   if (insn_lengths_max_uid > INSN_UID (insn))
674     return insn_lengths[INSN_UID (insn)];
675   else
676     switch (GET_CODE (insn))
677       {
678       case NOTE:
679       case BARRIER:
680       case CODE_LABEL:
681         return 0;
682
683       case CALL_INSN:
684         length = insn_default_length (insn);
685         break;
686
687       case JUMP_INSN:
688         body = PATTERN (insn);
689         if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
690           {
691             /* Alignment is machine-dependent and should be handled by
692                ADDR_VEC_ALIGN.  */
693           }
694         else
695           length = insn_default_length (insn);
696         break;
697
698       case INSN:
699         body = PATTERN (insn);
700         if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
701           return 0;
702
703         else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
704           length = asm_insn_count (body) * insn_default_length (insn);
705         else if (GET_CODE (body) == SEQUENCE)
706           for (i = 0; i < XVECLEN (body, 0); i++)
707             length += get_attr_length (XVECEXP (body, 0, i));
708         else
709           length = insn_default_length (insn);
710         break;
711
712       default:
713         break;
714       }
715
716 #ifdef ADJUST_INSN_LENGTH
717   ADJUST_INSN_LENGTH (insn, length);
718 #endif
719   return length;
720 #else /* not HAVE_ATTR_length */
721   return 0;
722 #endif /* not HAVE_ATTR_length */
723 }
724 \f
725 /* Code to handle alignment inside shorten_branches.  */
726
727 /* Here is an explanation how the algorithm in align_fuzz can give
728    proper results:
729
730    Call a sequence of instructions beginning with alignment point X
731    and continuing until the next alignment point `block X'.  When `X'
732    is used in an expression, it means the alignment value of the
733    alignment point.
734
735    Call the distance between the start of the first insn of block X, and
736    the end of the last insn of block X `IX', for the `inner size of X'.
737    This is clearly the sum of the instruction lengths.
738
739    Likewise with the next alignment-delimited block following X, which we
740    shall call block Y.
741
742    Call the distance between the start of the first insn of block X, and
743    the start of the first insn of block Y `OX', for the `outer size of X'.
744
745    The estimated padding is then OX - IX.
746
747    OX can be safely estimated as
748
749            if (X >= Y)
750                    OX = round_up(IX, Y)
751            else
752                    OX = round_up(IX, X) + Y - X
753
754    Clearly est(IX) >= real(IX), because that only depends on the
755    instruction lengths, and those being overestimated is a given.
756
757    Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so
758    we needn't worry about that when thinking about OX.
759
760    When X >= Y, the alignment provided by Y adds no uncertainty factor
761    for branch ranges starting before X, so we can just round what we have.
762    But when X < Y, we don't know anything about the, so to speak,
763    `middle bits', so we have to assume the worst when aligning up from an
764    address mod X to one mod Y, which is Y - X.  */
765
766 #ifndef LABEL_ALIGN
767 #define LABEL_ALIGN(LABEL) align_labels_log
768 #endif
769
770 #ifndef LABEL_ALIGN_MAX_SKIP
771 #define LABEL_ALIGN_MAX_SKIP (align_labels-1)
772 #endif
773
774 #ifndef LOOP_ALIGN
775 #define LOOP_ALIGN(LABEL) align_loops_log
776 #endif
777
778 #ifndef LOOP_ALIGN_MAX_SKIP
779 #define LOOP_ALIGN_MAX_SKIP (align_loops-1)
780 #endif
781
782 #ifndef LABEL_ALIGN_AFTER_BARRIER
783 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) align_jumps_log
784 #endif
785
786 #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
787 #define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (align_jumps-1)
788 #endif
789
790 #ifndef ADDR_VEC_ALIGN
791 static int
792 final_addr_vec_align (addr_vec)
793      rtx addr_vec;
794 {
795   int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec)));
796
797   if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
798     align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
799   return exact_log2 (align);
800
801 }
802
803 #define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC)
804 #endif
805
806 #ifndef INSN_LENGTH_ALIGNMENT
807 #define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log
808 #endif
809
810 #define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)])
811
812 static int min_labelno, max_labelno;
813
814 #define LABEL_TO_ALIGNMENT(LABEL) \
815   (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment)
816
817 #define LABEL_TO_MAX_SKIP(LABEL) \
818   (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip)
819
820 /* For the benefit of port specific code do this also as a function.  */
821
822 int
823 label_to_alignment (label)
824      rtx label;
825 {
826   return LABEL_TO_ALIGNMENT (label);
827 }
828
829 #ifdef HAVE_ATTR_length
830 /* The differences in addresses
831    between a branch and its target might grow or shrink depending on
832    the alignment the start insn of the range (the branch for a forward
833    branch or the label for a backward branch) starts out on; if these
834    differences are used naively, they can even oscillate infinitely.
835    We therefore want to compute a 'worst case' address difference that
836    is independent of the alignment the start insn of the range end
837    up on, and that is at least as large as the actual difference.
838    The function align_fuzz calculates the amount we have to add to the
839    naively computed difference, by traversing the part of the alignment
840    chain of the start insn of the range that is in front of the end insn
841    of the range, and considering for each alignment the maximum amount
842    that it might contribute to a size increase.
843
844    For casesi tables, we also want to know worst case minimum amounts of
845    address difference, in case a machine description wants to introduce
846    some common offset that is added to all offsets in a table.
847    For this purpose, align_fuzz with a growth argument of 0 comuptes the
848    appropriate adjustment.  */
849
850 /* Compute the maximum delta by which the difference of the addresses of
851    START and END might grow / shrink due to a different address for start
852    which changes the size of alignment insns between START and END.
853    KNOWN_ALIGN_LOG is the alignment known for START.
854    GROWTH should be ~0 if the objective is to compute potential code size
855    increase, and 0 if the objective is to compute potential shrink.
856    The return value is undefined for any other value of GROWTH.  */
857
858 static int
859 align_fuzz (start, end, known_align_log, growth)
860      rtx start, end;
861      int known_align_log;
862      unsigned growth;
863 {
864   int uid = INSN_UID (start);
865   rtx align_label;
866   int known_align = 1 << known_align_log;
867   int end_shuid = INSN_SHUID (end);
868   int fuzz = 0;
869
870   for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid])
871     {
872       int align_addr, new_align;
873
874       uid = INSN_UID (align_label);
875       align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid];
876       if (uid_shuid[uid] > end_shuid)
877         break;
878       known_align_log = LABEL_TO_ALIGNMENT (align_label);
879       new_align = 1 << known_align_log;
880       if (new_align < known_align)
881         continue;
882       fuzz += (-align_addr ^ growth) & (new_align - known_align);
883       known_align = new_align;
884     }
885   return fuzz;
886 }
887
888 /* Compute a worst-case reference address of a branch so that it
889    can be safely used in the presence of aligned labels.  Since the
890    size of the branch itself is unknown, the size of the branch is
891    not included in the range.  I.e. for a forward branch, the reference
892    address is the end address of the branch as known from the previous
893    branch shortening pass, minus a value to account for possible size
894    increase due to alignment.  For a backward branch, it is the start
895    address of the branch as known from the current pass, plus a value
896    to account for possible size increase due to alignment.
897    NB.: Therefore, the maximum offset allowed for backward branches needs
898    to exclude the branch size.  */
899
900 int
901 insn_current_reference_address (branch)
902      rtx branch;
903 {
904   rtx dest, seq;
905   int seq_uid;
906
907   if (! INSN_ADDRESSES_SET_P ())
908     return 0;
909
910   seq = NEXT_INSN (PREV_INSN (branch));
911   seq_uid = INSN_UID (seq);
912   if (GET_CODE (branch) != JUMP_INSN)
913     /* This can happen for example on the PA; the objective is to know the
914        offset to address something in front of the start of the function.
915        Thus, we can treat it like a backward branch.
916        We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than
917        any alignment we'd encounter, so we skip the call to align_fuzz.  */
918     return insn_current_address;
919   dest = JUMP_LABEL (branch);
920
921   /* BRANCH has no proper alignment chain set, so use SEQ.  
922      BRANCH also has no INSN_SHUID.  */
923   if (INSN_SHUID (seq) < INSN_SHUID (dest))
924     {
925       /* Forward branch.  */
926       return (insn_last_address + insn_lengths[seq_uid]
927               - align_fuzz (seq, dest, length_unit_log, ~0));
928     }
929   else
930     {
931       /* Backward branch.  */
932       return (insn_current_address
933               + align_fuzz (dest, seq, length_unit_log, ~0));
934     }
935 }
936 #endif /* HAVE_ATTR_length */
937 \f
938 /* Make a pass over all insns and compute their actual lengths by shortening
939    any branches of variable length if possible.  */
940
941 /* Give a default value for the lowest address in a function.  */
942
943 #ifndef FIRST_INSN_ADDRESS
944 #define FIRST_INSN_ADDRESS 0
945 #endif
946
947 /* shorten_branches might be called multiple times:  for example, the SH
948    port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
949    In order to do this, it needs proper length information, which it obtains
950    by calling shorten_branches.  This cannot be collapsed with
951    shorten_branches itself into a single pass unless we also want to intergate
952    reorg.c, since the branch splitting exposes new instructions with delay
953    slots.  */
954
955 void
956 shorten_branches (first)
957      rtx first ATTRIBUTE_UNUSED;
958 {
959   rtx insn;
960   int max_uid;
961   int i;
962   int max_log;
963   int max_skip;
964 #ifdef HAVE_ATTR_length
965 #define MAX_CODE_ALIGN 16
966   rtx seq;
967   int something_changed = 1;
968   char *varying_length;
969   rtx body;
970   int uid;
971   rtx align_tab[MAX_CODE_ALIGN];
972
973 #endif
974
975   /* We must do some computations even when not actually shortening, in
976      order to get the alignment information for the labels.  */
977
978   init_insn_lengths ();
979
980   /* Compute maximum UID and allocate label_align / uid_shuid.  */
981   max_uid = get_max_uid ();
982
983   max_labelno = max_label_num ();
984   min_labelno = get_first_label_num ();
985   label_align = (struct label_alignment *)
986     xcalloc ((max_labelno - min_labelno + 1), sizeof (struct label_alignment));
987
988   uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid);
989
990   /* Initialize label_align and set up uid_shuid to be strictly
991      monotonically rising with insn order.  */
992   /* We use max_log here to keep track of the maximum alignment we want to
993      impose on the next CODE_LABEL (or the current one if we are processing
994      the CODE_LABEL itself).  */
995
996   max_log = 0;
997   max_skip = 0;
998
999   for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
1000     {
1001       int log;
1002
1003       INSN_SHUID (insn) = i++;
1004       if (INSN_P (insn))
1005         {
1006           /* reorg might make the first insn of a loop being run once only,
1007              and delete the label in front of it.  Then we want to apply
1008              the loop alignment to the new label created by reorg, which
1009              is separated by the former loop start insn from the
1010              NOTE_INSN_LOOP_BEG.  */
1011         }
1012       else if (GET_CODE (insn) == CODE_LABEL)
1013         {
1014           rtx next;
1015
1016           log = LABEL_ALIGN (insn);
1017           if (max_log < log)
1018             {
1019               max_log = log;
1020               max_skip = LABEL_ALIGN_MAX_SKIP;
1021             }
1022           next = NEXT_INSN (insn);
1023           /* ADDR_VECs only take room if read-only data goes into the text
1024              section.  */
1025           if (JUMP_TABLES_IN_TEXT_SECTION
1026 #if !defined(READONLY_DATA_SECTION)
1027               || 1
1028 #endif
1029               )
1030             if (next && GET_CODE (next) == JUMP_INSN)
1031               {
1032                 rtx nextbody = PATTERN (next);
1033                 if (GET_CODE (nextbody) == ADDR_VEC
1034                     || GET_CODE (nextbody) == ADDR_DIFF_VEC)
1035                   {
1036                     log = ADDR_VEC_ALIGN (next);
1037                     if (max_log < log)
1038                       {
1039                         max_log = log;
1040                         max_skip = LABEL_ALIGN_MAX_SKIP;
1041                       }
1042                   }
1043               }
1044           LABEL_TO_ALIGNMENT (insn) = max_log;
1045           LABEL_TO_MAX_SKIP (insn) = max_skip;
1046           max_log = 0;
1047           max_skip = 0;
1048         }
1049       else if (GET_CODE (insn) == BARRIER)
1050         {
1051           rtx label;
1052
1053           for (label = insn; label && ! INSN_P (label);
1054                label = NEXT_INSN (label))
1055             if (GET_CODE (label) == CODE_LABEL)
1056               {
1057                 log = LABEL_ALIGN_AFTER_BARRIER (insn);
1058                 if (max_log < log)
1059                   {
1060                     max_log = log;
1061                     max_skip = LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP;
1062                   }
1063                 break;
1064               }
1065         }
1066       /* Again, we allow NOTE_INSN_LOOP_BEG - INSN - CODE_LABEL
1067          sequences in order to handle reorg output efficiently.  */
1068       else if (GET_CODE (insn) == NOTE
1069                && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
1070         {
1071           rtx label;
1072           int nest = 0;
1073
1074           /* Search for the label that starts the loop.
1075              Don't skip past the end of the loop, since that could
1076              lead to putting an alignment where it does not belong.
1077              However, a label after a nested (non-)loop would be OK.  */
1078           for (label = insn; label; label = NEXT_INSN (label))
1079             {
1080               if (GET_CODE (label) == NOTE
1081                   && NOTE_LINE_NUMBER (label) == NOTE_INSN_LOOP_BEG)
1082                 nest++;
1083               else if (GET_CODE (label) == NOTE
1084                        && NOTE_LINE_NUMBER (label) == NOTE_INSN_LOOP_END
1085                        && --nest == 0)
1086                 break;
1087               else if (GET_CODE (label) == CODE_LABEL)
1088                 {
1089                   log = LOOP_ALIGN (label);
1090                   if (max_log < log)
1091                     {
1092                       max_log = log;
1093                       max_skip = LOOP_ALIGN_MAX_SKIP;
1094                     }
1095                   break;
1096                 }
1097             }
1098         }
1099       else
1100         continue;
1101     }
1102 #ifdef HAVE_ATTR_length
1103
1104   /* Allocate the rest of the arrays.  */
1105   insn_lengths = (short *) xmalloc (max_uid * sizeof (short));
1106   insn_lengths_max_uid = max_uid;
1107   /* Syntax errors can lead to labels being outside of the main insn stream.
1108      Initialize insn_addresses, so that we get reproducible results.  */
1109   INSN_ADDRESSES_ALLOC (max_uid);
1110
1111   varying_length = (char *) xcalloc (max_uid, sizeof (char));
1112
1113   /* Initialize uid_align.  We scan instructions
1114      from end to start, and keep in align_tab[n] the last seen insn
1115      that does an alignment of at least n+1, i.e. the successor
1116      in the alignment chain for an insn that does / has a known
1117      alignment of n.  */
1118   uid_align = (rtx *) xcalloc (max_uid, sizeof *uid_align);
1119
1120   for (i = MAX_CODE_ALIGN; --i >= 0;)
1121     align_tab[i] = NULL_RTX;
1122   seq = get_last_insn ();
1123   for (; seq; seq = PREV_INSN (seq))
1124     {
1125       int uid = INSN_UID (seq);
1126       int log;
1127       log = (GET_CODE (seq) == CODE_LABEL ? LABEL_TO_ALIGNMENT (seq) : 0);
1128       uid_align[uid] = align_tab[0];
1129       if (log)
1130         {
1131           /* Found an alignment label.  */
1132           uid_align[uid] = align_tab[log];
1133           for (i = log - 1; i >= 0; i--)
1134             align_tab[i] = seq;
1135         }
1136     }
1137 #ifdef CASE_VECTOR_SHORTEN_MODE
1138   if (optimize)
1139     {
1140       /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum
1141          label fields.  */
1142
1143       int min_shuid = INSN_SHUID (get_insns ()) - 1;
1144       int max_shuid = INSN_SHUID (get_last_insn ()) + 1;
1145       int rel;
1146
1147       for (insn = first; insn != 0; insn = NEXT_INSN (insn))
1148         {
1149           rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat;
1150           int len, i, min, max, insn_shuid;
1151           int min_align;
1152           addr_diff_vec_flags flags;
1153
1154           if (GET_CODE (insn) != JUMP_INSN
1155               || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
1156             continue;
1157           pat = PATTERN (insn);
1158           len = XVECLEN (pat, 1);
1159           if (len <= 0)
1160             abort ();
1161           min_align = MAX_CODE_ALIGN;
1162           for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
1163             {
1164               rtx lab = XEXP (XVECEXP (pat, 1, i), 0);
1165               int shuid = INSN_SHUID (lab);
1166               if (shuid < min)
1167                 {
1168                   min = shuid;
1169                   min_lab = lab;
1170                 }
1171               if (shuid > max)
1172                 {
1173                   max = shuid;
1174                   max_lab = lab;
1175                 }
1176               if (min_align > LABEL_TO_ALIGNMENT (lab))
1177                 min_align = LABEL_TO_ALIGNMENT (lab);
1178             }
1179           XEXP (pat, 2) = gen_rtx_LABEL_REF (VOIDmode, min_lab);
1180           XEXP (pat, 3) = gen_rtx_LABEL_REF (VOIDmode, max_lab);
1181           insn_shuid = INSN_SHUID (insn);
1182           rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
1183           flags.min_align = min_align;
1184           flags.base_after_vec = rel > insn_shuid;
1185           flags.min_after_vec  = min > insn_shuid;
1186           flags.max_after_vec  = max > insn_shuid;
1187           flags.min_after_base = min > rel;
1188           flags.max_after_base = max > rel;
1189           ADDR_DIFF_VEC_FLAGS (pat) = flags;
1190         }
1191     }
1192 #endif /* CASE_VECTOR_SHORTEN_MODE */
1193
1194   /* Compute initial lengths, addresses, and varying flags for each insn.  */
1195   for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
1196        insn != 0;
1197        insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
1198     {
1199       uid = INSN_UID (insn);
1200
1201       insn_lengths[uid] = 0;
1202
1203       if (GET_CODE (insn) == CODE_LABEL)
1204         {
1205           int log = LABEL_TO_ALIGNMENT (insn);
1206           if (log)
1207             {
1208               int align = 1 << log;
1209               int new_address = (insn_current_address + align - 1) & -align;
1210               insn_lengths[uid] = new_address - insn_current_address;
1211             }
1212         }
1213
1214       INSN_ADDRESSES (uid) = insn_current_address;
1215
1216       if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER
1217           || GET_CODE (insn) == CODE_LABEL)
1218         continue;
1219       if (INSN_DELETED_P (insn))
1220         continue;
1221
1222       body = PATTERN (insn);
1223       if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
1224         {
1225           /* This only takes room if read-only data goes into the text
1226              section.  */
1227           if (JUMP_TABLES_IN_TEXT_SECTION
1228 #if !defined(READONLY_DATA_SECTION)
1229               || 1
1230 #endif
1231               )
1232             insn_lengths[uid] = (XVECLEN (body,
1233                                           GET_CODE (body) == ADDR_DIFF_VEC)
1234                                  * GET_MODE_SIZE (GET_MODE (body)));
1235           /* Alignment is handled by ADDR_VEC_ALIGN.  */
1236         }
1237       else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
1238         insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn);
1239       else if (GET_CODE (body) == SEQUENCE)
1240         {
1241           int i;
1242           int const_delay_slots;
1243 #ifdef DELAY_SLOTS
1244           const_delay_slots = const_num_delay_slots (XVECEXP (body, 0, 0));
1245 #else
1246           const_delay_slots = 0;
1247 #endif
1248           /* Inside a delay slot sequence, we do not do any branch shortening
1249              if the shortening could change the number of delay slots
1250              of the branch.  */
1251           for (i = 0; i < XVECLEN (body, 0); i++)
1252             {
1253               rtx inner_insn = XVECEXP (body, 0, i);
1254               int inner_uid = INSN_UID (inner_insn);
1255               int inner_length;
1256
1257               if (GET_CODE (body) == ASM_INPUT
1258                   || asm_noperands (PATTERN (XVECEXP (body, 0, i))) >= 0)
1259                 inner_length = (asm_insn_count (PATTERN (inner_insn))
1260                                 * insn_default_length (inner_insn));
1261               else
1262                 inner_length = insn_default_length (inner_insn);
1263
1264               insn_lengths[inner_uid] = inner_length;
1265               if (const_delay_slots)
1266                 {
1267                   if ((varying_length[inner_uid]
1268                        = insn_variable_length_p (inner_insn)) != 0)
1269                     varying_length[uid] = 1;
1270                   INSN_ADDRESSES (inner_uid) = (insn_current_address
1271                                                 + insn_lengths[uid]);
1272                 }
1273               else
1274                 varying_length[inner_uid] = 0;
1275               insn_lengths[uid] += inner_length;
1276             }
1277         }
1278       else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER)
1279         {
1280           insn_lengths[uid] = insn_default_length (insn);
1281           varying_length[uid] = insn_variable_length_p (insn);
1282         }
1283
1284       /* If needed, do any adjustment.  */
1285 #ifdef ADJUST_INSN_LENGTH
1286       ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
1287       if (insn_lengths[uid] < 0)
1288         fatal_insn ("Negative insn length", insn);
1289 #endif
1290     }
1291
1292   /* Now loop over all the insns finding varying length insns.  For each,
1293      get the current insn length.  If it has changed, reflect the change.
1294      When nothing changes for a full pass, we are done.  */
1295
1296   while (something_changed)
1297     {
1298       something_changed = 0;
1299       insn_current_align = MAX_CODE_ALIGN - 1;
1300       for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
1301            insn != 0;
1302            insn = NEXT_INSN (insn))
1303         {
1304           int new_length;
1305 #ifdef ADJUST_INSN_LENGTH
1306           int tmp_length;
1307 #endif
1308           int length_align;
1309
1310           uid = INSN_UID (insn);
1311
1312           if (GET_CODE (insn) == CODE_LABEL)
1313             {
1314               int log = LABEL_TO_ALIGNMENT (insn);
1315               if (log > insn_current_align)
1316                 {
1317                   int align = 1 << log;
1318                   int new_address= (insn_current_address + align - 1) & -align;
1319                   insn_lengths[uid] = new_address - insn_current_address;
1320                   insn_current_align = log;
1321                   insn_current_address = new_address;
1322                 }
1323               else
1324                 insn_lengths[uid] = 0;
1325               INSN_ADDRESSES (uid) = insn_current_address;
1326               continue;
1327             }
1328
1329           length_align = INSN_LENGTH_ALIGNMENT (insn);
1330           if (length_align < insn_current_align)
1331             insn_current_align = length_align;
1332
1333           insn_last_address = INSN_ADDRESSES (uid);
1334           INSN_ADDRESSES (uid) = insn_current_address;
1335
1336 #ifdef CASE_VECTOR_SHORTEN_MODE
1337           if (optimize && GET_CODE (insn) == JUMP_INSN
1338               && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
1339             {
1340               rtx body = PATTERN (insn);
1341               int old_length = insn_lengths[uid];
1342               rtx rel_lab = XEXP (XEXP (body, 0), 0);
1343               rtx min_lab = XEXP (XEXP (body, 2), 0);
1344               rtx max_lab = XEXP (XEXP (body, 3), 0);
1345               addr_diff_vec_flags flags = ADDR_DIFF_VEC_FLAGS (body);
1346               int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab));
1347               int min_addr = INSN_ADDRESSES (INSN_UID (min_lab));
1348               int max_addr = INSN_ADDRESSES (INSN_UID (max_lab));
1349               rtx prev;
1350               int rel_align = 0;
1351
1352               /* Try to find a known alignment for rel_lab.  */
1353               for (prev = rel_lab;
1354                    prev
1355                    && ! insn_lengths[INSN_UID (prev)]
1356                    && ! (varying_length[INSN_UID (prev)] & 1);
1357                    prev = PREV_INSN (prev))
1358                 if (varying_length[INSN_UID (prev)] & 2)
1359                   {
1360                     rel_align = LABEL_TO_ALIGNMENT (prev);
1361                     break;
1362                   }
1363
1364               /* See the comment on addr_diff_vec_flags in rtl.h for the
1365                  meaning of the flags values.  base: REL_LAB   vec: INSN  */
1366               /* Anything after INSN has still addresses from the last
1367                  pass; adjust these so that they reflect our current
1368                  estimate for this pass.  */
1369               if (flags.base_after_vec)
1370                 rel_addr += insn_current_address - insn_last_address;
1371               if (flags.min_after_vec)
1372                 min_addr += insn_current_address - insn_last_address;
1373               if (flags.max_after_vec)
1374                 max_addr += insn_current_address - insn_last_address;
1375               /* We want to know the worst case, i.e. lowest possible value
1376                  for the offset of MIN_LAB.  If MIN_LAB is after REL_LAB,
1377                  its offset is positive, and we have to be wary of code shrink;
1378                  otherwise, it is negative, and we have to be vary of code
1379                  size increase.  */
1380               if (flags.min_after_base)
1381                 {
1382                   /* If INSN is between REL_LAB and MIN_LAB, the size
1383                      changes we are about to make can change the alignment
1384                      within the observed offset, therefore we have to break
1385                      it up into two parts that are independent.  */
1386                   if (! flags.base_after_vec && flags.min_after_vec)
1387                     {
1388                       min_addr -= align_fuzz (rel_lab, insn, rel_align, 0);
1389                       min_addr -= align_fuzz (insn, min_lab, 0, 0);
1390                     }
1391                   else
1392                     min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0);
1393                 }
1394               else
1395                 {
1396                   if (flags.base_after_vec && ! flags.min_after_vec)
1397                     {
1398                       min_addr -= align_fuzz (min_lab, insn, 0, ~0);
1399                       min_addr -= align_fuzz (insn, rel_lab, 0, ~0);
1400                     }
1401                   else
1402                     min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0);
1403                 }
1404               /* Likewise, determine the highest lowest possible value
1405                  for the offset of MAX_LAB.  */
1406               if (flags.max_after_base)
1407                 {
1408                   if (! flags.base_after_vec && flags.max_after_vec)
1409                     {
1410                       max_addr += align_fuzz (rel_lab, insn, rel_align, ~0);
1411                       max_addr += align_fuzz (insn, max_lab, 0, ~0);
1412                     }
1413                   else
1414                     max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0);
1415                 }
1416               else
1417                 {
1418                   if (flags.base_after_vec && ! flags.max_after_vec)
1419                     {
1420                       max_addr += align_fuzz (max_lab, insn, 0, 0);
1421                       max_addr += align_fuzz (insn, rel_lab, 0, 0);
1422                     }
1423                   else
1424                     max_addr += align_fuzz (max_lab, rel_lab, 0, 0);
1425                 }
1426               PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
1427                                                         max_addr - rel_addr,
1428                                                         body));
1429               if (JUMP_TABLES_IN_TEXT_SECTION
1430 #if !defined(READONLY_DATA_SECTION)
1431                   || 1
1432 #endif
1433                   )
1434                 {
1435                   insn_lengths[uid]
1436                     = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body)));
1437                   insn_current_address += insn_lengths[uid];
1438                   if (insn_lengths[uid] != old_length)
1439                     something_changed = 1;
1440                 }
1441
1442               continue;
1443             }
1444 #endif /* CASE_VECTOR_SHORTEN_MODE */
1445
1446           if (! (varying_length[uid]))
1447             {
1448               insn_current_address += insn_lengths[uid];
1449               continue;
1450             }
1451           if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
1452             {
1453               int i;
1454
1455               body = PATTERN (insn);
1456               new_length = 0;
1457               for (i = 0; i < XVECLEN (body, 0); i++)
1458                 {
1459                   rtx inner_insn = XVECEXP (body, 0, i);
1460                   int inner_uid = INSN_UID (inner_insn);
1461                   int inner_length;
1462
1463                   INSN_ADDRESSES (inner_uid) = insn_current_address;
1464
1465                   /* insn_current_length returns 0 for insns with a
1466                      non-varying length.  */
1467                   if (! varying_length[inner_uid])
1468                     inner_length = insn_lengths[inner_uid];
1469                   else
1470                     inner_length = insn_current_length (inner_insn);
1471
1472                   if (inner_length != insn_lengths[inner_uid])
1473                     {
1474                       insn_lengths[inner_uid] = inner_length;
1475                       something_changed = 1;
1476                     }
1477                   insn_current_address += insn_lengths[inner_uid];
1478                   new_length += inner_length;
1479                 }
1480             }
1481           else
1482             {
1483               new_length = insn_current_length (insn);
1484               insn_current_address += new_length;
1485             }
1486
1487 #ifdef ADJUST_INSN_LENGTH
1488           /* If needed, do any adjustment.  */
1489           tmp_length = new_length;
1490           ADJUST_INSN_LENGTH (insn, new_length);
1491           insn_current_address += (new_length - tmp_length);
1492 #endif
1493
1494           if (new_length != insn_lengths[uid])
1495             {
1496               insn_lengths[uid] = new_length;
1497               something_changed = 1;
1498             }
1499         }
1500       /* For a non-optimizing compile, do only a single pass.  */
1501       if (!optimize)
1502         break;
1503     }
1504
1505   free (varying_length);
1506
1507 #endif /* HAVE_ATTR_length */
1508 }
1509
1510 #ifdef HAVE_ATTR_length
1511 /* Given the body of an INSN known to be generated by an ASM statement, return
1512    the number of machine instructions likely to be generated for this insn.
1513    This is used to compute its length.  */
1514
1515 static int
1516 asm_insn_count (body)
1517      rtx body;
1518 {
1519   const char *template;
1520   int count = 1;
1521
1522   if (GET_CODE (body) == ASM_INPUT)
1523     template = XSTR (body, 0);
1524   else
1525     template = decode_asm_operands (body, NULL, NULL, NULL, NULL);
1526
1527   for (; *template; template++)
1528     if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template) || *template == '\n')
1529       count++;
1530
1531   return count;
1532 }
1533 #endif
1534 \f
1535 /* Output assembler code for the start of a function,
1536    and initialize some of the variables in this file
1537    for the new function.  The label for the function and associated
1538    assembler pseudo-ops have already been output in `assemble_start_function'.
1539
1540    FIRST is the first insn of the rtl for the function being compiled.
1541    FILE is the file to write assembler code to.
1542    OPTIMIZE is nonzero if we should eliminate redundant
1543      test and compare insns.  */
1544
1545 void
1546 final_start_function (first, file, optimize)
1547      rtx first;
1548      FILE *file;
1549      int optimize ATTRIBUTE_UNUSED;
1550 {
1551   block_depth = 0;
1552
1553   this_is_asm_operands = 0;
1554
1555 #ifdef NON_SAVING_SETJMP
1556   /* A function that calls setjmp should save and restore all the
1557      call-saved registers on a system where longjmp clobbers them.  */
1558   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1559     {
1560       int i;
1561
1562       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1563         if (!call_used_regs[i])
1564           regs_ever_live[i] = 1;
1565     }
1566 #endif
1567
1568   if (NOTE_LINE_NUMBER (first) != NOTE_INSN_DELETED)
1569     notice_source_line (first);
1570   high_block_linenum = high_function_linenum = last_linenum;
1571
1572   (*debug_hooks->begin_prologue) (last_linenum, last_filename);
1573
1574 #if defined (DWARF2_UNWIND_INFO) || defined (IA64_UNWIND_INFO)
1575   if (write_symbols != DWARF2_DEBUG)
1576     dwarf2out_begin_prologue (0, NULL);
1577 #endif
1578
1579 #ifdef LEAF_REG_REMAP
1580   if (current_function_uses_only_leaf_regs)
1581     leaf_renumber_regs (first);
1582 #endif
1583
1584   /* The Sun386i and perhaps other machines don't work right
1585      if the profiling code comes after the prologue.  */
1586 #ifdef PROFILE_BEFORE_PROLOGUE
1587   if (profile_flag)
1588     profile_function (file);
1589 #endif /* PROFILE_BEFORE_PROLOGUE */
1590
1591 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue)
1592   if (dwarf2out_do_frame ())
1593     dwarf2out_frame_debug (NULL_RTX);
1594 #endif
1595
1596   /* If debugging, assign block numbers to all of the blocks in this
1597      function.  */
1598   if (write_symbols)
1599     {
1600       number_blocks (current_function_decl);
1601       remove_unnecessary_notes ();
1602       /* We never actually put out begin/end notes for the top-level
1603          block in the function.  But, conceptually, that block is
1604          always needed.  */
1605       TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
1606     }
1607
1608   /* First output the function prologue: code to set up the stack frame.  */
1609   (*targetm.asm_out.function_prologue) (file, get_frame_size ());
1610
1611   /* If the machine represents the prologue as RTL, the profiling code must
1612      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
1613 #ifdef HAVE_prologue
1614   if (! HAVE_prologue)
1615 #endif
1616     profile_after_prologue (file);
1617
1618   profile_label_no++;
1619
1620   /* If we are doing basic block profiling, remember a printable version
1621      of the function name.  */
1622   if (profile_block_flag)
1623     {
1624       bb_func_label_num =
1625         add_bb_string ((*decl_printable_name) (current_function_decl, 2),
1626                        FALSE);
1627     }
1628 }
1629
1630 static void
1631 profile_after_prologue (file)
1632      FILE *file ATTRIBUTE_UNUSED;
1633 {
1634 #ifdef FUNCTION_BLOCK_PROFILER
1635   if (profile_block_flag)
1636     {
1637       FUNCTION_BLOCK_PROFILER (file, count_basic_blocks);
1638     }
1639 #endif /* FUNCTION_BLOCK_PROFILER */
1640
1641 #ifndef PROFILE_BEFORE_PROLOGUE
1642   if (profile_flag)
1643     profile_function (file);
1644 #endif /* not PROFILE_BEFORE_PROLOGUE */
1645 }
1646
1647 static void
1648 profile_function (file)
1649      FILE *file;
1650 {
1651 #ifndef NO_PROFILE_COUNTERS
1652   int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
1653 #endif
1654 #if defined(ASM_OUTPUT_REG_PUSH)
1655 #if defined(STRUCT_VALUE_INCOMING_REGNUM) || defined(STRUCT_VALUE_REGNUM)
1656   int sval = current_function_returns_struct;
1657 #endif
1658 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
1659   int cxt = current_function_needs_context;
1660 #endif
1661 #endif /* ASM_OUTPUT_REG_PUSH */
1662
1663 #ifndef NO_PROFILE_COUNTERS
1664   data_section ();
1665   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
1666   ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no);
1667   assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, 1);
1668 #endif
1669
1670   function_section (current_function_decl);
1671
1672 #if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1673   if (sval)
1674     ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM);
1675 #else
1676 #if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1677   if (sval)
1678     {
1679       ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM);
1680     }
1681 #endif
1682 #endif
1683
1684 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1685   if (cxt)
1686     ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_INCOMING_REGNUM);
1687 #else
1688 #if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1689   if (cxt)
1690     {
1691       ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM);
1692     }
1693 #endif
1694 #endif
1695
1696   FUNCTION_PROFILER (file, profile_label_no);
1697
1698 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1699   if (cxt)
1700     ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM);
1701 #else
1702 #if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1703   if (cxt)
1704     {
1705       ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_REGNUM);
1706     }
1707 #endif
1708 #endif
1709
1710 #if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1711   if (sval)
1712     ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM);
1713 #else
1714 #if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
1715   if (sval)
1716     {
1717       ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM);
1718     }
1719 #endif
1720 #endif
1721 }
1722
1723 /* Output assembler code for the end of a function.
1724    For clarity, args are same as those of `final_start_function'
1725    even though not all of them are needed.  */
1726
1727 void
1728 final_end_function ()
1729 {
1730   app_disable ();
1731
1732   (*debug_hooks->end_function) (high_function_linenum);
1733
1734   /* Finally, output the function epilogue:
1735      code to restore the stack frame and return to the caller.  */
1736   (*targetm.asm_out.function_epilogue) (asm_out_file, get_frame_size ());
1737
1738   /* And debug output.  */
1739   (*debug_hooks->end_epilogue) ();
1740
1741 #if defined (DWARF2_UNWIND_INFO)
1742   if (write_symbols != DWARF2_DEBUG && dwarf2out_do_frame ())
1743     dwarf2out_end_epilogue ();
1744 #endif
1745
1746   bb_func_label_num = -1;       /* not in function, nuke label # */
1747 }
1748 \f
1749 /* Add a block to the linked list that remembers the current line/file/function
1750    for basic block profiling.  Emit the label in front of the basic block and
1751    the instructions that increment the count field.  */
1752
1753 static void
1754 add_bb (file)
1755      FILE *file;
1756 {
1757   struct bb_list *ptr =
1758     (struct bb_list *) permalloc (sizeof (struct bb_list));
1759
1760   /* Add basic block to linked list.  */
1761   ptr->next = 0;
1762   ptr->line_num = last_linenum;
1763   ptr->file_label_num = bb_file_label_num;
1764   ptr->func_label_num = bb_func_label_num;
1765   *bb_tail = ptr;
1766   bb_tail = &ptr->next;
1767
1768   /* Enable the table of basic-block use counts
1769      to point at the code it applies to.  */
1770   ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);
1771
1772   /* Before first insn of this basic block, increment the
1773      count of times it was entered.  */
1774 #ifdef BLOCK_PROFILER
1775   BLOCK_PROFILER (file, count_basic_blocks);
1776 #endif
1777 #ifdef HAVE_cc0
1778   CC_STATUS_INIT;
1779 #endif
1780
1781   new_block = 0;
1782   count_basic_blocks++;
1783 }
1784
1785 /* Add a string to be used for basic block profiling.  */
1786
1787 static int
1788 add_bb_string (string, perm_p)
1789      const char *string;
1790      int perm_p;
1791 {
1792   int len;
1793   struct bb_str *ptr = 0;
1794
1795   if (!string)
1796     {
1797       string = "<unknown>";
1798       perm_p = TRUE;
1799     }
1800
1801   /* Allocate a new string if the current string isn't permanent.  If
1802      the string is permanent search for the same string in other
1803      allocations.  */
1804
1805   len = strlen (string) + 1;
1806   if (!perm_p)
1807     {
1808       char *p = (char *) permalloc (len);
1809       memcpy (p, string, len);
1810       string = p;
1811     }
1812   else
1813     for (ptr = sbb_head; ptr != (struct bb_str *) 0; ptr = ptr->next)
1814       if (ptr->string == string)
1815         break;
1816
1817   /* Allocate a new string block if we need to.  */
1818   if (!ptr)
1819     {
1820       ptr = (struct bb_str *) permalloc (sizeof (*ptr));
1821       ptr->next = 0;
1822       ptr->length = len;
1823       ptr->label_num = sbb_label_num++;
1824       ptr->string = string;
1825       *sbb_tail = ptr;
1826       sbb_tail = &ptr->next;
1827     }
1828
1829   return ptr->label_num;
1830 }
1831 \f
1832 /* Output assembler code for some insns: all or part of a function.
1833    For description of args, see `final_start_function', above.
1834
1835    PRESCAN is 1 if we are not really outputting,
1836      just scanning as if we were outputting.
1837    Prescanning deletes and rearranges insns just like ordinary output.
1838    PRESCAN is -2 if we are outputting after having prescanned.
1839    In this case, don't try to delete or rearrange insns
1840    because that has already been done.
1841    Prescanning is done only on certain machines.  */
1842
1843 void
1844 final (first, file, optimize, prescan)
1845      rtx first;
1846      FILE *file;
1847      int optimize;
1848      int prescan;
1849 {
1850   register rtx insn;
1851   int max_line = 0;
1852   int max_uid = 0;
1853
1854   last_ignored_compare = 0;
1855   new_block = 1;
1856
1857   /* Make a map indicating which line numbers appear in this function.
1858      When producing SDB debugging info, delete troublesome line number
1859      notes from inlined functions in other files as well as duplicate
1860      line number notes.  */
1861 #ifdef SDB_DEBUGGING_INFO
1862   if (write_symbols == SDB_DEBUG)
1863     {
1864       rtx last = 0;
1865       for (insn = first; insn; insn = NEXT_INSN (insn))
1866         if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1867           {
1868             if ((RTX_INTEGRATED_P (insn)
1869                  && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
1870                  || (last != 0
1871                      && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
1872                      && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
1873               {
1874                 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
1875                 NOTE_SOURCE_FILE (insn) = 0;
1876                 continue;
1877               }
1878             last = insn;
1879             if (NOTE_LINE_NUMBER (insn) > max_line)
1880               max_line = NOTE_LINE_NUMBER (insn);
1881           }
1882     }
1883   else
1884 #endif
1885     {
1886       for (insn = first; insn; insn = NEXT_INSN (insn))
1887         if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)
1888           max_line = NOTE_LINE_NUMBER (insn);
1889     }
1890
1891   line_note_exists = (char *) xcalloc (max_line + 1, sizeof (char));
1892
1893   for (insn = first; insn; insn = NEXT_INSN (insn))
1894     {
1895       if (INSN_UID (insn) > max_uid)       /* find largest UID */
1896         max_uid = INSN_UID (insn);
1897       if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
1898         line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
1899 #ifdef HAVE_cc0
1900       /* If CC tracking across branches is enabled, record the insn which
1901          jumps to each branch only reached from one place.  */
1902       if (optimize && GET_CODE (insn) == JUMP_INSN)
1903         {
1904           rtx lab = JUMP_LABEL (insn);
1905           if (lab && LABEL_NUSES (lab) == 1)
1906             {
1907               LABEL_REFS (lab) = insn;
1908             }
1909         }
1910 #endif
1911     }
1912
1913   init_recog ();
1914
1915   CC_STATUS_INIT;
1916
1917   /* Output the insns.  */
1918   for (insn = NEXT_INSN (first); insn;)
1919     {
1920 #ifdef HAVE_ATTR_length
1921       if (INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
1922         {
1923 #ifdef STACK_REGS
1924           /* Irritatingly, the reg-stack pass is creating new instructions
1925              and because of REG_DEAD note abuse it has to run after
1926              shorten_branches.  Fake address of -1 then.  */
1927           insn_current_address = -1;
1928 #else
1929           /* This can be triggered by bugs elsewhere in the compiler if
1930              new insns are created after init_insn_lengths is called.  */
1931           abort ();
1932 #endif
1933         }
1934       else
1935         insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
1936 #endif /* HAVE_ATTR_length */
1937
1938       insn = final_scan_insn (insn, file, optimize, prescan, 0);
1939     }
1940
1941   /* Do basic-block profiling here
1942      if the last insn was a conditional branch.  */
1943   if (profile_block_flag && new_block)
1944     add_bb (file);
1945
1946   free (line_note_exists);
1947   line_note_exists = NULL;
1948 }
1949 \f
1950 const char *
1951 get_insn_template (code, insn)
1952      int code;
1953      rtx insn;
1954 {
1955   const void *output = insn_data[code].output;
1956   switch (insn_data[code].output_format)
1957     {
1958     case INSN_OUTPUT_FORMAT_SINGLE:
1959       return (const char *) output;
1960     case INSN_OUTPUT_FORMAT_MULTI:
1961       return ((const char *const *) output)[which_alternative];
1962     case INSN_OUTPUT_FORMAT_FUNCTION:
1963       if (insn == NULL)
1964         abort ();
1965       return (*(insn_output_fn) output) (recog_data.operand, insn);
1966
1967     default:
1968       abort ();
1969     }
1970 }
1971
1972 /* The final scan for one insn, INSN.
1973    Args are same as in `final', except that INSN
1974    is the insn being scanned.
1975    Value returned is the next insn to be scanned.
1976
1977    NOPEEPHOLES is the flag to disallow peephole processing (currently
1978    used for within delayed branch sequence output).  */
1979
1980 rtx
1981 final_scan_insn (insn, file, optimize, prescan, nopeepholes)
1982      rtx insn;
1983      FILE *file;
1984      int optimize ATTRIBUTE_UNUSED;
1985      int prescan;
1986      int nopeepholes ATTRIBUTE_UNUSED;
1987 {
1988 #ifdef HAVE_cc0
1989   rtx set;
1990 #endif
1991
1992   insn_counter++;
1993
1994   /* Ignore deleted insns.  These can occur when we split insns (due to a
1995      template of "#") while not optimizing.  */
1996   if (INSN_DELETED_P (insn))
1997     return NEXT_INSN (insn);
1998
1999   switch (GET_CODE (insn))
2000     {
2001     case NOTE:
2002       if (prescan > 0)
2003         break;
2004
2005       switch (NOTE_LINE_NUMBER (insn))
2006         {
2007         case NOTE_INSN_DELETED:
2008         case NOTE_INSN_LOOP_BEG:
2009         case NOTE_INSN_LOOP_END:
2010         case NOTE_INSN_LOOP_CONT:
2011         case NOTE_INSN_LOOP_VTOP:
2012         case NOTE_INSN_FUNCTION_END:
2013         case NOTE_INSN_SETJMP:
2014         case NOTE_INSN_REPEATED_LINE_NUMBER:
2015         case NOTE_INSN_RANGE_BEG:
2016         case NOTE_INSN_RANGE_END:
2017         case NOTE_INSN_LIVE:
2018         case NOTE_INSN_EXPECTED_VALUE:
2019           break;
2020
2021         case NOTE_INSN_BASIC_BLOCK:
2022 #ifdef IA64_UNWIND_INFO
2023           IA64_UNWIND_EMIT (asm_out_file, insn);
2024 #endif
2025           if (flag_debug_asm)
2026             fprintf (asm_out_file, "\t%s basic block %d\n",
2027                      ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
2028           break;
2029
2030         case NOTE_INSN_EH_REGION_BEG:
2031           ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB",
2032                                   NOTE_EH_HANDLER (insn));
2033           break;
2034
2035         case NOTE_INSN_EH_REGION_END:
2036           ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE",
2037                                   NOTE_EH_HANDLER (insn));
2038           break;
2039
2040         case NOTE_INSN_PROLOGUE_END:
2041           (*targetm.asm_out.function_end_prologue) (file);           
2042           profile_after_prologue (file);
2043           break;
2044
2045         case NOTE_INSN_EPILOGUE_BEG:
2046           (*targetm.asm_out.function_begin_epilogue) (file);         
2047           break;
2048
2049         case NOTE_INSN_FUNCTION_BEG:
2050           app_disable ();
2051           (*debug_hooks->end_prologue) (last_linenum);
2052           break;
2053
2054         case NOTE_INSN_BLOCK_BEG:
2055           if (debug_info_level == DINFO_LEVEL_NORMAL
2056               || debug_info_level == DINFO_LEVEL_VERBOSE
2057               || write_symbols == DWARF_DEBUG
2058               || write_symbols == DWARF2_DEBUG)
2059             {
2060               int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
2061
2062               app_disable ();
2063               ++block_depth;
2064               high_block_linenum = last_linenum;
2065
2066               /* Output debugging info about the symbol-block beginning.  */
2067               (*debug_hooks->begin_block) (last_linenum, n);
2068
2069               /* Mark this block as output.  */
2070               TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
2071             }
2072           break;
2073
2074         case NOTE_INSN_BLOCK_END:
2075           if (debug_info_level == DINFO_LEVEL_NORMAL
2076               || debug_info_level == DINFO_LEVEL_VERBOSE
2077               || write_symbols == DWARF_DEBUG
2078               || write_symbols == DWARF2_DEBUG)
2079             {
2080               int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
2081
2082               app_disable ();
2083
2084               /* End of a symbol-block.  */
2085               --block_depth;
2086               if (block_depth < 0)
2087                 abort ();
2088
2089               (*debug_hooks->end_block) (high_block_linenum, n);
2090             }
2091           break;
2092
2093         case NOTE_INSN_DELETED_LABEL:
2094           /* Emit the label.  We may have deleted the CODE_LABEL because
2095              the label could be proved to be unreachable, though still
2096              referenced (in the form of having its address taken.  */
2097           ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
2098           break;
2099
2100         case 0:
2101           break;
2102
2103         default:
2104           if (NOTE_LINE_NUMBER (insn) <= 0)
2105             abort ();
2106
2107           /* This note is a line-number.  */
2108           {
2109             register rtx note;
2110             int note_after = 0;
2111
2112             /* If there is anything real after this note, output it.
2113                If another line note follows, omit this one.  */
2114             for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
2115               {
2116                 if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
2117                   break;
2118
2119                 /* These types of notes can be significant
2120                    so make sure the preceding line number stays.  */
2121                 else if (GET_CODE (note) == NOTE
2122                          && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
2123                              || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
2124                              || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
2125                   break;
2126                 else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
2127                   {
2128                     /* Another line note follows; we can delete this note
2129                        if no intervening line numbers have notes elsewhere.  */
2130                     int num;
2131                     for (num = NOTE_LINE_NUMBER (insn) + 1;
2132                          num < NOTE_LINE_NUMBER (note);
2133                          num++)
2134                       if (line_note_exists[num])
2135                         break;
2136
2137                     if (num >= NOTE_LINE_NUMBER (note))
2138                       note_after = 1;
2139                     break;
2140                   }
2141               }
2142
2143             /* Output this line note if it is the first or the last line
2144                note in a row.  */
2145             if (!note_after)
2146               {
2147                 notice_source_line (insn);
2148                 (*debug_hooks->source_line) (last_linenum, last_filename);
2149               }
2150           }
2151           break;
2152         }
2153       break;
2154
2155     case BARRIER:
2156 #if defined (DWARF2_UNWIND_INFO)
2157       if (dwarf2out_do_frame ())
2158         dwarf2out_frame_debug (insn);
2159 #endif
2160       break;
2161
2162     case CODE_LABEL:
2163       /* The target port might emit labels in the output function for
2164          some insn, e.g. sh.c output_branchy_insn.  */
2165       if (CODE_LABEL_NUMBER (insn) <= max_labelno)
2166         {
2167           int align = LABEL_TO_ALIGNMENT (insn);
2168 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
2169           int max_skip = LABEL_TO_MAX_SKIP (insn);
2170 #endif
2171
2172           if (align && NEXT_INSN (insn))
2173 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
2174             ASM_OUTPUT_MAX_SKIP_ALIGN (file, align, max_skip);
2175 #else
2176             ASM_OUTPUT_ALIGN (file, align);
2177 #endif
2178         }
2179 #ifdef HAVE_cc0
2180       CC_STATUS_INIT;
2181       /* If this label is reached from only one place, set the condition
2182          codes from the instruction just before the branch.  */
2183
2184       /* Disabled because some insns set cc_status in the C output code
2185          and NOTICE_UPDATE_CC alone can set incorrect status.  */
2186       if (0 /* optimize && LABEL_NUSES (insn) == 1*/)
2187         {
2188           rtx jump = LABEL_REFS (insn);
2189           rtx barrier = prev_nonnote_insn (insn);
2190           rtx prev;
2191           /* If the LABEL_REFS field of this label has been set to point
2192              at a branch, the predecessor of the branch is a regular
2193              insn, and that branch is the only way to reach this label,
2194              set the condition codes based on the branch and its
2195              predecessor.  */
2196           if (barrier && GET_CODE (barrier) == BARRIER
2197               && jump && GET_CODE (jump) == JUMP_INSN
2198               && (prev = prev_nonnote_insn (jump))
2199               && GET_CODE (prev) == INSN)
2200             {
2201               NOTICE_UPDATE_CC (PATTERN (prev), prev);
2202               NOTICE_UPDATE_CC (PATTERN (jump), jump);
2203             }
2204         }
2205 #endif
2206       if (prescan > 0)
2207         break;
2208       new_block = 1;
2209
2210 #ifdef FINAL_PRESCAN_LABEL
2211       FINAL_PRESCAN_INSN (insn, NULL, 0);
2212 #endif
2213
2214       if (LABEL_NAME (insn))
2215         (*debug_hooks->label) (insn);
2216
2217       if (app_on)
2218         {
2219           fputs (ASM_APP_OFF, file);
2220           app_on = 0;
2221         }
2222       if (NEXT_INSN (insn) != 0
2223           && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
2224         {
2225           rtx nextbody = PATTERN (NEXT_INSN (insn));
2226
2227           /* If this label is followed by a jump-table,
2228              make sure we put the label in the read-only section.  Also
2229              possibly write the label and jump table together.  */
2230
2231           if (GET_CODE (nextbody) == ADDR_VEC
2232               || GET_CODE (nextbody) == ADDR_DIFF_VEC)
2233             {
2234 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
2235               /* In this case, the case vector is being moved by the
2236                  target, so don't output the label at all.  Leave that
2237                  to the back end macros.  */
2238 #else
2239               if (! JUMP_TABLES_IN_TEXT_SECTION)
2240                 {
2241                   readonly_data_section ();
2242 #ifdef READONLY_DATA_SECTION
2243                   ASM_OUTPUT_ALIGN (file,
2244                                     exact_log2 (BIGGEST_ALIGNMENT
2245                                                 / BITS_PER_UNIT));
2246 #endif /* READONLY_DATA_SECTION */
2247                 }
2248               else
2249                 function_section (current_function_decl);
2250
2251 #ifdef ASM_OUTPUT_CASE_LABEL
2252               ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
2253                                      NEXT_INSN (insn));
2254 #else
2255               if (LABEL_ALTERNATE_NAME (insn))
2256                 ASM_OUTPUT_ALTERNATE_LABEL_NAME (file, insn);
2257               else
2258                 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
2259 #endif
2260 #endif
2261               break;
2262             }
2263         }
2264       if (LABEL_ALTERNATE_NAME (insn))
2265         ASM_OUTPUT_ALTERNATE_LABEL_NAME (file, insn);
2266       else
2267         ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
2268       break;
2269
2270     default:
2271       {
2272         register rtx body = PATTERN (insn);
2273         int insn_code_number;
2274         const char *template;
2275 #ifdef HAVE_cc0
2276         rtx note;
2277 #endif
2278
2279         /* An INSN, JUMP_INSN or CALL_INSN.
2280            First check for special kinds that recog doesn't recognize.  */
2281
2282         if (GET_CODE (body) == USE /* These are just declarations */
2283             || GET_CODE (body) == CLOBBER)
2284           break;
2285
2286 #ifdef HAVE_cc0
2287         /* If there is a REG_CC_SETTER note on this insn, it means that
2288            the setting of the condition code was done in the delay slot
2289            of the insn that branched here.  So recover the cc status
2290            from the insn that set it.  */
2291
2292         note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
2293         if (note)
2294           {
2295             NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));
2296             cc_prev_status = cc_status;
2297           }
2298 #endif
2299
2300         /* Detect insns that are really jump-tables
2301            and output them as such.  */
2302
2303         if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
2304           {
2305 #if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC))
2306             register int vlen, idx;
2307 #endif
2308
2309             if (prescan > 0)
2310               break;
2311
2312             if (app_on)
2313               {
2314                 fputs (ASM_APP_OFF, file);
2315                 app_on = 0;
2316               }
2317
2318 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
2319             if (GET_CODE (body) == ADDR_VEC)
2320               {
2321 #ifdef ASM_OUTPUT_ADDR_VEC
2322                 ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
2323 #else
2324                 abort ();
2325 #endif
2326               }
2327             else
2328               {
2329 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC
2330                 ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
2331 #else
2332                 abort ();
2333 #endif
2334               }
2335 #else
2336             vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
2337             for (idx = 0; idx < vlen; idx++)
2338               {
2339                 if (GET_CODE (body) == ADDR_VEC)
2340                   {
2341 #ifdef ASM_OUTPUT_ADDR_VEC_ELT
2342                     ASM_OUTPUT_ADDR_VEC_ELT
2343                       (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
2344 #else
2345                     abort ();
2346 #endif
2347                   }
2348                 else
2349                   {
2350 #ifdef ASM_OUTPUT_ADDR_DIFF_ELT
2351                     ASM_OUTPUT_ADDR_DIFF_ELT
2352                       (file,
2353                        body,
2354                        CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
2355                        CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
2356 #else
2357                     abort ();
2358 #endif
2359                   }
2360               }
2361 #ifdef ASM_OUTPUT_CASE_END
2362             ASM_OUTPUT_CASE_END (file,
2363                                  CODE_LABEL_NUMBER (PREV_INSN (insn)),
2364                                  insn);
2365 #endif
2366 #endif
2367
2368             function_section (current_function_decl);
2369
2370             break;
2371           }
2372
2373         /* Do basic-block profiling when we reach a new block.
2374            Done here to avoid jump tables.  */
2375         if (profile_block_flag && new_block)
2376           add_bb (file);
2377
2378         if (GET_CODE (body) == ASM_INPUT)
2379           {
2380             /* There's no telling what that did to the condition codes.  */
2381             CC_STATUS_INIT;
2382             if (prescan > 0)
2383               break;
2384             if (! app_on)
2385               {
2386                 fputs (ASM_APP_ON, file);
2387                 app_on = 1;
2388               }
2389             fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));
2390             break;
2391           }
2392
2393         /* Detect `asm' construct with operands.  */
2394         if (asm_noperands (body) >= 0)
2395           {
2396             unsigned int noperands = asm_noperands (body);
2397             rtx *ops = (rtx *) alloca (noperands * sizeof (rtx));
2398             const char *string;
2399
2400             /* There's no telling what that did to the condition codes.  */
2401             CC_STATUS_INIT;
2402             if (prescan > 0)
2403               break;
2404
2405             if (! app_on)
2406               {
2407                 fputs (ASM_APP_ON, file);
2408                 app_on = 1;
2409               }
2410
2411             /* Get out the operand values.  */
2412             string = decode_asm_operands (body, ops, NULL, NULL, NULL);
2413             /* Inhibit aborts on what would otherwise be compiler bugs.  */
2414             insn_noperands = noperands;
2415             this_is_asm_operands = insn;
2416
2417             /* Output the insn using them.  */
2418             output_asm_insn (string, ops);
2419             this_is_asm_operands = 0;
2420             break;
2421           }
2422
2423         if (prescan <= 0 && app_on)
2424           {
2425             fputs (ASM_APP_OFF, file);
2426             app_on = 0;
2427           }
2428
2429         if (GET_CODE (body) == SEQUENCE)
2430           {
2431             /* A delayed-branch sequence */
2432             register int i;
2433             rtx next;
2434
2435             if (prescan > 0)
2436               break;
2437             final_sequence = body;
2438
2439             /* The first insn in this SEQUENCE might be a JUMP_INSN that will
2440                force the restoration of a comparison that was previously
2441                thought unnecessary.  If that happens, cancel this sequence
2442                and cause that insn to be restored.  */
2443
2444             next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);
2445             if (next != XVECEXP (body, 0, 1))
2446               {
2447                 final_sequence = 0;
2448                 return next;
2449               }
2450
2451             for (i = 1; i < XVECLEN (body, 0); i++)
2452               {
2453                 rtx insn = XVECEXP (body, 0, i);
2454                 rtx next = NEXT_INSN (insn);
2455                 /* We loop in case any instruction in a delay slot gets
2456                    split.  */
2457                 do
2458                   insn = final_scan_insn (insn, file, 0, prescan, 1);
2459                 while (insn != next);
2460               }
2461 #ifdef DBR_OUTPUT_SEQEND
2462             DBR_OUTPUT_SEQEND (file);
2463 #endif
2464             final_sequence = 0;
2465
2466             /* If the insn requiring the delay slot was a CALL_INSN, the
2467                insns in the delay slot are actually executed before the
2468                called function.  Hence we don't preserve any CC-setting
2469                actions in these insns and the CC must be marked as being
2470                clobbered by the function.  */
2471             if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)
2472               {
2473                 CC_STATUS_INIT;
2474               }
2475
2476             /* Following a conditional branch sequence, we have a new basic
2477                block.  */
2478             if (profile_block_flag)
2479               {
2480                 rtx insn = XVECEXP (body, 0, 0);
2481                 rtx body = PATTERN (insn);
2482
2483                 if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
2484                      && GET_CODE (SET_SRC (body)) != LABEL_REF)
2485                     || (GET_CODE (insn) == JUMP_INSN
2486                         && GET_CODE (body) == PARALLEL
2487                         && GET_CODE (XVECEXP (body, 0, 0)) == SET
2488                         && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))
2489                   new_block = 1;
2490               }
2491             break;
2492           }
2493
2494         /* We have a real machine instruction as rtl.  */
2495
2496         body = PATTERN (insn);
2497
2498 #ifdef HAVE_cc0
2499         set = single_set (insn);
2500
2501         /* Check for redundant test and compare instructions
2502            (when the condition codes are already set up as desired).
2503            This is done only when optimizing; if not optimizing,
2504            it should be possible for the user to alter a variable
2505            with the debugger in between statements
2506            and the next statement should reexamine the variable
2507            to compute the condition codes.  */
2508
2509         if (optimize)
2510           {
2511 #if 0
2512             rtx set = single_set (insn);
2513 #endif
2514
2515             if (set
2516                 && GET_CODE (SET_DEST (set)) == CC0
2517                 && insn != last_ignored_compare)
2518               {
2519                 if (GET_CODE (SET_SRC (set)) == SUBREG)
2520                   SET_SRC (set) = alter_subreg (SET_SRC (set));
2521                 else if (GET_CODE (SET_SRC (set)) == COMPARE)
2522                   {
2523                     if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG)
2524                       XEXP (SET_SRC (set), 0)
2525                         = alter_subreg (XEXP (SET_SRC (set), 0));
2526                     if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG)
2527                       XEXP (SET_SRC (set), 1)
2528                         = alter_subreg (XEXP (SET_SRC (set), 1));
2529                   }
2530                 if ((cc_status.value1 != 0
2531                      && rtx_equal_p (SET_SRC (set), cc_status.value1))
2532                     || (cc_status.value2 != 0
2533                         && rtx_equal_p (SET_SRC (set), cc_status.value2)))
2534                   {
2535                     /* Don't delete insn if it has an addressing side-effect.  */
2536                     if (! FIND_REG_INC_NOTE (insn, 0)
2537                         /* or if anything in it is volatile.  */
2538                         && ! volatile_refs_p (PATTERN (insn)))
2539                       {
2540                         /* We don't really delete the insn; just ignore it.  */
2541                         last_ignored_compare = insn;
2542                         break;
2543                       }
2544                   }
2545               }
2546           }
2547 #endif
2548
2549         /* Following a conditional branch, we have a new basic block.
2550            But if we are inside a sequence, the new block starts after the
2551            last insn of the sequence.  */
2552         if (profile_block_flag && final_sequence == 0
2553             && ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
2554                  && GET_CODE (SET_SRC (body)) != LABEL_REF)
2555                 || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL
2556                     && GET_CODE (XVECEXP (body, 0, 0)) == SET
2557                     && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)))
2558           new_block = 1;
2559
2560 #ifndef STACK_REGS
2561         /* Don't bother outputting obvious no-ops, even without -O.
2562            This optimization is fast and doesn't interfere with debugging.
2563            Don't do this if the insn is in a delay slot, since this
2564            will cause an improper number of delay insns to be written.  */
2565         if (final_sequence == 0
2566             && prescan >= 0
2567             && GET_CODE (insn) == INSN && GET_CODE (body) == SET
2568             && GET_CODE (SET_SRC (body)) == REG
2569             && GET_CODE (SET_DEST (body)) == REG
2570             && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
2571           break;
2572 #endif
2573
2574 #ifdef HAVE_cc0
2575         /* If this is a conditional branch, maybe modify it
2576            if the cc's are in a nonstandard state
2577            so that it accomplishes the same thing that it would
2578            do straightforwardly if the cc's were set up normally.  */
2579
2580         if (cc_status.flags != 0
2581             && GET_CODE (insn) == JUMP_INSN
2582             && GET_CODE (body) == SET
2583             && SET_DEST (body) == pc_rtx
2584             && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
2585             && GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (body), 0))) == '<'
2586             && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx
2587             /* This is done during prescan; it is not done again
2588                in final scan when prescan has been done.  */
2589             && prescan >= 0)
2590           {
2591             /* This function may alter the contents of its argument
2592                and clear some of the cc_status.flags bits.
2593                It may also return 1 meaning condition now always true
2594                or -1 meaning condition now always false
2595                or 2 meaning condition nontrivial but altered.  */
2596             register int result = alter_cond (XEXP (SET_SRC (body), 0));
2597             /* If condition now has fixed value, replace the IF_THEN_ELSE
2598                with its then-operand or its else-operand.  */
2599             if (result == 1)
2600               SET_SRC (body) = XEXP (SET_SRC (body), 1);
2601             if (result == -1)
2602               SET_SRC (body) = XEXP (SET_SRC (body), 2);
2603
2604             /* The jump is now either unconditional or a no-op.
2605                If it has become a no-op, don't try to output it.
2606                (It would not be recognized.)  */
2607             if (SET_SRC (body) == pc_rtx)
2608               {
2609                 PUT_CODE (insn, NOTE);
2610                 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
2611                 NOTE_SOURCE_FILE (insn) = 0;
2612                 break;
2613               }
2614             else if (GET_CODE (SET_SRC (body)) == RETURN)
2615               /* Replace (set (pc) (return)) with (return).  */
2616               PATTERN (insn) = body = SET_SRC (body);
2617
2618             /* Rerecognize the instruction if it has changed.  */
2619             if (result != 0)
2620               INSN_CODE (insn) = -1;
2621           }
2622
2623         /* Make same adjustments to instructions that examine the
2624            condition codes without jumping and instructions that
2625            handle conditional moves (if this machine has either one).  */
2626
2627         if (cc_status.flags != 0
2628             && set != 0)
2629           {
2630             rtx cond_rtx, then_rtx, else_rtx;
2631
2632             if (GET_CODE (insn) != JUMP_INSN
2633                 && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
2634               {
2635                 cond_rtx = XEXP (SET_SRC (set), 0);
2636                 then_rtx = XEXP (SET_SRC (set), 1);
2637                 else_rtx = XEXP (SET_SRC (set), 2);
2638               }
2639             else
2640               {
2641                 cond_rtx = SET_SRC (set);
2642                 then_rtx = const_true_rtx;
2643                 else_rtx = const0_rtx;
2644               }
2645
2646             switch (GET_CODE (cond_rtx))
2647               {
2648               case GTU:
2649               case GT:
2650               case LTU:
2651               case LT:
2652               case GEU:
2653               case GE:
2654               case LEU:
2655               case LE:
2656               case EQ:
2657               case NE:
2658                 {
2659                   register int result;
2660                   if (XEXP (cond_rtx, 0) != cc0_rtx)
2661                     break;
2662                   result = alter_cond (cond_rtx);
2663                   if (result == 1)
2664                     validate_change (insn, &SET_SRC (set), then_rtx, 0);
2665                   else if (result == -1)
2666                     validate_change (insn, &SET_SRC (set), else_rtx, 0);
2667                   else if (result == 2)
2668                     INSN_CODE (insn) = -1;
2669                   if (SET_DEST (set) == SET_SRC (set))
2670                     {
2671                       PUT_CODE (insn, NOTE);
2672                       NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
2673                       NOTE_SOURCE_FILE (insn) = 0;
2674                     }
2675                 }
2676                 break;
2677
2678               default:
2679                 break;
2680               }
2681           }
2682
2683 #endif
2684
2685 #ifdef HAVE_peephole
2686         /* Do machine-specific peephole optimizations if desired.  */
2687
2688         if (optimize && !flag_no_peephole && !nopeepholes)
2689           {
2690             rtx next = peephole (insn);
2691             /* When peepholing, if there were notes within the peephole,
2692                emit them before the peephole.  */
2693             if (next != 0 && next != NEXT_INSN (insn))
2694               {
2695                 rtx prev = PREV_INSN (insn);
2696                 rtx note;
2697
2698                 for (note = NEXT_INSN (insn); note != next;
2699                      note = NEXT_INSN (note))
2700                   final_scan_insn (note, file, optimize, prescan, nopeepholes);
2701
2702                 /* In case this is prescan, put the notes
2703                    in proper position for later rescan.  */
2704                 note = NEXT_INSN (insn);
2705                 PREV_INSN (note) = prev;
2706                 NEXT_INSN (prev) = note;
2707                 NEXT_INSN (PREV_INSN (next)) = insn;
2708                 PREV_INSN (insn) = PREV_INSN (next);
2709                 NEXT_INSN (insn) = next;
2710                 PREV_INSN (next) = insn;
2711               }
2712
2713             /* PEEPHOLE might have changed this.  */
2714             body = PATTERN (insn);
2715           }
2716 #endif
2717
2718         /* Try to recognize the instruction.
2719            If successful, verify that the operands satisfy the
2720            constraints for the instruction.  Crash if they don't,
2721            since `reload' should have changed them so that they do.  */
2722
2723         insn_code_number = recog_memoized (insn);
2724         cleanup_subreg_operands (insn);
2725
2726        /* Dump the insn in the assembly for debugging.  */
2727        if (flag_dump_rtl_in_asm)
2728          {
2729            print_rtx_head = ASM_COMMENT_START;
2730            print_rtl_single (asm_out_file, insn);
2731            print_rtx_head = "";
2732          }
2733        
2734         if (! constrain_operands_cached (1))
2735           fatal_insn_not_found (insn);
2736
2737         /* Some target machines need to prescan each insn before
2738            it is output.  */
2739
2740 #ifdef FINAL_PRESCAN_INSN
2741         FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
2742 #endif
2743
2744 #ifdef HAVE_conditional_execution
2745         if (GET_CODE (PATTERN (insn)) == COND_EXEC)
2746           current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
2747         else
2748           current_insn_predicate = NULL_RTX;
2749 #endif
2750
2751 #ifdef HAVE_cc0
2752         cc_prev_status = cc_status;
2753
2754         /* Update `cc_status' for this instruction.
2755            The instruction's output routine may change it further.
2756            If the output routine for a jump insn needs to depend
2757            on the cc status, it should look at cc_prev_status.  */
2758
2759         NOTICE_UPDATE_CC (body, insn);
2760 #endif
2761
2762         current_output_insn = debug_insn = insn;
2763
2764 #if defined (DWARF2_UNWIND_INFO)
2765         if (GET_CODE (insn) == CALL_INSN && dwarf2out_do_frame ())
2766           dwarf2out_frame_debug (insn);
2767 #endif
2768
2769         /* Find the proper template for this insn.  */
2770         template = get_insn_template (insn_code_number, insn);
2771
2772         /* If the C code returns 0, it means that it is a jump insn
2773            which follows a deleted test insn, and that test insn
2774            needs to be reinserted.  */
2775         if (template == 0)
2776           {
2777             rtx prev;
2778
2779             if (prev_nonnote_insn (insn) != last_ignored_compare)
2780               abort ();
2781             new_block = 0;
2782
2783             /* We have already processed the notes between the setter and
2784                the user.  Make sure we don't process them again, this is
2785                particularly important if one of the notes is a block
2786                scope note or an EH note.  */
2787             for (prev = insn;
2788                  prev != last_ignored_compare;
2789                  prev = PREV_INSN (prev))
2790               {
2791                 if (GET_CODE (prev) == NOTE)
2792                   {
2793                     NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;
2794                     NOTE_SOURCE_FILE (prev) = 0;
2795                   }
2796               }
2797
2798             return prev;
2799           }
2800
2801         /* If the template is the string "#", it means that this insn must
2802            be split.  */
2803         if (template[0] == '#' && template[1] == '\0')
2804           {
2805             rtx new = try_split (body, insn, 0);
2806
2807             /* If we didn't split the insn, go away.  */
2808             if (new == insn && PATTERN (new) == body)
2809               fatal_insn ("Could not split insn", insn);
2810
2811 #ifdef HAVE_ATTR_length
2812             /* This instruction should have been split in shorten_branches,
2813                to ensure that we would have valid length info for the
2814                splitees.  */
2815             abort ();
2816 #endif
2817
2818             new_block = 0;
2819             return new;
2820           }
2821
2822         if (prescan > 0)
2823           break;
2824
2825 #ifdef IA64_UNWIND_INFO
2826         IA64_UNWIND_EMIT (asm_out_file, insn);
2827 #endif
2828         /* Output assembler code from the template.  */
2829
2830         output_asm_insn (template, recog_data.operand);
2831
2832 #if defined (DWARF2_UNWIND_INFO)
2833 #if defined (HAVE_prologue)
2834         if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
2835           dwarf2out_frame_debug (insn);
2836 #else
2837         if (!ACCUMULATE_OUTGOING_ARGS
2838             && GET_CODE (insn) == INSN
2839             && dwarf2out_do_frame ())
2840           dwarf2out_frame_debug (insn);
2841 #endif
2842 #endif
2843
2844 #if 0
2845         /* It's not at all clear why we did this and doing so interferes
2846            with tests we'd like to do to use REG_WAS_0 notes, so let's try
2847            with this out.  */
2848
2849         /* Mark this insn as having been output.  */
2850         INSN_DELETED_P (insn) = 1;
2851 #endif
2852
2853         current_output_insn = debug_insn = 0;
2854       }
2855     }
2856   return NEXT_INSN (insn);
2857 }
2858 \f
2859 /* Output debugging info to the assembler file FILE
2860    based on the NOTE-insn INSN, assumed to be a line number.  */
2861
2862 static void
2863 notice_source_line (insn)
2864      rtx insn;
2865 {
2866   register const char *filename = NOTE_SOURCE_FILE (insn);
2867
2868   /* Remember filename for basic block profiling.
2869      Filenames are allocated on the permanent obstack
2870      or are passed in ARGV, so we don't have to save
2871      the string.  */
2872
2873   if (profile_block_flag && last_filename != filename)
2874     bb_file_label_num = add_bb_string (filename, TRUE);
2875
2876   last_filename = filename;
2877   last_linenum = NOTE_LINE_NUMBER (insn);
2878   high_block_linenum = MAX (last_linenum, high_block_linenum);
2879   high_function_linenum = MAX (last_linenum, high_function_linenum);
2880 }
2881 \f
2882 /* For each operand in INSN, simplify (subreg (reg)) so that it refers
2883    directly to the desired hard register.  */
2884
2885 void
2886 cleanup_subreg_operands (insn)
2887      rtx insn;
2888 {
2889   int i;
2890   extract_insn_cached (insn);
2891   for (i = 0; i < recog_data.n_operands; i++)
2892     {
2893       if (GET_CODE (recog_data.operand[i]) == SUBREG)
2894         recog_data.operand[i] = alter_subreg (recog_data.operand[i]);
2895       else if (GET_CODE (recog_data.operand[i]) == PLUS
2896                || GET_CODE (recog_data.operand[i]) == MULT
2897                || GET_CODE (recog_data.operand[i]) == MEM)
2898         recog_data.operand[i] = walk_alter_subreg (recog_data.operand[i]);
2899     }
2900
2901   for (i = 0; i < recog_data.n_dups; i++)
2902     {
2903       if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
2904         *recog_data.dup_loc[i] = alter_subreg (*recog_data.dup_loc[i]);
2905       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
2906                || GET_CODE (*recog_data.dup_loc[i]) == MULT
2907                || GET_CODE (*recog_data.dup_loc[i]) == MEM)
2908         *recog_data.dup_loc[i] = walk_alter_subreg (*recog_data.dup_loc[i]);
2909     }
2910 }
2911
2912 /* If X is a SUBREG, replace it with a REG or a MEM,
2913    based on the thing it is a subreg of.  */
2914
2915 rtx
2916 alter_subreg (x)
2917      register rtx x;
2918 {
2919   register rtx y = SUBREG_REG (x);
2920
2921   if (GET_CODE (y) == SUBREG)
2922     y = alter_subreg (y);
2923
2924   /* If reload is operating, we may be replacing inside this SUBREG.
2925      Check for that and make a new one if so.  */
2926   if (reload_in_progress && find_replacement (&SUBREG_REG (x)) != 0)
2927     x = copy_rtx (x);
2928
2929   if (GET_CODE (y) == REG)
2930     {
2931       int regno = subreg_hard_regno (x, 1);
2932
2933       PUT_CODE (x, REG);
2934       REGNO (x) = regno;
2935       ORIGINAL_REGNO (x) = ORIGINAL_REGNO (y);
2936       /* This field has a different meaning for REGs and SUBREGs.  Make sure
2937          to clear it!  */
2938       x->used = 0;
2939     }
2940   else if (GET_CODE (y) == MEM)
2941     {
2942       HOST_WIDE_INT offset = SUBREG_BYTE (x);
2943
2944       /* Catch these instead of generating incorrect code.  */
2945       if ((offset % GET_MODE_SIZE (GET_MODE (x))) != 0)
2946         abort ();
2947
2948       PUT_CODE (x, MEM);
2949       MEM_COPY_ATTRIBUTES (x, y);
2950       XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
2951     }
2952
2953   return x;
2954 }
2955
2956 /* Do alter_subreg on all the SUBREGs contained in X.  */
2957
2958 static rtx
2959 walk_alter_subreg (x)
2960      rtx x;
2961 {
2962   switch (GET_CODE (x))
2963     {
2964     case PLUS:
2965     case MULT:
2966       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
2967       XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1));
2968       break;
2969
2970     case MEM:
2971       XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
2972       break;
2973
2974     case SUBREG:
2975       return alter_subreg (x);
2976
2977     default:
2978       break;
2979     }
2980
2981   return x;
2982 }
2983 \f
2984 #ifdef HAVE_cc0
2985
2986 /* Given BODY, the body of a jump instruction, alter the jump condition
2987    as required by the bits that are set in cc_status.flags.
2988    Not all of the bits there can be handled at this level in all cases.
2989
2990    The value is normally 0.
2991    1 means that the condition has become always true.
2992    -1 means that the condition has become always false.
2993    2 means that COND has been altered.  */
2994
2995 static int
2996 alter_cond (cond)
2997      register rtx cond;
2998 {
2999   int value = 0;
3000
3001   if (cc_status.flags & CC_REVERSED)
3002     {
3003       value = 2;
3004       PUT_CODE (cond, swap_condition (GET_CODE (cond)));
3005     }
3006
3007   if (cc_status.flags & CC_INVERTED)
3008     {
3009       value = 2;
3010       PUT_CODE (cond, reverse_condition (GET_CODE (cond)));
3011     }
3012
3013   if (cc_status.flags & CC_NOT_POSITIVE)
3014     switch (GET_CODE (cond))
3015       {
3016       case LE:
3017       case LEU:
3018       case GEU:
3019         /* Jump becomes unconditional.  */
3020         return 1;
3021
3022       case GT:
3023       case GTU:
3024       case LTU:
3025         /* Jump becomes no-op.  */
3026         return -1;
3027
3028       case GE:
3029         PUT_CODE (cond, EQ);
3030         value = 2;
3031         break;
3032
3033       case LT:
3034         PUT_CODE (cond, NE);
3035         value = 2;
3036         break;
3037
3038       default:
3039         break;
3040       }
3041
3042   if (cc_status.flags & CC_NOT_NEGATIVE)
3043     switch (GET_CODE (cond))
3044       {
3045       case GE:
3046       case GEU:
3047         /* Jump becomes unconditional.  */
3048         return 1;
3049
3050       case LT:
3051       case LTU:
3052         /* Jump becomes no-op.  */
3053         return -1;
3054
3055       case LE:
3056       case LEU:
3057         PUT_CODE (cond, EQ);
3058         value = 2;
3059         break;
3060
3061       case GT:
3062       case GTU:
3063         PUT_CODE (cond, NE);
3064         value = 2;
3065         break;
3066
3067       default:
3068         break;
3069       }
3070
3071   if (cc_status.flags & CC_NO_OVERFLOW)
3072     switch (GET_CODE (cond))
3073       {
3074       case GEU:
3075         /* Jump becomes unconditional.  */
3076         return 1;
3077
3078       case LEU:
3079         PUT_CODE (cond, EQ);
3080         value = 2;
3081         break;
3082
3083       case GTU:
3084         PUT_CODE (cond, NE);
3085         value = 2;
3086         break;
3087
3088       case LTU:
3089         /* Jump becomes no-op.  */
3090         return -1;
3091
3092       default:
3093         break;
3094       }
3095
3096   if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N))
3097     switch (GET_CODE (cond))
3098       {
3099       default:
3100         abort ();
3101
3102       case NE:
3103         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
3104         value = 2;
3105         break;
3106
3107       case EQ:
3108         PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE);
3109         value = 2;
3110         break;
3111       }
3112
3113   if (cc_status.flags & CC_NOT_SIGNED)
3114     /* The flags are valid if signed condition operators are converted
3115        to unsigned.  */
3116     switch (GET_CODE (cond))
3117       {
3118       case LE:
3119         PUT_CODE (cond, LEU);
3120         value = 2;
3121         break;
3122
3123       case LT:
3124         PUT_CODE (cond, LTU);
3125         value = 2;
3126         break;
3127
3128       case GT:
3129         PUT_CODE (cond, GTU);
3130         value = 2;
3131         break;
3132
3133       case GE:
3134         PUT_CODE (cond, GEU);
3135         value = 2;
3136         break;
3137
3138       default:
3139         break;
3140       }
3141
3142   return value;
3143 }
3144 #endif
3145 \f
3146 /* Report inconsistency between the assembler template and the operands.
3147    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
3148
3149 void
3150 output_operand_lossage (msgid)
3151      const char *msgid;
3152 {
3153   if (this_is_asm_operands)
3154     error_for_asm (this_is_asm_operands, "invalid `asm': %s", _(msgid));
3155   else
3156     internal_error ("output_operand: %s", _(msgid));
3157 }
3158 \f
3159 /* Output of assembler code from a template, and its subroutines.  */
3160
3161 /* Output text from TEMPLATE to the assembler output file,
3162    obeying %-directions to substitute operands taken from
3163    the vector OPERANDS.
3164
3165    %N (for N a digit) means print operand N in usual manner.
3166    %lN means require operand N to be a CODE_LABEL or LABEL_REF
3167       and print the label name with no punctuation.
3168    %cN means require operand N to be a constant
3169       and print the constant expression with no punctuation.
3170    %aN means expect operand N to be a memory address
3171       (not a memory reference!) and print a reference
3172       to that address.
3173    %nN means expect operand N to be a constant
3174       and print a constant expression for minus the value
3175       of the operand, with no other punctuation.  */
3176
3177 static void
3178 output_asm_name ()
3179 {
3180   if (flag_print_asm_name)
3181     {
3182       /* Annotate the assembly with a comment describing the pattern and
3183          alternative used.  */
3184       if (debug_insn)
3185         {
3186           register int num = INSN_CODE (debug_insn);
3187           fprintf (asm_out_file, "\t%s %d\t%s",
3188                    ASM_COMMENT_START, INSN_UID (debug_insn),
3189                    insn_data[num].name);
3190           if (insn_data[num].n_alternatives > 1)
3191             fprintf (asm_out_file, "/%d", which_alternative + 1);
3192 #ifdef HAVE_ATTR_length
3193           fprintf (asm_out_file, "\t[length = %d]",
3194                    get_attr_length (debug_insn));
3195 #endif
3196           /* Clear this so only the first assembler insn
3197              of any rtl insn will get the special comment for -dp.  */
3198           debug_insn = 0;
3199         }
3200     }
3201 }
3202
3203 void
3204 output_asm_insn (template, operands)
3205      const char *template;
3206      rtx *operands;
3207 {
3208   register const char *p;
3209   register int c;
3210
3211   /* An insn may return a null string template
3212      in a case where no assembler code is needed.  */
3213   if (*template == 0)
3214     return;
3215
3216   p = template;
3217   putc ('\t', asm_out_file);
3218
3219 #ifdef ASM_OUTPUT_OPCODE
3220   ASM_OUTPUT_OPCODE (asm_out_file, p);
3221 #endif
3222
3223   while ((c = *p++))
3224     switch (c)
3225       {
3226       case '\n':
3227         output_asm_name ();
3228         putc (c, asm_out_file);
3229 #ifdef ASM_OUTPUT_OPCODE
3230         while ((c = *p) == '\t')
3231           {
3232             putc (c, asm_out_file);
3233             p++;
3234           }
3235         ASM_OUTPUT_OPCODE (asm_out_file, p);
3236 #endif
3237         break;
3238
3239 #ifdef ASSEMBLER_DIALECT
3240       case '{':
3241         {
3242           register int i;
3243
3244           /* If we want the first dialect, do nothing.  Otherwise, skip
3245              DIALECT_NUMBER of strings ending with '|'.  */
3246           for (i = 0; i < dialect_number; i++)
3247             {
3248               while (*p && *p != '}' && *p++ != '|')
3249                 ;
3250               if (*p == '}')
3251                 break;
3252               if (*p == '|')
3253                 p++;
3254             }
3255         }
3256         break;
3257
3258       case '|':
3259         /* Skip to close brace.  */
3260         while (*p && *p++ != '}')
3261           ;
3262         break;
3263
3264       case '}':
3265         break;
3266 #endif
3267
3268       case '%':
3269         /* %% outputs a single %.  */
3270         if (*p == '%')
3271           {
3272             p++;
3273             putc (c, asm_out_file);
3274           }
3275         /* %= outputs a number which is unique to each insn in the entire
3276            compilation.  This is useful for making local labels that are
3277            referred to more than once in a given insn.  */
3278         else if (*p == '=')
3279           {
3280             p++;
3281             fprintf (asm_out_file, "%d", insn_counter);
3282           }
3283         /* % followed by a letter and some digits
3284            outputs an operand in a special way depending on the letter.
3285            Letters `acln' are implemented directly.
3286            Other letters are passed to `output_operand' so that
3287            the PRINT_OPERAND macro can define them.  */
3288         else if (ISLOWER (*p) || ISUPPER (*p))
3289           {
3290             int letter = *p++;
3291             c = atoi (p);
3292
3293             if (! (*p >= '0' && *p <= '9'))
3294               output_operand_lossage ("operand number missing after %-letter");
3295             else if (this_is_asm_operands && (c < 0 || (unsigned int) c >= insn_noperands))
3296               output_operand_lossage ("operand number out of range");
3297             else if (letter == 'l')
3298               output_asm_label (operands[c]);
3299             else if (letter == 'a')
3300               output_address (operands[c]);
3301             else if (letter == 'c')
3302               {
3303                 if (CONSTANT_ADDRESS_P (operands[c]))
3304                   output_addr_const (asm_out_file, operands[c]);
3305                 else
3306                   output_operand (operands[c], 'c');
3307               }
3308             else if (letter == 'n')
3309               {
3310                 if (GET_CODE (operands[c]) == CONST_INT)
3311                   fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
3312                            - INTVAL (operands[c]));
3313                 else
3314                   {
3315                     putc ('-', asm_out_file);
3316                     output_addr_const (asm_out_file, operands[c]);
3317                   }
3318               }
3319             else
3320               output_operand (operands[c], letter);
3321
3322             while ((c = *p) >= '0' && c <= '9')
3323               p++;
3324           }
3325         /* % followed by a digit outputs an operand the default way.  */
3326         else if (*p >= '0' && *p <= '9')
3327           {
3328             c = atoi (p);
3329             if (this_is_asm_operands
3330                 && (c < 0 || (unsigned int) c >= insn_noperands))
3331               output_operand_lossage ("operand number out of range");
3332             else
3333               output_operand (operands[c], 0);
3334             while ((c = *p) >= '0' && c <= '9')
3335               p++;
3336           }
3337         /* % followed by punctuation: output something for that
3338            punctuation character alone, with no operand.
3339            The PRINT_OPERAND macro decides what is actually done.  */
3340 #ifdef PRINT_OPERAND_PUNCT_VALID_P
3341         else if (PRINT_OPERAND_PUNCT_VALID_P ((unsigned char) *p))
3342           output_operand (NULL_RTX, *p++);
3343 #endif
3344         else
3345           output_operand_lossage ("invalid %%-code");
3346         break;
3347
3348       default:
3349         putc (c, asm_out_file);
3350       }
3351
3352   output_asm_name ();
3353
3354   putc ('\n', asm_out_file);
3355 }
3356 \f
3357 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
3358
3359 void
3360 output_asm_label (x)
3361      rtx x;
3362 {
3363   char buf[256];
3364
3365   if (GET_CODE (x) == LABEL_REF)
3366     x = XEXP (x, 0);
3367   if (GET_CODE (x) == CODE_LABEL
3368       || (GET_CODE (x) == NOTE
3369           && NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
3370     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
3371   else
3372     output_operand_lossage ("`%l' operand isn't a label");
3373
3374   assemble_name (asm_out_file, buf);
3375 }
3376
3377 /* Print operand X using machine-dependent assembler syntax.
3378    The macro PRINT_OPERAND is defined just to control this function.
3379    CODE is a non-digit that preceded the operand-number in the % spec,
3380    such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char
3381    between the % and the digits.
3382    When CODE is a non-letter, X is 0.
3383
3384    The meanings of the letters are machine-dependent and controlled
3385    by PRINT_OPERAND.  */
3386
3387 static void
3388 output_operand (x, code)
3389      rtx x;
3390      int code ATTRIBUTE_UNUSED;
3391 {
3392   if (x && GET_CODE (x) == SUBREG)
3393     x = alter_subreg (x);
3394
3395   /* If X is a pseudo-register, abort now rather than writing trash to the
3396      assembler file.  */
3397
3398   if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
3399     abort ();
3400
3401   PRINT_OPERAND (asm_out_file, x, code);
3402 }
3403
3404 /* Print a memory reference operand for address X
3405    using machine-dependent assembler syntax.
3406    The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */
3407
3408 void
3409 output_address (x)
3410      rtx x;
3411 {
3412   walk_alter_subreg (x);
3413   PRINT_OPERAND_ADDRESS (asm_out_file, x);
3414 }
3415 \f
3416 /* Print an integer constant expression in assembler syntax.
3417    Addition and subtraction are the only arithmetic
3418    that may appear in these expressions.  */
3419
3420 void
3421 output_addr_const (file, x)
3422      FILE *file;
3423      rtx x;
3424 {
3425   char buf[256];
3426
3427  restart:
3428   switch (GET_CODE (x))
3429     {
3430     case PC:
3431       if (flag_pic)
3432         putc ('.', file);
3433       else
3434         abort ();
3435       break;
3436
3437     case SYMBOL_REF:
3438 #ifdef ASM_OUTPUT_SYMBOL_REF
3439       ASM_OUTPUT_SYMBOL_REF (file, x);
3440 #else
3441       assemble_name (file, XSTR (x, 0));
3442 #endif
3443       break;
3444
3445     case LABEL_REF:
3446       x = XEXP (x, 0);
3447       /* Fall through.  */
3448     case CODE_LABEL:
3449       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
3450       assemble_name (file, buf);
3451       break;
3452
3453     case CONST_INT:
3454       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3455       break;
3456
3457     case CONST:
3458       /* This used to output parentheses around the expression,
3459          but that does not work on the 386 (either ATT or BSD assembler).  */
3460       output_addr_const (file, XEXP (x, 0));
3461       break;
3462
3463     case CONST_DOUBLE:
3464       if (GET_MODE (x) == VOIDmode)
3465         {
3466           /* We can use %d if the number is one word and positive.  */
3467           if (CONST_DOUBLE_HIGH (x))
3468             fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
3469                      CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
3470           else if (CONST_DOUBLE_LOW (x) < 0)
3471             fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
3472           else
3473             fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
3474         }
3475       else
3476         /* We can't handle floating point constants;
3477            PRINT_OPERAND must handle them.  */
3478         output_operand_lossage ("floating constant misused");
3479       break;
3480
3481     case PLUS:
3482       /* Some assemblers need integer constants to appear last (eg masm).  */
3483       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3484         {
3485           output_addr_const (file, XEXP (x, 1));
3486           if (INTVAL (XEXP (x, 0)) >= 0)
3487             fprintf (file, "+");
3488           output_addr_const (file, XEXP (x, 0));
3489         }
3490       else
3491         {
3492           output_addr_const (file, XEXP (x, 0));
3493           if (GET_CODE (XEXP (x, 1)) != CONST_INT
3494               || INTVAL (XEXP (x, 1)) >= 0)
3495             fprintf (file, "+");
3496           output_addr_const (file, XEXP (x, 1));
3497         }
3498       break;
3499
3500     case MINUS:
3501       /* Avoid outputting things like x-x or x+5-x,
3502          since some assemblers can't handle that.  */
3503       x = simplify_subtraction (x);
3504       if (GET_CODE (x) != MINUS)
3505         goto restart;
3506
3507       output_addr_const (file, XEXP (x, 0));
3508       fprintf (file, "-");
3509       if ((GET_CODE (XEXP (x, 1)) == CONST_INT
3510            && INTVAL (XEXP (x, 1)) < 0)
3511           || GET_CODE (XEXP (x, 1)) != CONST_INT)
3512         {
3513           fputs (targetm.asm_out.open_paren, file);
3514           output_addr_const (file, XEXP (x, 1));
3515           fputs (targetm.asm_out.close_paren, file);
3516         }
3517       else
3518         output_addr_const (file, XEXP (x, 1));
3519       break;
3520
3521     case ZERO_EXTEND:
3522     case SIGN_EXTEND:
3523       output_addr_const (file, XEXP (x, 0));
3524       break;
3525
3526     default:
3527 #ifdef OUTPUT_ADDR_CONST_EXTRA
3528       OUTPUT_ADDR_CONST_EXTRA (file, x, fail);
3529       break;
3530
3531     fail:
3532 #endif
3533       output_operand_lossage ("invalid expression as operand");
3534     }
3535 }
3536 \f
3537 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
3538    %R prints the value of REGISTER_PREFIX.
3539    %L prints the value of LOCAL_LABEL_PREFIX.
3540    %U prints the value of USER_LABEL_PREFIX.
3541    %I prints the value of IMMEDIATE_PREFIX.
3542    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
3543    Also supported are %d, %x, %s, %e, %f, %g and %%.
3544
3545    We handle alternate assembler dialects here, just like output_asm_insn.  */
3546
3547 void
3548 asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
3549 {
3550 #ifndef ANSI_PROTOTYPES
3551   FILE *file;
3552   const char *p;
3553 #endif
3554   va_list argptr;
3555   char buf[10];
3556   char *q, c;
3557
3558   VA_START (argptr, p);
3559
3560 #ifndef ANSI_PROTOTYPES
3561   file = va_arg (argptr, FILE *);
3562   p = va_arg (argptr, const char *);
3563 #endif
3564
3565   buf[0] = '%';
3566
3567   while ((c = *p++))
3568     switch (c)
3569       {
3570 #ifdef ASSEMBLER_DIALECT
3571       case '{':
3572         {
3573           int i;
3574
3575           /* If we want the first dialect, do nothing.  Otherwise, skip
3576              DIALECT_NUMBER of strings ending with '|'.  */
3577           for (i = 0; i < dialect_number; i++)
3578             {
3579               while (*p && *p++ != '|')
3580                 ;
3581
3582               if (*p == '|')
3583                 p++;
3584             }
3585         }
3586         break;
3587
3588       case '|':
3589         /* Skip to close brace.  */
3590         while (*p && *p++ != '}')
3591           ;
3592         break;
3593
3594       case '}':
3595         break;
3596 #endif
3597
3598       case '%':
3599         c = *p++;
3600         q = &buf[1];
3601         while ((c >= '0' && c <= '9') || c == '.')
3602           {
3603             *q++ = c;
3604             c = *p++;
3605           }
3606         switch (c)
3607           {
3608           case '%':
3609             fprintf (file, "%%");
3610             break;
3611
3612           case 'd':  case 'i':  case 'u':
3613           case 'x':  case 'p':  case 'X':
3614           case 'o':
3615             *q++ = c;
3616             *q = 0;
3617             fprintf (file, buf, va_arg (argptr, int));
3618             break;
3619
3620           case 'w':
3621             /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases,
3622                but we do not check for those cases.  It means that the value
3623                is a HOST_WIDE_INT, which may be either `int' or `long'.  */
3624
3625 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
3626 #else
3627 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
3628             *q++ = 'l';
3629 #else
3630             *q++ = 'l';
3631             *q++ = 'l';
3632 #endif
3633 #endif
3634
3635             *q++ = *p++;
3636             *q = 0;
3637             fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
3638             break;
3639
3640           case 'l':
3641             *q++ = c;
3642             *q++ = *p++;
3643             *q = 0;
3644             fprintf (file, buf, va_arg (argptr, long));
3645             break;
3646
3647           case 'e':
3648           case 'f':
3649           case 'g':
3650             *q++ = c;
3651             *q = 0;
3652             fprintf (file, buf, va_arg (argptr, double));
3653             break;
3654
3655           case 's':
3656             *q++ = c;
3657             *q = 0;
3658             fprintf (file, buf, va_arg (argptr, char *));
3659             break;
3660
3661           case 'O':
3662 #ifdef ASM_OUTPUT_OPCODE
3663             ASM_OUTPUT_OPCODE (asm_out_file, p);
3664 #endif
3665             break;
3666
3667           case 'R':
3668 #ifdef REGISTER_PREFIX
3669             fprintf (file, "%s", REGISTER_PREFIX);
3670 #endif
3671             break;
3672
3673           case 'I':
3674 #ifdef IMMEDIATE_PREFIX
3675             fprintf (file, "%s", IMMEDIATE_PREFIX);
3676 #endif
3677             break;
3678
3679           case 'L':
3680 #ifdef LOCAL_LABEL_PREFIX
3681             fprintf (file, "%s", LOCAL_LABEL_PREFIX);
3682 #endif
3683             break;
3684
3685           case 'U':
3686             fputs (user_label_prefix, file);
3687             break;
3688
3689 #ifdef ASM_FPRINTF_EXTENSIONS
3690             /* Upper case letters are reserved for general use by asm_fprintf
3691                and so are not available to target specific code.  In order to
3692                prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
3693                they are defined here.  As they get turned into real extensions
3694                to asm_fprintf they should be removed from this list.  */
3695           case 'A': case 'B': case 'C': case 'D': case 'E':
3696           case 'F': case 'G': case 'H': case 'J': case 'K':
3697           case 'M': case 'N': case 'P': case 'Q': case 'S':
3698           case 'T': case 'V': case 'W': case 'Y': case 'Z':
3699             break;
3700
3701           ASM_FPRINTF_EXTENSIONS (file, argptr, p)
3702 #endif
3703           default:
3704             abort ();
3705           }
3706         break;
3707
3708       default:
3709         fputc (c, file);
3710       }
3711   va_end (argptr);
3712 }
3713 \f
3714 /* Split up a CONST_DOUBLE or integer constant rtx
3715    into two rtx's for single words,
3716    storing in *FIRST the word that comes first in memory in the target
3717    and in *SECOND the other.  */
3718
3719 void
3720 split_double (value, first, second)
3721      rtx value;
3722      rtx *first, *second;
3723 {
3724   if (GET_CODE (value) == CONST_INT)
3725     {
3726       if (HOST_BITS_PER_WIDE_INT >= (2 * BITS_PER_WORD))
3727         {
3728           /* In this case the CONST_INT holds both target words.
3729              Extract the bits from it into two word-sized pieces.
3730              Sign extend each half to HOST_WIDE_INT.  */
3731           unsigned HOST_WIDE_INT low, high;
3732           unsigned HOST_WIDE_INT mask, sign_bit, sign_extend;
3733
3734           /* Set sign_bit to the most significant bit of a word.  */
3735           sign_bit = 1;
3736           sign_bit <<= BITS_PER_WORD - 1;
3737
3738           /* Set mask so that all bits of the word are set.  We could
3739              have used 1 << BITS_PER_WORD instead of basing the
3740              calculation on sign_bit.  However, on machines where
3741              HOST_BITS_PER_WIDE_INT == BITS_PER_WORD, it could cause a
3742              compiler warning, even though the code would never be
3743              executed.  */
3744           mask = sign_bit << 1;
3745           mask--;
3746
3747           /* Set sign_extend as any remaining bits.  */
3748           sign_extend = ~mask;
3749
3750           /* Pick the lower word and sign-extend it.  */
3751           low = INTVAL (value);
3752           low &= mask;
3753           if (low & sign_bit)
3754             low |= sign_extend;
3755
3756           /* Pick the higher word, shifted to the least significant
3757              bits, and sign-extend it.  */
3758           high = INTVAL (value);
3759           high >>= BITS_PER_WORD - 1;
3760           high >>= 1;
3761           high &= mask;
3762           if (high & sign_bit)
3763             high |= sign_extend;
3764
3765           /* Store the words in the target machine order.  */
3766           if (WORDS_BIG_ENDIAN)
3767             {
3768               *first = GEN_INT (high);
3769               *second = GEN_INT (low);
3770             }
3771           else
3772             {
3773               *first = GEN_INT (low);
3774               *second = GEN_INT (high);
3775             }
3776         }
3777       else
3778         {
3779           /* The rule for using CONST_INT for a wider mode
3780              is that we regard the value as signed.
3781              So sign-extend it.  */
3782           rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx);
3783           if (WORDS_BIG_ENDIAN)
3784             {
3785               *first = high;
3786               *second = value;
3787             }
3788           else
3789             {
3790               *first = value;
3791               *second = high;
3792             }
3793         }
3794     }
3795   else if (GET_CODE (value) != CONST_DOUBLE)
3796     {
3797       if (WORDS_BIG_ENDIAN)
3798         {
3799           *first = const0_rtx;
3800           *second = value;
3801         }
3802       else
3803         {
3804           *first = value;
3805           *second = const0_rtx;
3806         }
3807     }
3808   else if (GET_MODE (value) == VOIDmode
3809            /* This is the old way we did CONST_DOUBLE integers.  */
3810            || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT)
3811     {
3812       /* In an integer, the words are defined as most and least significant.
3813          So order them by the target's convention.  */
3814       if (WORDS_BIG_ENDIAN)
3815         {
3816           *first = GEN_INT (CONST_DOUBLE_HIGH (value));
3817           *second = GEN_INT (CONST_DOUBLE_LOW (value));
3818         }
3819       else
3820         {
3821           *first = GEN_INT (CONST_DOUBLE_LOW (value));
3822           *second = GEN_INT (CONST_DOUBLE_HIGH (value));
3823         }
3824     }
3825   else
3826     {
3827 #ifdef REAL_ARITHMETIC
3828       REAL_VALUE_TYPE r;
3829       long l[2];
3830       REAL_VALUE_FROM_CONST_DOUBLE (r, value);
3831
3832       /* Note, this converts the REAL_VALUE_TYPE to the target's
3833          format, splits up the floating point double and outputs
3834          exactly 32 bits of it into each of l[0] and l[1] --
3835          not necessarily BITS_PER_WORD bits.  */
3836       REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3837
3838       /* If 32 bits is an entire word for the target, but not for the host,
3839          then sign-extend on the host so that the number will look the same
3840          way on the host that it would on the target.  See for instance
3841          simplify_unary_operation.  The #if is needed to avoid compiler
3842          warnings.  */
3843
3844 #if HOST_BITS_PER_LONG > 32
3845       if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32)
3846         {
3847           if (l[0] & ((long) 1 << 31))
3848             l[0] |= ((long) (-1) << 32);
3849           if (l[1] & ((long) 1 << 31))
3850             l[1] |= ((long) (-1) << 32);
3851         }
3852 #endif
3853
3854       *first = GEN_INT ((HOST_WIDE_INT) l[0]);
3855       *second = GEN_INT ((HOST_WIDE_INT) l[1]);
3856 #else
3857       if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
3858            || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
3859           && ! flag_pretend_float)
3860         abort ();
3861
3862       if (
3863 #ifdef HOST_WORDS_BIG_ENDIAN
3864           WORDS_BIG_ENDIAN
3865 #else
3866           ! WORDS_BIG_ENDIAN
3867 #endif
3868           )
3869         {
3870           /* Host and target agree => no need to swap.  */
3871           *first = GEN_INT (CONST_DOUBLE_LOW (value));
3872           *second = GEN_INT (CONST_DOUBLE_HIGH (value));
3873         }
3874       else
3875         {
3876           *second = GEN_INT (CONST_DOUBLE_LOW (value));
3877           *first = GEN_INT (CONST_DOUBLE_HIGH (value));
3878         }
3879 #endif /* no REAL_ARITHMETIC */
3880     }
3881 }
3882 \f
3883 /* Return nonzero if this function has no function calls.  */
3884
3885 int
3886 leaf_function_p ()
3887 {
3888   rtx insn;
3889   rtx link;
3890
3891   if (profile_flag || profile_block_flag || profile_arc_flag)
3892     return 0;
3893
3894   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3895     {
3896       if (GET_CODE (insn) == CALL_INSN
3897           && ! SIBLING_CALL_P (insn))
3898         return 0;
3899       if (GET_CODE (insn) == INSN
3900           && GET_CODE (PATTERN (insn)) == SEQUENCE
3901           && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN
3902           && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
3903         return 0;
3904     }
3905   for (link = current_function_epilogue_delay_list;
3906        link;
3907        link = XEXP (link, 1))
3908     {
3909       insn = XEXP (link, 0);
3910
3911       if (GET_CODE (insn) == CALL_INSN
3912           && ! SIBLING_CALL_P (insn))
3913         return 0;
3914       if (GET_CODE (insn) == INSN
3915           && GET_CODE (PATTERN (insn)) == SEQUENCE
3916           && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN
3917           && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
3918         return 0;
3919     }
3920
3921   return 1;
3922 }
3923
3924 /* Return 1 if branch is an forward branch.
3925    Uses insn_shuid array, so it works only in the final pass.  May be used by
3926    output templates to customary add branch prediction hints.
3927  */
3928 int
3929 final_forward_branch_p (insn)
3930      rtx insn;
3931 {
3932   int insn_id, label_id;
3933   if (!uid_shuid)
3934     abort ();
3935   insn_id = INSN_SHUID (insn);
3936   label_id = INSN_SHUID (JUMP_LABEL (insn));
3937   /* We've hit some insns that does not have id information available.  */
3938   if (!insn_id || !label_id)
3939     abort ();
3940   return insn_id < label_id;
3941 }
3942
3943 /* On some machines, a function with no call insns
3944    can run faster if it doesn't create its own register window.
3945    When output, the leaf function should use only the "output"
3946    registers.  Ordinarily, the function would be compiled to use
3947    the "input" registers to find its arguments; it is a candidate
3948    for leaf treatment if it uses only the "input" registers.
3949    Leaf function treatment means renumbering so the function
3950    uses the "output" registers instead.  */
3951
3952 #ifdef LEAF_REGISTERS
3953
3954 /* Return 1 if this function uses only the registers that can be
3955    safely renumbered.  */
3956
3957 int
3958 only_leaf_regs_used ()
3959 {
3960   int i;
3961   char *permitted_reg_in_leaf_functions = LEAF_REGISTERS;
3962
3963   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3964     if ((regs_ever_live[i] || global_regs[i])
3965         && ! permitted_reg_in_leaf_functions[i])
3966       return 0;
3967
3968   if (current_function_uses_pic_offset_table
3969       && pic_offset_table_rtx != 0
3970       && GET_CODE (pic_offset_table_rtx) == REG
3971       && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
3972     return 0;
3973
3974   return 1;
3975 }
3976
3977 /* Scan all instructions and renumber all registers into those
3978    available in leaf functions.  */
3979
3980 static void
3981 leaf_renumber_regs (first)
3982      rtx first;
3983 {
3984   rtx insn;
3985
3986   /* Renumber only the actual patterns.
3987      The reg-notes can contain frame pointer refs,
3988      and renumbering them could crash, and should not be needed.  */
3989   for (insn = first; insn; insn = NEXT_INSN (insn))
3990     if (INSN_P (insn))
3991       leaf_renumber_regs_insn (PATTERN (insn));
3992   for (insn = current_function_epilogue_delay_list;
3993        insn;
3994        insn = XEXP (insn, 1))
3995     if (INSN_P (XEXP (insn, 0)))
3996       leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0)));
3997 }
3998
3999 /* Scan IN_RTX and its subexpressions, and renumber all regs into those
4000    available in leaf functions.  */
4001
4002 void
4003 leaf_renumber_regs_insn (in_rtx)
4004      register rtx in_rtx;
4005 {
4006   register int i, j;
4007   register const char *format_ptr;
4008
4009   if (in_rtx == 0)
4010     return;
4011
4012   /* Renumber all input-registers into output-registers.
4013      renumbered_regs would be 1 for an output-register;
4014      they  */
4015
4016   if (GET_CODE (in_rtx) == REG)
4017     {
4018       int newreg;
4019
4020       /* Don't renumber the same reg twice.  */
4021       if (in_rtx->used)
4022         return;
4023
4024       newreg = REGNO (in_rtx);
4025       /* Don't try to renumber pseudo regs.  It is possible for a pseudo reg
4026          to reach here as part of a REG_NOTE.  */
4027       if (newreg >= FIRST_PSEUDO_REGISTER)
4028         {
4029           in_rtx->used = 1;
4030           return;
4031         }
4032       newreg = LEAF_REG_REMAP (newreg);
4033       if (newreg < 0)
4034         abort ();
4035       regs_ever_live[REGNO (in_rtx)] = 0;
4036       regs_ever_live[newreg] = 1;
4037       REGNO (in_rtx) = newreg;
4038       in_rtx->used = 1;
4039     }
4040
4041   if (INSN_P (in_rtx))
4042     {
4043       /* Inside a SEQUENCE, we find insns.
4044          Renumber just the patterns of these insns,
4045          just as we do for the top-level insns.  */
4046       leaf_renumber_regs_insn (PATTERN (in_rtx));
4047       return;
4048     }
4049
4050   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
4051
4052   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
4053     switch (*format_ptr++)
4054       {
4055       case 'e':
4056         leaf_renumber_regs_insn (XEXP (in_rtx, i));
4057         break;
4058
4059       case 'E':
4060         if (NULL != XVEC (in_rtx, i))
4061           {
4062             for (j = 0; j < XVECLEN (in_rtx, i); j++)
4063               leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
4064           }
4065         break;
4066
4067       case 'S':
4068       case 's':
4069       case '0':
4070       case 'i':
4071       case 'w':
4072       case 'n':
4073       case 'u':
4074         break;
4075
4076       default:
4077         abort ();
4078       }
4079 }
4080 #endif