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