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