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