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