]> 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;
1031 else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
1032 {
1033 /* Another note follows; we can delete this note provided
1034 no intervening line numbers have notes elsewhere. */
1035 int num;
1036 for (num = NOTE_LINE_NUMBER (insn) + 1;
1037 num < NOTE_LINE_NUMBER (note);
1038 num++)
1039 if (line_note_exists[num])
1040 break;
1041
1042 if (num == NOTE_LINE_NUMBER (note))
1043 note_after = 1;
1044 break;
1045 }
1046 }
1047
1048 /* Output this line note
1049 if it is the first or the last line note in a row. */
1050 if (!note_after)
1051 output_source_line (file, insn);
1052 }
1053 break;
1054
1055 case BARRIER:
1056#ifdef ASM_OUTPUT_ALIGN_CODE
1057 ASM_OUTPUT_ALIGN_CODE (file);
1058#endif
1059 break;
1060
1061 case CODE_LABEL:
1062 CC_STATUS_INIT;
1063 if (prescan > 0)
1064 break;
1065 new_block = 1;
1066#ifdef SDB_DEBUGGING_INFO
1067 if (write_symbols == SDB_DEBUG && LABEL_NAME (insn))
1068 sdbout_label (insn);
1069#endif
1070#ifdef DWARF_DEBUGGING_INFO
1071 if (write_symbols == DWARF_DEBUG && LABEL_NAME (insn))
1072 dwarfout_label (insn);
1073#endif
1074 if (app_on)
1075 {
1076 fprintf (file, ASM_APP_OFF);
1077 app_on = 0;
1078 }
1079 if (NEXT_INSN (insn) != 0
1080 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
1081 {
1082 rtx nextbody = PATTERN (NEXT_INSN (insn));
1083
1084 /* If this label is followed by a jump-table,
1085 make sure we put the label in the read-only section. Also
1086 possibly write the label and jump table together. */
1087
1088 if (GET_CODE (nextbody) == ADDR_VEC
1089 || GET_CODE (nextbody) == ADDR_DIFF_VEC)
1090 {
1091#ifndef JUMP_TABLES_IN_TEXT_SECTION
1092 readonly_data_section ();
1093#else
1094 text_section ();
1095#endif
1096#ifdef ASM_OUTPUT_CASE_LABEL
1097 ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
1098 NEXT_INSN (insn));
1099#else
1100 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
1101#endif
1102 break;
1103 }
1104 }
1105
1106 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
1107 break;
1108
1109 default:
1110 {
1111 register rtx body = PATTERN (insn);
1112 int insn_code_number;
1113 char *template;
1114 rtx note;
1115
1116 /* An INSN, JUMP_INSN or CALL_INSN.
1117 First check for special kinds that recog doesn't recognize. */
1118
1119 if (GET_CODE (body) == USE /* These are just declarations */
1120 || GET_CODE (body) == CLOBBER)
1121 break;
1122
1123#ifdef HAVE_cc0
1124 /* If there is a REG_CC_SETTER note on this insn, it means that
1125 the setting of the condition code was done in the delay slot
1126 of the insn that branched here. So recover the cc status
1127 from the insn that set it. */
1128
1129 note = find_reg_note (insn, REG_CC_SETTER, 0);
1130 if (note)
1131 {
1132 NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));
1133 cc_prev_status = cc_status;
1134 }
1135#endif
1136
1137 /* Detect insns that are really jump-tables
1138 and output them as such. */
1139
1140 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
1141 {
1142 register int vlen, idx;
1143
1144 if (prescan > 0)
1145 break;
1146
1147 if (app_on)
1148 {
1149 fprintf (file, ASM_APP_OFF);
1150 app_on = 0;
1151 }
1152
1153 vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
1154 for (idx = 0; idx < vlen; idx++)
1155 {
1156 if (GET_CODE (body) == ADDR_VEC)
1157 ASM_OUTPUT_ADDR_VEC_ELT
1158 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
1159 else
1160 ASM_OUTPUT_ADDR_DIFF_ELT
1161 (file,
1162 CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
1163 CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
1164 }
1165#ifdef ASM_OUTPUT_CASE_END
1166 ASM_OUTPUT_CASE_END (file,
1167 CODE_LABEL_NUMBER (PREV_INSN (insn)),
1168 insn);
1169#endif
1170
1171 text_section ();
1172
1173 break;
1174 }
1175
1176 /* Do basic-block profiling when we reach a new block.
1177 Done here to avoid jump tables. */
1178 if (profile_block_flag && new_block)
1179 {
1180 new_block = 0;
1181 /* Enable the table of basic-block use counts
1182 to point at the code it applies to. */
1183 ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);
1184 /* Before first insn of this basic block, increment the
1185 count of times it was entered. */
1186#ifdef BLOCK_PROFILER
1187 BLOCK_PROFILER (file, count_basic_blocks);
1188 CC_STATUS_INIT;
1189#endif
1190 count_basic_blocks++;
1191 }
1192
1193 if (GET_CODE (body) == ASM_INPUT)
1194 {
1195 /* There's no telling what that did to the condition codes. */
1196 CC_STATUS_INIT;
1197 if (prescan > 0)
1198 break;
1199 if (! app_on)
1200 {
1201 fprintf (file, ASM_APP_ON);
1202 app_on = 1;
1203 }
1204 fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));
1205 break;
1206 }
1207
1208 /* Detect `asm' construct with operands. */
1209 if (asm_noperands (body) >= 0)
1210 {
1211 int noperands = asm_noperands (body);
1212 rtx *ops;
1213 char *string;
1214
1215 /* There's no telling what that did to the condition codes. */
1216 CC_STATUS_INIT;
1217 if (prescan > 0)
1218 break;
1219
1220 /* alloca won't do here, since only return from `final'
1221 would free it. */
1222 if (noperands > 0)
1223 ops = (rtx *) xmalloc (noperands * sizeof (rtx));
1224
1225 if (! app_on)
1226 {
1227 fprintf (file, ASM_APP_ON);
1228 app_on = 1;
1229 }
1230
1231 /* Get out the operand values. */
1232 string = decode_asm_operands (body, ops, 0, 0, 0);
1233 /* Inhibit aborts on what would otherwise be compiler bugs. */
1234 insn_noperands = noperands;
1235 this_is_asm_operands = insn;
1236 /* Output the insn using them. */
1237 output_asm_insn (string, ops);
1238 this_is_asm_operands = 0;
1239 if (noperands > 0)
1240 free (ops);
1241 break;
1242 }
1243
1244 if (prescan <= 0 && app_on)
1245 {
1246 fprintf (file, ASM_APP_OFF);
1247 app_on = 0;
1248 }
1249
1250 if (GET_CODE (body) == SEQUENCE)
1251 {
1252 /* A delayed-branch sequence */
1253 register int i;
1254 rtx next;
1255
1256 if (prescan > 0)
1257 break;
1258 final_sequence = body;
1259
1260 /* The first insn in this SEQUENCE might be a JUMP_INSN that will
1261 force the restoration of a comparison that was previously
1262 thought unnecessary. If that happens, cancel this sequence
1263 and cause that insn to be restored. */
1264
1265 next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);
1266 if (next != XVECEXP (body, 0, 1))
1267 {
1268 final_sequence = 0;
1269 return next;
1270 }
1271
1272 for (i = 1; i < XVECLEN (body, 0); i++)
1273 final_scan_insn (XVECEXP (body, 0, i), file, 0, prescan, 1);
1274#ifdef DBR_OUTPUT_SEQEND
1275 DBR_OUTPUT_SEQEND (file);
1276#endif
1277 final_sequence = 0;
1278
1279 /* If the insn requiring the delay slot was a CALL_INSN, the
1280 insns in the delay slot are actually executed before the
1281 called function. Hence we don't preserve any CC-setting
1282 actions in these insns and the CC must be marked as being
1283 clobbered by the function. */
1284 if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)
1285 CC_STATUS_INIT;
ee668edc
RS
1286
1287 /* Following a conditional branch sequence, we have a new basic
1288 block. */
1289 if (profile_block_flag)
1290 {
1291 rtx insn = XVECEXP (body, 0, 0);
1292 rtx body = PATTERN (insn);
1293
1294 if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
1295 && GET_CODE (SET_SRC (body)) != LABEL_REF)
1296 || (GET_CODE (insn) == JUMP_INSN
1297 && GET_CODE (body) == PARALLEL
1298 && GET_CODE (XVECEXP (body, 0, 0)) == SET
1299 && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))
1300 new_block = 1;
1301 }
a130a441
MM
1302 break;
1303 }
1304
1305 /* We have a real machine instruction as rtl. */
1306
1307 body = PATTERN (insn);
1308
1309#ifdef HAVE_cc0
1310 /* Check for redundant test and compare instructions
1311 (when the condition codes are already set up as desired).
1312 This is done only when optimizing; if not optimizing,
1313 it should be possible for the user to alter a variable
1314 with the debugger in between statements
1315 and the next statement should reexamine the variable
1316 to compute the condition codes. */
1317
1318 if (optimize
1319 && GET_CODE (body) == SET
1320 && GET_CODE (SET_DEST (body)) == CC0
1321 && insn != last_ignored_compare)
1322 {
1323 if (GET_CODE (SET_SRC (body)) == SUBREG)
1324 SET_SRC (body) = alter_subreg (SET_SRC (body));
1325 else if (GET_CODE (SET_SRC (body)) == COMPARE)
1326 {
1327 if (GET_CODE (XEXP (SET_SRC (body), 0)) == SUBREG)
1328 XEXP (SET_SRC (body), 0)
1329 = alter_subreg (XEXP (SET_SRC (body), 0));
1330 if (GET_CODE (XEXP (SET_SRC (body), 1)) == SUBREG)
1331 XEXP (SET_SRC (body), 1)
1332 = alter_subreg (XEXP (SET_SRC (body), 1));
1333 }
1334 if ((cc_status.value1 != 0
1335 && rtx_equal_p (SET_SRC (body), cc_status.value1))
1336 || (cc_status.value2 != 0
1337 && rtx_equal_p (SET_SRC (body), cc_status.value2)))
1338 {
1339 /* Don't delete insn if it has an addressing side-effect. */
1340 if (! FIND_REG_INC_NOTE (insn, 0)
1341 /* or if anything in it is volatile. */
1342 && ! volatile_refs_p (PATTERN (insn)))
1343 {
1344 /* We don't really delete the insn; just ignore it. */
1345 last_ignored_compare = insn;
1346 break;
1347 }
1348 }
1349 }
1350#endif
1351
ee668edc
RS
1352 /* Following a conditional branch, we have a new basic block.
1353 But if we are inside a sequence, the new block starts after the
1354 last insn of the sequence. */
1355 if (profile_block_flag && final_sequence == 0
1356 && ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET
1357 && GET_CODE (SET_SRC (body)) != LABEL_REF)
1358 || (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL
1359 && GET_CODE (XVECEXP (body, 0, 0)) == SET
1360 && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)))
a130a441
MM
1361 new_block = 1;
1362
1363#ifndef STACK_REGS
1364 /* Don't bother outputting obvious no-ops, even without -O.
1365 This optimization is fast and doesn't interfere with debugging.
1366 Don't do this if the insn is in a delay slot, since this
1367 will cause an improper number of delay insns to be written. */
1368 if (final_sequence == 0
1369 && prescan >= 0
1370 && GET_CODE (insn) == INSN && GET_CODE (body) == SET
1371 && GET_CODE (SET_SRC (body)) == REG
1372 && GET_CODE (SET_DEST (body)) == REG
1373 && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
1374 break;
1375#endif
1376
1377#ifdef HAVE_cc0
1378 /* If this is a conditional branch, maybe modify it
1379 if the cc's are in a nonstandard state
1380 so that it accomplishes the same thing that it would
1381 do straightforwardly if the cc's were set up normally. */
1382
1383 if (cc_status.flags != 0
1384 && GET_CODE (insn) == JUMP_INSN
1385 && GET_CODE (body) == SET
1386 && SET_DEST (body) == pc_rtx
1387 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
1388 /* This is done during prescan; it is not done again
1389 in final scan when prescan has been done. */
1390 && prescan >= 0)
1391 {
1392 /* This function may alter the contents of its argument
1393 and clear some of the cc_status.flags bits.
1394 It may also return 1 meaning condition now always true
1395 or -1 meaning condition now always false
1396 or 2 meaning condition nontrivial but altered. */
1397 register int result = alter_cond (XEXP (SET_SRC (body), 0));
1398 /* If condition now has fixed value, replace the IF_THEN_ELSE
1399 with its then-operand or its else-operand. */
1400 if (result == 1)
1401 SET_SRC (body) = XEXP (SET_SRC (body), 1);
1402 if (result == -1)
1403 SET_SRC (body) = XEXP (SET_SRC (body), 2);
1404
1405 /* The jump is now either unconditional or a no-op.
1406 If it has become a no-op, don't try to output it.
1407 (It would not be recognized.) */
1408 if (SET_SRC (body) == pc_rtx)
1409 {
1410 PUT_CODE (insn, NOTE);
1411 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
1412 NOTE_SOURCE_FILE (insn) = 0;
1413 break;
1414 }
1415 else if (GET_CODE (SET_SRC (body)) == RETURN)
1416 /* Replace (set (pc) (return)) with (return). */
1417 PATTERN (insn) = body = SET_SRC (body);
1418
1419 /* Rerecognize the instruction if it has changed. */
1420 if (result != 0)
1421 INSN_CODE (insn) = -1;
1422 }
1423
1424 /* Make same adjustments to instructions that examine the
1425 condition codes without jumping (if this machine has them). */
1426
1427 if (cc_status.flags != 0
1428 && GET_CODE (body) == SET)
1429 {
1430 switch (GET_CODE (SET_SRC (body)))
1431 {
1432 case GTU:
1433 case GT:
1434 case LTU:
1435 case LT:
1436 case GEU:
1437 case GE:
1438 case LEU:
1439 case LE:
1440 case EQ:
1441 case NE:
1442 {
1443 register int result;
1444 if (XEXP (SET_SRC (body), 0) != cc0_rtx)
1445 break;
1446 result = alter_cond (SET_SRC (body));
1447 if (result == 1)
1448 validate_change (insn, &SET_SRC (body), const_true_rtx, 0);
1449 else if (result == -1)
1450 validate_change (insn, &SET_SRC (body), const0_rtx, 0);
1451 else if (result == 2)
1452 INSN_CODE (insn) = -1;
1453 }
1454 }
1455 }
1456#endif
1457
1458 /* Do machine-specific peephole optimizations if desired. */
1459
1460 if (optimize && !flag_no_peephole && !nopeepholes)
1461 {
1462 rtx next = peephole (insn);
1463 /* When peepholing, if there were notes within the peephole,
1464 emit them before the peephole. */
1465 if (next != 0 && next != NEXT_INSN (insn))
1466 {
1467 rtx prev = PREV_INSN (insn);
1468 rtx note;
1469
1470 for (note = NEXT_INSN (insn); note != next;
1471 note = NEXT_INSN (note))
1472 final_scan_insn (note, file, optimize, prescan, nopeepholes);
1473
1474 /* In case this is prescan, put the notes
1475 in proper position for later rescan. */
1476 note = NEXT_INSN (insn);
1477 PREV_INSN (note) = prev;
1478 NEXT_INSN (prev) = note;
1479 NEXT_INSN (PREV_INSN (next)) = insn;
1480 PREV_INSN (insn) = PREV_INSN (next);
1481 NEXT_INSN (insn) = next;
1482 PREV_INSN (next) = insn;
1483 }
1484
1485 /* PEEPHOLE might have changed this. */
1486 body = PATTERN (insn);
1487 }
1488
1489 /* Try to recognize the instruction.
1490 If successful, verify that the operands satisfy the
1491 constraints for the instruction. Crash if they don't,
1492 since `reload' should have changed them so that they do. */
1493
1494 insn_code_number = recog_memoized (insn);
1495 insn_extract (insn);
1496 for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1497 {
1498 if (GET_CODE (recog_operand[i]) == SUBREG)
1499 recog_operand[i] = alter_subreg (recog_operand[i]);
1500 }
1501
1502#ifdef REGISTER_CONSTRAINTS
1503 if (! constrain_operands (insn_code_number, 1))
1504 fatal_insn_not_found (insn);
1505#endif
1506
1507 /* Some target machines need to prescan each insn before
1508 it is output. */
1509
1510#ifdef FINAL_PRESCAN_INSN
1511 FINAL_PRESCAN_INSN (insn, recog_operand,
1512 insn_n_operands[insn_code_number]);
1513#endif
1514
1515#ifdef HAVE_cc0
1516 cc_prev_status = cc_status;
1517
1518 /* Update `cc_status' for this instruction.
1519 The instruction's output routine may change it further.
1520 If the output routine for a jump insn needs to depend
1521 on the cc status, it should look at cc_prev_status. */
1522
1523 NOTICE_UPDATE_CC (body, insn);
1524#endif
1525
1526 debug_insn = insn;
1527
1528 /* If the proper template needs to be chosen by some C code,
1529 run that code and get the real template. */
1530
1531 template = insn_template[insn_code_number];
1532 if (template == 0)
1533 {
1534 template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
1535
1536 /* If the C code returns 0, it means that it is a jump insn
1537 which follows a deleted test insn, and that test insn
1538 needs to be reinserted. */
1539 if (template == 0)
1540 {
1541 if (prev_nonnote_insn (insn) != last_ignored_compare)
1542 abort ();
1543 new_block = 0;
1544 return prev_nonnote_insn (insn);
1545 }
1546 }
1547
1548 /* If the template is the string "#", it means that this insn must
1549 be split. */
1550 if (template[0] == '#' && template[1] == '\0')
1551 {
1552 rtx new = try_split (body, insn, 0);
1553
1554 /* If we didn't split the insn, go away. */
1555 if (new == insn && PATTERN (new) == body)
1556 abort ();
1557
1558 new_block = 0;
1559 return new;
1560 }
1561
1562 if (prescan > 0)
1563 break;
1564
1565 /* Output assembler code from the template. */
1566
1567 output_asm_insn (template, recog_operand);
1568
1569#if 0
1570 /* It's not at all clear why we did this and doing so interferes
1571 with tests we'd like to do to use REG_WAS_0 notes, so let's try
1572 with this out. */
1573
1574 /* Mark this insn as having been output. */
1575 INSN_DELETED_P (insn) = 1;
1576#endif
1577
1578 debug_insn = 0;
1579 }
1580 }
1581 return NEXT_INSN (insn);
1582}
1583\f
1584/* Output debugging info to the assembler file FILE
1585 based on the NOTE-insn INSN, assumed to be a line number. */
1586
1587static void
1588output_source_line (file, insn)
1589 FILE *file;
1590 rtx insn;
1591{
1592 char ltext_label_name[100];
1593 register char *filename = NOTE_SOURCE_FILE (insn);
1594
1595 last_linenum = NOTE_LINE_NUMBER (insn);
1596
1597 if (write_symbols != NO_DEBUG)
1598 {
1599#ifdef SDB_DEBUGGING_INFO
1600 if (write_symbols == SDB_DEBUG
1601#if 0 /* People like having line numbers even in wrong file! */
1602 /* COFF can't handle multiple source files--lose, lose. */
1603 && !strcmp (filename, main_input_filename)
1604#endif
1605 /* COFF relative line numbers must be positive. */
1606 && last_linenum > sdb_begin_function_line)
1607 {
1608#ifdef ASM_OUTPUT_SOURCE_LINE
1609 ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
1610#else
1611 fprintf (file, "\t.ln\t%d\n",
1612 ((sdb_begin_function_line > -1)
1613 ? last_linenum - sdb_begin_function_line : 1));
1614#endif
1615 }
1616#endif
1617
1618#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
1619 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
1620 {
1621 dbxout_source_file (file, filename);
1622
1623#ifdef ASM_OUTPUT_SOURCE_LINE
1624 ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (insn));
1625#else
1626 fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP,
1627 N_SLINE, NOTE_LINE_NUMBER (insn));
1628#endif
1629 }
1630#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
1631
1632#ifdef DWARF_DEBUGGING_INFO
1633 if (write_symbols == DWARF_DEBUG)
1634 dwarfout_line (filename, NOTE_LINE_NUMBER (insn));
1635#endif
1636 }
1637}
1638\f
1639/* If X is a SUBREG, replace it with a REG or a MEM,
1640 based on the thing it is a subreg of. */
1641
1642rtx
1643alter_subreg (x)
1644 register rtx x;
1645{
1646 register rtx y = SUBREG_REG (x);
1647 if (GET_CODE (y) == SUBREG)
1648 y = alter_subreg (y);
1649
1650 if (GET_CODE (y) == REG)
1651 {
1652 /* If the containing reg really gets a hard reg, so do we. */
1653 PUT_CODE (x, REG);
1654 REGNO (x) = REGNO (y) + SUBREG_WORD (x);
1655 }
1656 else if (GET_CODE (y) == MEM)
1657 {
1658 register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
1659#if BYTES_BIG_ENDIAN
1660 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
1661 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
1662#endif
1663 PUT_CODE (x, MEM);
1664 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);
1665 XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
1666 }
1667
1668 return x;
1669}
1670
1671/* Do alter_subreg on all the SUBREGs contained in X. */
1672
1673static rtx
1674walk_alter_subreg (x)
1675 rtx x;
1676{
1677 switch (GET_CODE (x))
1678 {
1679 case PLUS:
1680 case MULT:
1681 XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
1682 XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1));
1683 break;
1684
1685 case MEM:
1686 XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));
1687 break;
1688
1689 case SUBREG:
1690 return alter_subreg (x);
1691 }
1692
1693 return x;
1694}
1695\f
1696#ifdef HAVE_cc0
1697
1698/* Given BODY, the body of a jump instruction, alter the jump condition
1699 as required by the bits that are set in cc_status.flags.
1700 Not all of the bits there can be handled at this level in all cases.
1701
1702 The value is normally 0.
1703 1 means that the condition has become always true.
1704 -1 means that the condition has become always false.
1705 2 means that COND has been altered. */
1706
1707static int
1708alter_cond (cond)
1709 register rtx cond;
1710{
1711 int value = 0;
1712
1713 if (cc_status.flags & CC_REVERSED)
1714 {
1715 value = 2;
1716 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
1717 }
1718
1719 if (cc_status.flags & CC_INVERTED)
1720 {
1721 value = 2;
1722 PUT_CODE (cond, reverse_condition (GET_CODE (cond)));
1723 }
1724
1725 if (cc_status.flags & CC_NOT_POSITIVE)
1726 switch (GET_CODE (cond))
1727 {
1728 case LE:
1729 case LEU:
1730 case GEU:
1731 /* Jump becomes unconditional. */
1732 return 1;
1733
1734 case GT:
1735 case GTU:
1736 case LTU:
1737 /* Jump becomes no-op. */
1738 return -1;
1739
1740 case GE:
1741 PUT_CODE (cond, EQ);
1742 value = 2;
1743 break;
1744
1745 case LT:
1746 PUT_CODE (cond, NE);
1747 value = 2;
1748 break;
1749 }
1750
1751 if (cc_status.flags & CC_NOT_NEGATIVE)
1752 switch (GET_CODE (cond))
1753 {
1754 case GE:
1755 case GEU:
1756 /* Jump becomes unconditional. */
1757 return 1;
1758
1759 case LT:
1760 case LTU:
1761 /* Jump becomes no-op. */
1762 return -1;
1763
1764 case LE:
1765 case LEU:
1766 PUT_CODE (cond, EQ);
1767 value = 2;
1768 break;
1769
1770 case GT:
1771 case GTU:
1772 PUT_CODE (cond, NE);
1773 value = 2;
1774 break;
1775 }
1776
1777 if (cc_status.flags & CC_NO_OVERFLOW)
1778 switch (GET_CODE (cond))
1779 {
1780 case GEU:
1781 /* Jump becomes unconditional. */
1782 return 1;
1783
1784 case LEU:
1785 PUT_CODE (cond, EQ);
1786 value = 2;
1787 break;
1788
1789 case GTU:
1790 PUT_CODE (cond, NE);
1791 value = 2;
1792 break;
1793
1794 case LTU:
1795 /* Jump becomes no-op. */
1796 return -1;
1797 }
1798
1799 if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N))
1800 switch (GET_CODE (cond))
1801 {
1802 case LE:
1803 case LEU:
1804 case GE:
1805 case GEU:
1806 case LT:
1807 case LTU:
1808 case GT:
1809 case GTU:
1810 abort ();
1811
1812 case NE:
1813 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
1814 value = 2;
1815 break;
1816
1817 case EQ:
1818 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE);
1819 value = 2;
1820 break;
1821 }
1822
1823 return value;
1824}
1825#endif
1826\f
1827/* Report inconsistency between the assembler template and the operands.
1828 In an `asm', it's the user's fault; otherwise, the compiler's fault. */
1829
1830void
1831output_operand_lossage (str)
1832 char *str;
1833{
1834 if (this_is_asm_operands)
1835 error_for_asm (this_is_asm_operands, "invalid `asm': %s", str);
1836 else
1837 abort ();
1838}
1839\f
1840/* Output of assembler code from a template, and its subroutines. */
1841
1842/* Output text from TEMPLATE to the assembler output file,
1843 obeying %-directions to substitute operands taken from
1844 the vector OPERANDS.
1845
1846 %N (for N a digit) means print operand N in usual manner.
1847 %lN means require operand N to be a CODE_LABEL or LABEL_REF
1848 and print the label name with no punctuation.
1849 %cN means require operand N to be a constant
1850 and print the constant expression with no punctuation.
1851 %aN means expect operand N to be a memory address
1852 (not a memory reference!) and print a reference
1853 to that address.
1854 %nN means expect operand N to be a constant
1855 and print a constant expression for minus the value
1856 of the operand, with no other punctuation. */
1857
1858void
1859output_asm_insn (template, operands)
1860 char *template;
1861 rtx *operands;
1862{
1863 register char *p;
1864 register int c;
1865
1866 /* An insn may return a null string template
1867 in a case where no assembler code is needed. */
1868 if (*template == 0)
1869 return;
1870
1871 p = template;
1872 putc ('\t', asm_out_file);
1873
1874#ifdef ASM_OUTPUT_OPCODE
1875 ASM_OUTPUT_OPCODE (asm_out_file, p);
1876#endif
1877
1878 while (c = *p++)
1879 {
1880#ifdef ASM_OUTPUT_OPCODE
1881 if (c == '\n')
1882 {
1883 putc (c, asm_out_file);
1884 while ((c = *p) == '\t')
1885 {
1886 putc (c, asm_out_file);
1887 p++;
1888 }
1889 ASM_OUTPUT_OPCODE (asm_out_file, p);
1890 }
1891 else
1892#endif
1893 if (c != '%')
1894 putc (c, asm_out_file);
1895 else
1896 {
1897 /* %% outputs a single %. */
1898 if (*p == '%')
1899 {
1900 p++;
1901 putc (c, asm_out_file);
1902 }
1903 /* %= outputs a number which is unique to each insn in the entire
1904 compilation. This is useful for making local labels that are
1905 referred to more than once in a given insn. */
1906 else if (*p == '=')
1907 fprintf (asm_out_file, "%d", insn_counter);
1908 /* % followed by a letter and some digits
1909 outputs an operand in a special way depending on the letter.
1910 Letters `acln' are implemented directly.
1911 Other letters are passed to `output_operand' so that
1912 the PRINT_OPERAND macro can define them. */
1913 else if ((*p >= 'a' && *p <= 'z')
1914 || (*p >= 'A' && *p <= 'Z'))
1915 {
1916 int letter = *p++;
1917 c = atoi (p);
1918
1919 if (! (*p >= '0' && *p <= '9'))
1920 output_operand_lossage ("operand number missing after %-letter");
1921 else if (this_is_asm_operands && c >= (unsigned) insn_noperands)
1922 output_operand_lossage ("operand number out of range");
1923 else if (letter == 'l')
1924 output_asm_label (operands[c]);
1925 else if (letter == 'a')
1926 output_address (operands[c]);
1927 else if (letter == 'c')
1928 {
1929 if (CONSTANT_ADDRESS_P (operands[c]))
1930 output_addr_const (asm_out_file, operands[c]);
1931 else
1932 output_operand (operands[c], 'c');
1933 }
1934 else if (letter == 'n')
1935 {
1936 if (GET_CODE (operands[c]) == CONST_INT)
1937 fprintf (asm_out_file, "%d", - INTVAL (operands[c]));
1938 else
1939 {
1940 putc ('-', asm_out_file);
1941 output_addr_const (asm_out_file, operands[c]);
1942 }
1943 }
1944 else
1945 output_operand (operands[c], letter);
1946
1947 while ((c = *p) >= '0' && c <= '9') p++;
1948 }
1949 /* % followed by a digit outputs an operand the default way. */
1950 else if (*p >= '0' && *p <= '9')
1951 {
1952 c = atoi (p);
1953 if (this_is_asm_operands && c >= (unsigned) insn_noperands)
1954 output_operand_lossage ("operand number out of range");
1955 else
1956 output_operand (operands[c], 0);
1957 while ((c = *p) >= '0' && c <= '9') p++;
1958 }
1959 /* % followed by punctuation: output something for that
1960 punctuation character alone, with no operand.
1961 The PRINT_OPERAND macro decides what is actually done. */
1962#ifdef PRINT_OPERAND_PUNCT_VALID_P
1963 else if (PRINT_OPERAND_PUNCT_VALID_P (*p))
1964 output_operand (0, *p++);
1965#endif
1966 else
1967 output_operand_lossage ("invalid %%-code");
1968 }
1969 }
1970
1971 if (flag_print_asm_name)
1972 {
1973 /* Annotate the assembly with a comment describing the pattern and
1974 alternative used. */
1975 if (debug_insn)
1976 {
1977 register int num = INSN_CODE (debug_insn);
1978 fprintf (asm_out_file, " %s %d %s",
1979 ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);
1980 if (insn_n_alternatives[num] > 1)
1981 fprintf (asm_out_file, "/%d", which_alternative + 1);
1982
1983 /* Clear this so only the first assembler insn
1984 of any rtl insn will get the special comment for -dp. */
1985 debug_insn = 0;
1986 }
1987 }
1988
1989 putc ('\n', asm_out_file);
1990}
1991\f
1992/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
1993
1994void
1995output_asm_label (x)
1996 rtx x;
1997{
1998 char buf[256];
1999
2000 if (GET_CODE (x) == LABEL_REF)
2001 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2002 else if (GET_CODE (x) == CODE_LABEL)
2003 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2004 else
2005 output_operand_lossage ("`%l' operand isn't a label");
2006
2007 assemble_name (asm_out_file, buf);
2008}
2009
2010/* Print operand X using machine-dependent assembler syntax.
2011 The macro PRINT_OPERAND is defined just to control this function.
2012 CODE is a non-digit that preceded the operand-number in the % spec,
2013 such as 'z' if the spec was `%z3'. CODE is 0 if there was no char
2014 between the % and the digits.
2015 When CODE is a non-letter, X is 0.
2016
2017 The meanings of the letters are machine-dependent and controlled
2018 by PRINT_OPERAND. */
2019
2020static void
2021output_operand (x, code)
2022 rtx x;
2023 int code;
2024{
2025 if (x && GET_CODE (x) == SUBREG)
2026 x = alter_subreg (x);
2027 PRINT_OPERAND (asm_out_file, x, code);
2028}
2029
2030/* Print a memory reference operand for address X
2031 using machine-dependent assembler syntax.
2032 The macro PRINT_OPERAND_ADDRESS exists just to control this function. */
2033
2034void
2035output_address (x)
2036 rtx x;
2037{
2038 walk_alter_subreg (x);
2039 PRINT_OPERAND_ADDRESS (asm_out_file, x);
2040}
2041\f
2042/* Print an integer constant expression in assembler syntax.
2043 Addition and subtraction are the only arithmetic
2044 that may appear in these expressions. */
2045
2046void
2047output_addr_const (file, x)
2048 FILE *file;
2049 rtx x;
2050{
2051 char buf[256];
2052
2053 restart:
2054 switch (GET_CODE (x))
2055 {
2056 case PC:
2057 if (flag_pic)
2058 putc ('.', file);
2059 else
2060 abort ();
2061 break;
2062
2063 case SYMBOL_REF:
2064 assemble_name (file, XSTR (x, 0));
2065 break;
2066
2067 case LABEL_REF:
2068 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
2069 assemble_name (asm_out_file, buf);
2070 break;
2071
2072 case CODE_LABEL:
2073 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2074 assemble_name (asm_out_file, buf);
2075 break;
2076
2077 case CONST_INT:
2078 fprintf (file, "%d", INTVAL (x));
2079 break;
2080
2081 case CONST:
2082 /* This used to output parentheses around the expression,
2083 but that does not work on the 386 (either ATT or BSD assembler). */
2084 output_addr_const (file, XEXP (x, 0));
2085 break;
2086
2087 case CONST_DOUBLE:
2088 if (GET_MODE (x) == VOIDmode)
2089 {
2090 /* We can use %d if the number is <32 bits and positive. */
2091 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2092 fprintf (file, "0x%x%08x",
2093 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2094 else
2095 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2096 }
2097 else
2098 /* We can't handle floating point constants;
2099 PRINT_OPERAND must handle them. */
2100 output_operand_lossage ("floating constant misused");
2101 break;
2102
2103 case PLUS:
2104 /* Some assemblers need integer constants to appear last (eg masm). */
2105 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2106 {
2107 output_addr_const (file, XEXP (x, 1));
2108 if (INTVAL (XEXP (x, 0)) >= 0)
2109 fprintf (file, "+");
2110 output_addr_const (file, XEXP (x, 0));
2111 }
2112 else
2113 {
2114 output_addr_const (file, XEXP (x, 0));
2115 if (INTVAL (XEXP (x, 1)) >= 0)
2116 fprintf (file, "+");
2117 output_addr_const (file, XEXP (x, 1));
2118 }
2119 break;
2120
2121 case MINUS:
2122 output_addr_const (file, XEXP (x, 0));
2123 fprintf (file, "-");
2124 output_addr_const (file, XEXP (x, 1));
2125 break;
2126
2127 default:
2128 output_operand_lossage ("invalid expression as operand");
2129 }
2130}
2131\f
2132/* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
2133 %R prints the value of REGISTER_PREFIX.
2134 %L prints the value of LOCAL_LABEL_PREFIX.
2135 %U prints the value of USER_LABEL_PREFIX.
2136 %I prints the value of IMMEDIATE_PREFIX.
2137 %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
2138 Also supported are %d, %x, %s, %e, %f, %g and %%. */
2139
2140void
2141asm_fprintf (va_alist)
2142 va_dcl
2143{
2144 va_list argptr;
2145 FILE *file;
2146 char buf[10];
2147 char *p, *q, c;
2148
2149 va_start (argptr);
2150
2151 file = va_arg (argptr, FILE *);
2152 p = va_arg (argptr, char *);
2153 buf[0] = '%';
2154
2155 while (c = *p++)
2156 switch (c)
2157 {
2158 case '%':
2159 c = *p++;
2160 q = &buf[1];
2161 while ((c >= '0' && c <= '9') || c == '.')
2162 {
2163 *q++ = c;
2164 c = *p++;
2165 }
2166 switch (c)
2167 {
2168 case '%':
2169 fprintf (file, "%%");
2170 break;
2171
2172 case 'd': case 'i': case 'u':
2173 case 'x': case 'p': case 'X':
2174 case 'o':
2175 *q++ = c;
2176 *q = 0;
2177 fprintf (file, buf, va_arg (argptr, int));
2178 break;
2179
2180 case 'e':
2181 case 'f':
2182 case 'g':
2183 *q++ = c;
2184 *q = 0;
2185 fprintf (file, buf, va_arg (argptr, double));
2186 break;
2187
2188 case 's':
2189 *q++ = c;
2190 *q = 0;
2191 fprintf (file, buf, va_arg (argptr, char *));
2192 break;
2193
2194 case 'O':
2195#ifdef ASM_OUTPUT_OPCODE
2196 ASM_OUTPUT_OPCODE (asm_out_file, p);
2197#endif
2198 break;
2199
2200 case 'R':
2201#ifdef REGISTER_PREFIX
2202 fprintf (file, "%s", REGISTER_PREFIX);
2203#endif
2204 break;
2205
2206 case 'I':
2207#ifdef IMMEDIATE_PREFIX
2208 fprintf (file, "%s", IMMEDIATE_PREFIX);
2209#endif
2210 break;
2211
2212 case 'L':
2213#ifdef LOCAL_LABEL_PREFIX
2214 fprintf (file, "%s", LOCAL_LABEL_PREFIX);
2215#endif
2216 break;
2217
2218 case 'U':
2219#ifdef USER_LABEL_PREFIX
2220 fprintf (file, "%s", USER_LABEL_PREFIX);
2221#endif
2222 break;
2223
2224 default:
2225 abort ();
2226 }
2227 break;
2228
2229 default:
2230 fputc (c, file);
2231 }
2232}
2233\f
2234/* Split up a CONST_DOUBLE or integer constant rtx
2235 into two rtx's for single words,
2236 storing in *FIRST the word that comes first in memory in the target
2237 and in *SECOND the other. */
2238
2239void
2240split_double (value, first, second)
2241 rtx value;
2242 rtx *first, *second;
2243{
2244 if (GET_CODE (value) == CONST_INT)
2245 {
2246 /* The rule for using CONST_INT for a wider mode
2247 is that we regard the value as signed.
2248 So sign-extend it. */
2249 rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx);
2250#if WORDS_BIG_ENDIAN
2251 *first = high;
2252 *second = value;
2253#else
2254 *first = value;
2255 *second = high;
2256#endif
2257 }
2258 else if (GET_CODE (value) != CONST_DOUBLE)
2259 {
2260#if WORDS_BIG_ENDIAN
2261 *first = const0_rtx;
2262 *second = value;
2263#else
2264 *first = value;
2265 *second = const0_rtx;
2266#endif
2267 }
2268 else if (GET_MODE (value) == VOIDmode
2269 /* This is the old way we did CONST_DOUBLE integers. */
2270 || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT)
2271 {
2272 /* In an integer, the words are defined as most and least significant.
2273 So order them by the target's convention. */
2274#if WORDS_BIG_ENDIAN
2275 *first = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (value));
2276 *second = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (value));
2277#else
2278 *first = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (value));
2279 *second = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (value));
2280#endif
2281 }
2282 else
2283 {
2284 if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
2285 || HOST_BITS_PER_INT != BITS_PER_WORD)
2286 && ! flag_pretend_float)
2287 abort ();
2288
2289#if defined (HOST_WORDS_BIG_ENDIAN) == WORDS_BIG_ENDIAN
2290 /* Host and target agree => no need to swap. */
2291 *first = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (value));
2292 *second = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (value));
2293#else
2294 *second = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (value));
2295 *first = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (value));
2296#endif
2297 }
2298}
2299\f
2300/* Return nonzero if this function has no function calls. */
2301
2302int
2303leaf_function_p ()
2304{
2305 rtx insn;
2306
2307 if (profile_flag || profile_block_flag)
2308 return 0;
2309
2310 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2311 {
2312 if (GET_CODE (insn) == CALL_INSN)
2313 return 0;
2314 if (GET_CODE (insn) == INSN
2315 && GET_CODE (PATTERN (insn)) == SEQUENCE
2316 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)
2317 return 0;
2318 }
2319 for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2320 {
2321 if (GET_CODE (XEXP (insn, 0)) == CALL_INSN)
2322 return 0;
2323 if (GET_CODE (XEXP (insn, 0)) == INSN
2324 && GET_CODE (PATTERN (XEXP (insn, 0))) == SEQUENCE
2325 && GET_CODE (XVECEXP (PATTERN (XEXP (insn, 0)), 0, 0)) == CALL_INSN)
2326 return 0;
2327 }
2328
2329 return 1;
2330}
2331
2332/* On some machines, a function with no call insns
2333 can run faster if it doesn't create its own register window.
2334 When output, the leaf function should use only the "output"
2335 registers. Ordinarily, the function would be compiled to use
2336 the "input" registers to find its arguments; it is a candidate
2337 for leaf treatment if it uses only the "input" registers.
2338 Leaf function treatment means renumbering so the function
2339 uses the "output" registers instead. */
2340
2341#ifdef LEAF_REGISTERS
2342
2343static char permitted_reg_in_leaf_functions[] = LEAF_REGISTERS;
2344
2345/* Return 1 if this function uses only the registers that can be
2346 safely renumbered. */
2347
2348int
2349only_leaf_regs_used ()
2350{
2351 int i;
2352
2353 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2354 {
2355 if (regs_ever_live[i] > permitted_reg_in_leaf_functions[i])
2356 return 0;
2357 }
2358 return 1;
2359}
2360
2361/* Scan all instructions and renumber all registers into those
2362 available in leaf functions. */
2363
2364static void
2365leaf_renumber_regs (first)
2366 rtx first;
2367{
2368 rtx insn;
2369
2370 /* Renumber only the actual patterns.
2371 The reg-notes can contain frame pointer refs,
2372 and renumbering them could crash, and should not be needed. */
2373 for (insn = first; insn; insn = NEXT_INSN (insn))
2374 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
2375 leaf_renumber_regs_insn (PATTERN (insn));
2376 for (insn = current_function_epilogue_delay_list; insn; insn = XEXP (insn, 1))
2377 if (GET_RTX_CLASS (GET_CODE (XEXP (insn, 0))) == 'i')
2378 leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0)));
2379}
2380
2381/* Scan IN_RTX and its subexpressions, and renumber all regs into those
2382 available in leaf functions. */
2383
2384void
2385leaf_renumber_regs_insn (in_rtx)
2386 register rtx in_rtx;
2387{
2388 register int i, j;
2389 register char *format_ptr;
2390
2391 if (in_rtx == 0)
2392 return;
2393
2394 /* Renumber all input-registers into output-registers.
2395 renumbered_regs would be 1 for an output-register;
2396 they */
2397
2398 if (GET_CODE (in_rtx) == REG)
2399 {
2400 int newreg;
2401
2402 /* Don't renumber the same reg twice. */
2403 if (in_rtx->used)
2404 return;
2405
2406 newreg = REGNO (in_rtx);
2407 /* Don't try to renumber pseudo regs. It is possible for a pseudo reg
2408 to reach here as part of a REG_NOTE. */
2409 if (newreg >= FIRST_PSEUDO_REGISTER)
2410 {
2411 in_rtx->used = 1;
2412 return;
2413 }
2414 newreg = LEAF_REG_REMAP (newreg);
2415 if (newreg < 0)
2416 abort ();
2417 regs_ever_live[REGNO (in_rtx)] = 0;
2418 regs_ever_live[newreg] = 1;
2419 REGNO (in_rtx) = newreg;
2420 in_rtx->used = 1;
2421 }
2422
2423 if (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i')
2424 {
2425 /* Inside a SEQUENCE, we find insns.
2426 Renumber just the patterns of these insns,
2427 just as we do for the top-level insns. */
2428 leaf_renumber_regs_insn (PATTERN (in_rtx));
2429 return;
2430 }
2431
2432 format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
2433
2434 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
2435 switch (*format_ptr++)
2436 {
2437 case 'e':
2438 leaf_renumber_regs_insn (XEXP (in_rtx, i));
2439 break;
2440
2441 case 'E':
2442 if (NULL != XVEC (in_rtx, i))
2443 {
2444 for (j = 0; j < XVECLEN (in_rtx, i); j++)
2445 leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
2446 }
2447 break;
2448
2449 case 'S':
2450 case 's':
2451 case '0':
2452 case 'i':
2453 case 'n':
2454 case 'u':
2455 break;
2456
2457 default:
2458 abort ();
2459 }
2460}
2461#endif
This page took 0.273295 seconds and 5 git commands to generate.