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