Mercurial > hg > CbC > CbC_gcc
comparison gcc/final.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Convert RTL to assembler code and output it, for GNU compiler. | |
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, | |
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 | |
4 Free Software Foundation, Inc. | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 /* This is the final pass of the compiler. | |
23 It looks at the rtl code for a function and outputs assembler code. | |
24 | |
25 Call `final_start_function' to output the assembler code for function entry, | |
26 `final' to output assembler code for some RTL code, | |
27 `final_end_function' to output assembler code for function exit. | |
28 If a function is compiled in several pieces, each piece is | |
29 output separately with `final'. | |
30 | |
31 Some optimizations are also done at this level. | |
32 Move instructions that were made unnecessary by good register allocation | |
33 are detected and omitted from the output. (Though most of these | |
34 are removed by the last jump pass.) | |
35 | |
36 Instructions to set the condition codes are omitted when it can be | |
37 seen that the condition codes already had the desired values. | |
38 | |
39 In some cases it is sufficient if the inherited condition codes | |
40 have related values, but this may require the following insn | |
41 (the one that tests the condition codes) to be modified. | |
42 | |
43 The code for the function prologue and epilogue are generated | |
44 directly in assembler by the target functions function_prologue and | |
45 function_epilogue. Those instructions never exist as rtl. */ | |
46 | |
47 #include "config.h" | |
48 #include "system.h" | |
49 #include "coretypes.h" | |
50 #include "tm.h" | |
51 | |
52 #include "tree.h" | |
53 #include "rtl.h" | |
54 #include "tm_p.h" | |
55 #include "regs.h" | |
56 #include "insn-config.h" | |
57 #include "insn-attr.h" | |
58 #include "recog.h" | |
59 #include "conditions.h" | |
60 #include "flags.h" | |
61 #include "real.h" | |
62 #include "hard-reg-set.h" | |
63 #include "output.h" | |
64 #include "except.h" | |
65 #include "function.h" | |
66 #include "toplev.h" | |
67 #include "reload.h" | |
68 #include "intl.h" | |
69 #include "basic-block.h" | |
70 #include "target.h" | |
71 #include "debug.h" | |
72 #include "expr.h" | |
73 #include "cfglayout.h" | |
74 #include "tree-pass.h" | |
75 #include "timevar.h" | |
76 #include "cgraph.h" | |
77 #include "coverage.h" | |
78 #include "df.h" | |
79 #include "vecprim.h" | |
80 #include "ggc.h" | |
81 #include "cfgloop.h" | |
82 #include "params.h" | |
83 | |
84 #ifdef XCOFF_DEBUGGING_INFO | |
85 #include "xcoffout.h" /* Needed for external data | |
86 declarations for e.g. AIX 4.x. */ | |
87 #endif | |
88 | |
89 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) | |
90 #include "dwarf2out.h" | |
91 #endif | |
92 | |
93 #ifdef DBX_DEBUGGING_INFO | |
94 #include "dbxout.h" | |
95 #endif | |
96 | |
97 #ifdef SDB_DEBUGGING_INFO | |
98 #include "sdbout.h" | |
99 #endif | |
100 | |
101 /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a | |
102 null default for it to save conditionalization later. */ | |
103 #ifndef CC_STATUS_INIT | |
104 #define CC_STATUS_INIT | |
105 #endif | |
106 | |
107 /* How to start an assembler comment. */ | |
108 #ifndef ASM_COMMENT_START | |
109 #define ASM_COMMENT_START ";#" | |
110 #endif | |
111 | |
112 /* Is the given character a logical line separator for the assembler? */ | |
113 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR | |
114 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';') | |
115 #endif | |
116 | |
117 #ifndef JUMP_TABLES_IN_TEXT_SECTION | |
118 #define JUMP_TABLES_IN_TEXT_SECTION 0 | |
119 #endif | |
120 | |
121 /* Bitflags used by final_scan_insn. */ | |
122 #define SEEN_BB 1 | |
123 #define SEEN_NOTE 2 | |
124 #define SEEN_EMITTED 4 | |
125 | |
126 /* Last insn processed by final_scan_insn. */ | |
127 static rtx debug_insn; | |
128 rtx current_output_insn; | |
129 | |
130 /* Line number of last NOTE. */ | |
131 static int last_linenum; | |
132 | |
133 /* Highest line number in current block. */ | |
134 static int high_block_linenum; | |
135 | |
136 /* Likewise for function. */ | |
137 static int high_function_linenum; | |
138 | |
139 /* Filename of last NOTE. */ | |
140 static const char *last_filename; | |
141 | |
142 /* Override filename and line number. */ | |
143 static const char *override_filename; | |
144 static int override_linenum; | |
145 | |
146 /* Whether to force emission of a line note before the next insn. */ | |
147 static bool force_source_line = false; | |
148 | |
149 extern const int length_unit_log; /* This is defined in insn-attrtab.c. */ | |
150 | |
151 /* Nonzero while outputting an `asm' with operands. | |
152 This means that inconsistencies are the user's fault, so don't die. | |
153 The precise value is the insn being output, to pass to error_for_asm. */ | |
154 rtx this_is_asm_operands; | |
155 | |
156 /* Number of operands of this insn, for an `asm' with operands. */ | |
157 static unsigned int insn_noperands; | |
158 | |
159 /* Compare optimization flag. */ | |
160 | |
161 static rtx last_ignored_compare = 0; | |
162 | |
163 /* Assign a unique number to each insn that is output. | |
164 This can be used to generate unique local labels. */ | |
165 | |
166 static int insn_counter = 0; | |
167 | |
168 #ifdef HAVE_cc0 | |
169 /* This variable contains machine-dependent flags (defined in tm.h) | |
170 set and examined by output routines | |
171 that describe how to interpret the condition codes properly. */ | |
172 | |
173 CC_STATUS cc_status; | |
174 | |
175 /* During output of an insn, this contains a copy of cc_status | |
176 from before the insn. */ | |
177 | |
178 CC_STATUS cc_prev_status; | |
179 #endif | |
180 | |
181 /* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen. */ | |
182 | |
183 static int block_depth; | |
184 | |
185 /* Nonzero if have enabled APP processing of our assembler output. */ | |
186 | |
187 static int app_on; | |
188 | |
189 /* If we are outputting an insn sequence, this contains the sequence rtx. | |
190 Zero otherwise. */ | |
191 | |
192 rtx final_sequence; | |
193 | |
194 #ifdef ASSEMBLER_DIALECT | |
195 | |
196 /* Number of the assembler dialect to use, starting at 0. */ | |
197 static int dialect_number; | |
198 #endif | |
199 | |
200 #ifdef HAVE_conditional_execution | |
201 /* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */ | |
202 rtx current_insn_predicate; | |
203 #endif | |
204 | |
205 #ifdef HAVE_ATTR_length | |
206 static int asm_insn_count (rtx); | |
207 #endif | |
208 static void profile_function (FILE *); | |
209 static void profile_after_prologue (FILE *); | |
210 static bool notice_source_line (rtx); | |
211 static rtx walk_alter_subreg (rtx *, bool *); | |
212 static void output_asm_name (void); | |
213 static void output_alternate_entry_point (FILE *, rtx); | |
214 static tree get_mem_expr_from_op (rtx, int *); | |
215 static void output_asm_operand_names (rtx *, int *, int); | |
216 static void output_operand (rtx, int); | |
217 #ifdef LEAF_REGISTERS | |
218 static void leaf_renumber_regs (rtx); | |
219 #endif | |
220 #ifdef HAVE_cc0 | |
221 static int alter_cond (rtx); | |
222 #endif | |
223 #ifndef ADDR_VEC_ALIGN | |
224 static int final_addr_vec_align (rtx); | |
225 #endif | |
226 #ifdef HAVE_ATTR_length | |
227 static int align_fuzz (rtx, rtx, int, unsigned); | |
228 #endif | |
229 | |
230 /* Initialize data in final at the beginning of a compilation. */ | |
231 | |
232 void | |
233 init_final (const char *filename ATTRIBUTE_UNUSED) | |
234 { | |
235 app_on = 0; | |
236 final_sequence = 0; | |
237 | |
238 #ifdef ASSEMBLER_DIALECT | |
239 dialect_number = ASSEMBLER_DIALECT; | |
240 #endif | |
241 } | |
242 | |
243 /* Default target function prologue and epilogue assembler output. | |
244 | |
245 If not overridden for epilogue code, then the function body itself | |
246 contains return instructions wherever needed. */ | |
247 void | |
248 default_function_pro_epilogue (FILE *file ATTRIBUTE_UNUSED, | |
249 HOST_WIDE_INT size ATTRIBUTE_UNUSED) | |
250 { | |
251 } | |
252 | |
253 /* Default target hook that outputs nothing to a stream. */ | |
254 void | |
255 no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED) | |
256 { | |
257 } | |
258 | |
259 /* Enable APP processing of subsequent output. | |
260 Used before the output from an `asm' statement. */ | |
261 | |
262 void | |
263 app_enable (void) | |
264 { | |
265 if (! app_on) | |
266 { | |
267 fputs (ASM_APP_ON, asm_out_file); | |
268 app_on = 1; | |
269 } | |
270 } | |
271 | |
272 /* Disable APP processing of subsequent output. | |
273 Called from varasm.c before most kinds of output. */ | |
274 | |
275 void | |
276 app_disable (void) | |
277 { | |
278 if (app_on) | |
279 { | |
280 fputs (ASM_APP_OFF, asm_out_file); | |
281 app_on = 0; | |
282 } | |
283 } | |
284 | |
285 /* Return the number of slots filled in the current | |
286 delayed branch sequence (we don't count the insn needing the | |
287 delay slot). Zero if not in a delayed branch sequence. */ | |
288 | |
289 #ifdef DELAY_SLOTS | |
290 int | |
291 dbr_sequence_length (void) | |
292 { | |
293 if (final_sequence != 0) | |
294 return XVECLEN (final_sequence, 0) - 1; | |
295 else | |
296 return 0; | |
297 } | |
298 #endif | |
299 | |
300 /* The next two pages contain routines used to compute the length of an insn | |
301 and to shorten branches. */ | |
302 | |
303 /* Arrays for insn lengths, and addresses. The latter is referenced by | |
304 `insn_current_length'. */ | |
305 | |
306 static int *insn_lengths; | |
307 | |
308 VEC(int,heap) *insn_addresses_; | |
309 | |
310 /* Max uid for which the above arrays are valid. */ | |
311 static int insn_lengths_max_uid; | |
312 | |
313 /* Address of insn being processed. Used by `insn_current_length'. */ | |
314 int insn_current_address; | |
315 | |
316 /* Address of insn being processed in previous iteration. */ | |
317 int insn_last_address; | |
318 | |
319 /* known invariant alignment of insn being processed. */ | |
320 int insn_current_align; | |
321 | |
322 /* After shorten_branches, for any insn, uid_align[INSN_UID (insn)] | |
323 gives the next following alignment insn that increases the known | |
324 alignment, or NULL_RTX if there is no such insn. | |
325 For any alignment obtained this way, we can again index uid_align with | |
326 its uid to obtain the next following align that in turn increases the | |
327 alignment, till we reach NULL_RTX; the sequence obtained this way | |
328 for each insn we'll call the alignment chain of this insn in the following | |
329 comments. */ | |
330 | |
331 struct label_alignment | |
332 { | |
333 short alignment; | |
334 short max_skip; | |
335 }; | |
336 | |
337 static rtx *uid_align; | |
338 static int *uid_shuid; | |
339 static struct label_alignment *label_align; | |
340 | |
341 /* Indicate that branch shortening hasn't yet been done. */ | |
342 | |
343 void | |
344 init_insn_lengths (void) | |
345 { | |
346 if (uid_shuid) | |
347 { | |
348 free (uid_shuid); | |
349 uid_shuid = 0; | |
350 } | |
351 if (insn_lengths) | |
352 { | |
353 free (insn_lengths); | |
354 insn_lengths = 0; | |
355 insn_lengths_max_uid = 0; | |
356 } | |
357 #ifdef HAVE_ATTR_length | |
358 INSN_ADDRESSES_FREE (); | |
359 #endif | |
360 if (uid_align) | |
361 { | |
362 free (uid_align); | |
363 uid_align = 0; | |
364 } | |
365 } | |
366 | |
367 /* Obtain the current length of an insn. If branch shortening has been done, | |
368 get its actual length. Otherwise, use FALLBACK_FN to calculate the | |
369 length. */ | |
370 static inline int | |
371 get_attr_length_1 (rtx insn ATTRIBUTE_UNUSED, | |
372 int (*fallback_fn) (rtx) ATTRIBUTE_UNUSED) | |
373 { | |
374 #ifdef HAVE_ATTR_length | |
375 rtx body; | |
376 int i; | |
377 int length = 0; | |
378 | |
379 if (insn_lengths_max_uid > INSN_UID (insn)) | |
380 return insn_lengths[INSN_UID (insn)]; | |
381 else | |
382 switch (GET_CODE (insn)) | |
383 { | |
384 case NOTE: | |
385 case BARRIER: | |
386 case CODE_LABEL: | |
387 return 0; | |
388 | |
389 case CALL_INSN: | |
390 length = fallback_fn (insn); | |
391 break; | |
392 | |
393 case JUMP_INSN: | |
394 body = PATTERN (insn); | |
395 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) | |
396 { | |
397 /* Alignment is machine-dependent and should be handled by | |
398 ADDR_VEC_ALIGN. */ | |
399 } | |
400 else | |
401 length = fallback_fn (insn); | |
402 break; | |
403 | |
404 case INSN: | |
405 body = PATTERN (insn); | |
406 if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER) | |
407 return 0; | |
408 | |
409 else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) | |
410 length = asm_insn_count (body) * fallback_fn (insn); | |
411 else if (GET_CODE (body) == SEQUENCE) | |
412 for (i = 0; i < XVECLEN (body, 0); i++) | |
413 length += get_attr_length_1 (XVECEXP (body, 0, i), fallback_fn); | |
414 else | |
415 length = fallback_fn (insn); | |
416 break; | |
417 | |
418 default: | |
419 break; | |
420 } | |
421 | |
422 #ifdef ADJUST_INSN_LENGTH | |
423 ADJUST_INSN_LENGTH (insn, length); | |
424 #endif | |
425 return length; | |
426 #else /* not HAVE_ATTR_length */ | |
427 return 0; | |
428 #define insn_default_length 0 | |
429 #define insn_min_length 0 | |
430 #endif /* not HAVE_ATTR_length */ | |
431 } | |
432 | |
433 /* Obtain the current length of an insn. If branch shortening has been done, | |
434 get its actual length. Otherwise, get its maximum length. */ | |
435 int | |
436 get_attr_length (rtx insn) | |
437 { | |
438 return get_attr_length_1 (insn, insn_default_length); | |
439 } | |
440 | |
441 /* Obtain the current length of an insn. If branch shortening has been done, | |
442 get its actual length. Otherwise, get its minimum length. */ | |
443 int | |
444 get_attr_min_length (rtx insn) | |
445 { | |
446 return get_attr_length_1 (insn, insn_min_length); | |
447 } | |
448 | |
449 /* Code to handle alignment inside shorten_branches. */ | |
450 | |
451 /* Here is an explanation how the algorithm in align_fuzz can give | |
452 proper results: | |
453 | |
454 Call a sequence of instructions beginning with alignment point X | |
455 and continuing until the next alignment point `block X'. When `X' | |
456 is used in an expression, it means the alignment value of the | |
457 alignment point. | |
458 | |
459 Call the distance between the start of the first insn of block X, and | |
460 the end of the last insn of block X `IX', for the `inner size of X'. | |
461 This is clearly the sum of the instruction lengths. | |
462 | |
463 Likewise with the next alignment-delimited block following X, which we | |
464 shall call block Y. | |
465 | |
466 Call the distance between the start of the first insn of block X, and | |
467 the start of the first insn of block Y `OX', for the `outer size of X'. | |
468 | |
469 The estimated padding is then OX - IX. | |
470 | |
471 OX can be safely estimated as | |
472 | |
473 if (X >= Y) | |
474 OX = round_up(IX, Y) | |
475 else | |
476 OX = round_up(IX, X) + Y - X | |
477 | |
478 Clearly est(IX) >= real(IX), because that only depends on the | |
479 instruction lengths, and those being overestimated is a given. | |
480 | |
481 Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so | |
482 we needn't worry about that when thinking about OX. | |
483 | |
484 When X >= Y, the alignment provided by Y adds no uncertainty factor | |
485 for branch ranges starting before X, so we can just round what we have. | |
486 But when X < Y, we don't know anything about the, so to speak, | |
487 `middle bits', so we have to assume the worst when aligning up from an | |
488 address mod X to one mod Y, which is Y - X. */ | |
489 | |
490 #ifndef LABEL_ALIGN | |
491 #define LABEL_ALIGN(LABEL) align_labels_log | |
492 #endif | |
493 | |
494 #ifndef LABEL_ALIGN_MAX_SKIP | |
495 #define LABEL_ALIGN_MAX_SKIP align_labels_max_skip | |
496 #endif | |
497 | |
498 #ifndef LOOP_ALIGN | |
499 #define LOOP_ALIGN(LABEL) align_loops_log | |
500 #endif | |
501 | |
502 #ifndef LOOP_ALIGN_MAX_SKIP | |
503 #define LOOP_ALIGN_MAX_SKIP align_loops_max_skip | |
504 #endif | |
505 | |
506 #ifndef LABEL_ALIGN_AFTER_BARRIER | |
507 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0 | |
508 #endif | |
509 | |
510 #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP | |
511 #define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP 0 | |
512 #endif | |
513 | |
514 #ifndef JUMP_ALIGN | |
515 #define JUMP_ALIGN(LABEL) align_jumps_log | |
516 #endif | |
517 | |
518 #ifndef JUMP_ALIGN_MAX_SKIP | |
519 #define JUMP_ALIGN_MAX_SKIP align_jumps_max_skip | |
520 #endif | |
521 | |
522 #ifndef ADDR_VEC_ALIGN | |
523 static int | |
524 final_addr_vec_align (rtx addr_vec) | |
525 { | |
526 int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec))); | |
527 | |
528 if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT) | |
529 align = BIGGEST_ALIGNMENT / BITS_PER_UNIT; | |
530 return exact_log2 (align); | |
531 | |
532 } | |
533 | |
534 #define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC) | |
535 #endif | |
536 | |
537 #ifndef INSN_LENGTH_ALIGNMENT | |
538 #define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log | |
539 #endif | |
540 | |
541 #define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)]) | |
542 | |
543 static int min_labelno, max_labelno; | |
544 | |
545 #define LABEL_TO_ALIGNMENT(LABEL) \ | |
546 (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment) | |
547 | |
548 #define LABEL_TO_MAX_SKIP(LABEL) \ | |
549 (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip) | |
550 | |
551 /* For the benefit of port specific code do this also as a function. */ | |
552 | |
553 int | |
554 label_to_alignment (rtx label) | |
555 { | |
556 return LABEL_TO_ALIGNMENT (label); | |
557 } | |
558 | |
559 #ifdef HAVE_ATTR_length | |
560 /* The differences in addresses | |
561 between a branch and its target might grow or shrink depending on | |
562 the alignment the start insn of the range (the branch for a forward | |
563 branch or the label for a backward branch) starts out on; if these | |
564 differences are used naively, they can even oscillate infinitely. | |
565 We therefore want to compute a 'worst case' address difference that | |
566 is independent of the alignment the start insn of the range end | |
567 up on, and that is at least as large as the actual difference. | |
568 The function align_fuzz calculates the amount we have to add to the | |
569 naively computed difference, by traversing the part of the alignment | |
570 chain of the start insn of the range that is in front of the end insn | |
571 of the range, and considering for each alignment the maximum amount | |
572 that it might contribute to a size increase. | |
573 | |
574 For casesi tables, we also want to know worst case minimum amounts of | |
575 address difference, in case a machine description wants to introduce | |
576 some common offset that is added to all offsets in a table. | |
577 For this purpose, align_fuzz with a growth argument of 0 computes the | |
578 appropriate adjustment. */ | |
579 | |
580 /* Compute the maximum delta by which the difference of the addresses of | |
581 START and END might grow / shrink due to a different address for start | |
582 which changes the size of alignment insns between START and END. | |
583 KNOWN_ALIGN_LOG is the alignment known for START. | |
584 GROWTH should be ~0 if the objective is to compute potential code size | |
585 increase, and 0 if the objective is to compute potential shrink. | |
586 The return value is undefined for any other value of GROWTH. */ | |
587 | |
588 static int | |
589 align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth) | |
590 { | |
591 int uid = INSN_UID (start); | |
592 rtx align_label; | |
593 int known_align = 1 << known_align_log; | |
594 int end_shuid = INSN_SHUID (end); | |
595 int fuzz = 0; | |
596 | |
597 for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid]) | |
598 { | |
599 int align_addr, new_align; | |
600 | |
601 uid = INSN_UID (align_label); | |
602 align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid]; | |
603 if (uid_shuid[uid] > end_shuid) | |
604 break; | |
605 known_align_log = LABEL_TO_ALIGNMENT (align_label); | |
606 new_align = 1 << known_align_log; | |
607 if (new_align < known_align) | |
608 continue; | |
609 fuzz += (-align_addr ^ growth) & (new_align - known_align); | |
610 known_align = new_align; | |
611 } | |
612 return fuzz; | |
613 } | |
614 | |
615 /* Compute a worst-case reference address of a branch so that it | |
616 can be safely used in the presence of aligned labels. Since the | |
617 size of the branch itself is unknown, the size of the branch is | |
618 not included in the range. I.e. for a forward branch, the reference | |
619 address is the end address of the branch as known from the previous | |
620 branch shortening pass, minus a value to account for possible size | |
621 increase due to alignment. For a backward branch, it is the start | |
622 address of the branch as known from the current pass, plus a value | |
623 to account for possible size increase due to alignment. | |
624 NB.: Therefore, the maximum offset allowed for backward branches needs | |
625 to exclude the branch size. */ | |
626 | |
627 int | |
628 insn_current_reference_address (rtx branch) | |
629 { | |
630 rtx dest, seq; | |
631 int seq_uid; | |
632 | |
633 if (! INSN_ADDRESSES_SET_P ()) | |
634 return 0; | |
635 | |
636 seq = NEXT_INSN (PREV_INSN (branch)); | |
637 seq_uid = INSN_UID (seq); | |
638 if (!JUMP_P (branch)) | |
639 /* This can happen for example on the PA; the objective is to know the | |
640 offset to address something in front of the start of the function. | |
641 Thus, we can treat it like a backward branch. | |
642 We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than | |
643 any alignment we'd encounter, so we skip the call to align_fuzz. */ | |
644 return insn_current_address; | |
645 dest = JUMP_LABEL (branch); | |
646 | |
647 /* BRANCH has no proper alignment chain set, so use SEQ. | |
648 BRANCH also has no INSN_SHUID. */ | |
649 if (INSN_SHUID (seq) < INSN_SHUID (dest)) | |
650 { | |
651 /* Forward branch. */ | |
652 return (insn_last_address + insn_lengths[seq_uid] | |
653 - align_fuzz (seq, dest, length_unit_log, ~0)); | |
654 } | |
655 else | |
656 { | |
657 /* Backward branch. */ | |
658 return (insn_current_address | |
659 + align_fuzz (dest, seq, length_unit_log, ~0)); | |
660 } | |
661 } | |
662 #endif /* HAVE_ATTR_length */ | |
663 | |
664 /* Compute branch alignments based on frequency information in the | |
665 CFG. */ | |
666 | |
667 unsigned int | |
668 compute_alignments (void) | |
669 { | |
670 int log, max_skip, max_log; | |
671 basic_block bb; | |
672 int freq_max = 0; | |
673 int freq_threshold = 0; | |
674 | |
675 if (label_align) | |
676 { | |
677 free (label_align); | |
678 label_align = 0; | |
679 } | |
680 | |
681 max_labelno = max_label_num (); | |
682 min_labelno = get_first_label_num (); | |
683 label_align = XCNEWVEC (struct label_alignment, max_labelno - min_labelno + 1); | |
684 | |
685 /* If not optimizing or optimizing for size, don't assign any alignments. */ | |
686 if (! optimize || optimize_function_for_size_p (cfun)) | |
687 return 0; | |
688 | |
689 if (dump_file) | |
690 { | |
691 dump_flow_info (dump_file, TDF_DETAILS); | |
692 flow_loops_dump (dump_file, NULL, 1); | |
693 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | |
694 } | |
695 FOR_EACH_BB (bb) | |
696 if (bb->frequency > freq_max) | |
697 freq_max = bb->frequency; | |
698 freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD); | |
699 | |
700 if (dump_file) | |
701 fprintf(dump_file, "freq_max: %i\n",freq_max); | |
702 FOR_EACH_BB (bb) | |
703 { | |
704 rtx label = BB_HEAD (bb); | |
705 int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0; | |
706 edge e; | |
707 edge_iterator ei; | |
708 | |
709 if (!LABEL_P (label) | |
710 || optimize_bb_for_size_p (bb)) | |
711 { | |
712 if (dump_file) | |
713 fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n", | |
714 bb->index, bb->frequency, bb->loop_father->num, bb->loop_depth); | |
715 continue; | |
716 } | |
717 max_log = LABEL_ALIGN (label); | |
718 max_skip = LABEL_ALIGN_MAX_SKIP; | |
719 | |
720 FOR_EACH_EDGE (e, ei, bb->preds) | |
721 { | |
722 if (e->flags & EDGE_FALLTHRU) | |
723 has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e); | |
724 else | |
725 branch_frequency += EDGE_FREQUENCY (e); | |
726 } | |
727 if (dump_file) | |
728 { | |
729 fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i fall %4i branch %4i", | |
730 bb->index, bb->frequency, bb->loop_father->num, | |
731 bb->loop_depth, | |
732 fallthru_frequency, branch_frequency); | |
733 if (!bb->loop_father->inner && bb->loop_father->num) | |
734 fprintf (dump_file, " inner_loop"); | |
735 if (bb->loop_father->header == bb) | |
736 fprintf (dump_file, " loop_header"); | |
737 fprintf (dump_file, "\n"); | |
738 } | |
739 | |
740 /* There are two purposes to align block with no fallthru incoming edge: | |
741 1) to avoid fetch stalls when branch destination is near cache boundary | |
742 2) to improve cache efficiency in case the previous block is not executed | |
743 (so it does not need to be in the cache). | |
744 | |
745 We to catch first case, we align frequently executed blocks. | |
746 To catch the second, we align blocks that are executed more frequently | |
747 than the predecessor and the predecessor is likely to not be executed | |
748 when function is called. */ | |
749 | |
750 if (!has_fallthru | |
751 && (branch_frequency > freq_threshold | |
752 || (bb->frequency > bb->prev_bb->frequency * 10 | |
753 && (bb->prev_bb->frequency | |
754 <= ENTRY_BLOCK_PTR->frequency / 2)))) | |
755 { | |
756 log = JUMP_ALIGN (label); | |
757 if (dump_file) | |
758 fprintf(dump_file, " jump alignment added.\n"); | |
759 if (max_log < log) | |
760 { | |
761 max_log = log; | |
762 max_skip = JUMP_ALIGN_MAX_SKIP; | |
763 } | |
764 } | |
765 /* In case block is frequent and reached mostly by non-fallthru edge, | |
766 align it. It is most likely a first block of loop. */ | |
767 if (has_fallthru | |
768 && optimize_bb_for_speed_p (bb) | |
769 && branch_frequency + fallthru_frequency > freq_threshold | |
770 && (branch_frequency | |
771 > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS))) | |
772 { | |
773 log = LOOP_ALIGN (label); | |
774 if (dump_file) | |
775 fprintf(dump_file, " internal loop alignment added.\n"); | |
776 if (max_log < log) | |
777 { | |
778 max_log = log; | |
779 max_skip = LOOP_ALIGN_MAX_SKIP; | |
780 } | |
781 } | |
782 LABEL_TO_ALIGNMENT (label) = max_log; | |
783 LABEL_TO_MAX_SKIP (label) = max_skip; | |
784 } | |
785 | |
786 if (dump_file) | |
787 { | |
788 loop_optimizer_finalize (); | |
789 free_dominance_info (CDI_DOMINATORS); | |
790 } | |
791 return 0; | |
792 } | |
793 | |
794 struct rtl_opt_pass pass_compute_alignments = | |
795 { | |
796 { | |
797 RTL_PASS, | |
798 "alignments", /* name */ | |
799 NULL, /* gate */ | |
800 compute_alignments, /* execute */ | |
801 NULL, /* sub */ | |
802 NULL, /* next */ | |
803 0, /* static_pass_number */ | |
804 0, /* tv_id */ | |
805 0, /* properties_required */ | |
806 0, /* properties_provided */ | |
807 0, /* properties_destroyed */ | |
808 0, /* todo_flags_start */ | |
809 TODO_dump_func | TODO_verify_rtl_sharing | |
810 | TODO_ggc_collect /* todo_flags_finish */ | |
811 } | |
812 }; | |
813 | |
814 | |
815 /* Make a pass over all insns and compute their actual lengths by shortening | |
816 any branches of variable length if possible. */ | |
817 | |
818 /* shorten_branches might be called multiple times: for example, the SH | |
819 port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG. | |
820 In order to do this, it needs proper length information, which it obtains | |
821 by calling shorten_branches. This cannot be collapsed with | |
822 shorten_branches itself into a single pass unless we also want to integrate | |
823 reorg.c, since the branch splitting exposes new instructions with delay | |
824 slots. */ | |
825 | |
826 void | |
827 shorten_branches (rtx first ATTRIBUTE_UNUSED) | |
828 { | |
829 rtx insn; | |
830 int max_uid; | |
831 int i; | |
832 int max_log; | |
833 int max_skip; | |
834 #ifdef HAVE_ATTR_length | |
835 #define MAX_CODE_ALIGN 16 | |
836 rtx seq; | |
837 int something_changed = 1; | |
838 char *varying_length; | |
839 rtx body; | |
840 int uid; | |
841 rtx align_tab[MAX_CODE_ALIGN]; | |
842 | |
843 #endif | |
844 | |
845 /* Compute maximum UID and allocate label_align / uid_shuid. */ | |
846 max_uid = get_max_uid (); | |
847 | |
848 /* Free uid_shuid before reallocating it. */ | |
849 free (uid_shuid); | |
850 | |
851 uid_shuid = XNEWVEC (int, max_uid); | |
852 | |
853 if (max_labelno != max_label_num ()) | |
854 { | |
855 int old = max_labelno; | |
856 int n_labels; | |
857 int n_old_labels; | |
858 | |
859 max_labelno = max_label_num (); | |
860 | |
861 n_labels = max_labelno - min_labelno + 1; | |
862 n_old_labels = old - min_labelno + 1; | |
863 | |
864 label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); | |
865 | |
866 /* Range of labels grows monotonically in the function. Failing here | |
867 means that the initialization of array got lost. */ | |
868 gcc_assert (n_old_labels <= n_labels); | |
869 | |
870 memset (label_align + n_old_labels, 0, | |
871 (n_labels - n_old_labels) * sizeof (struct label_alignment)); | |
872 } | |
873 | |
874 /* Initialize label_align and set up uid_shuid to be strictly | |
875 monotonically rising with insn order. */ | |
876 /* We use max_log here to keep track of the maximum alignment we want to | |
877 impose on the next CODE_LABEL (or the current one if we are processing | |
878 the CODE_LABEL itself). */ | |
879 | |
880 max_log = 0; | |
881 max_skip = 0; | |
882 | |
883 for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn)) | |
884 { | |
885 int log; | |
886 | |
887 INSN_SHUID (insn) = i++; | |
888 if (INSN_P (insn)) | |
889 continue; | |
890 | |
891 if (LABEL_P (insn)) | |
892 { | |
893 rtx next; | |
894 | |
895 /* Merge in alignments computed by compute_alignments. */ | |
896 log = LABEL_TO_ALIGNMENT (insn); | |
897 if (max_log < log) | |
898 { | |
899 max_log = log; | |
900 max_skip = LABEL_TO_MAX_SKIP (insn); | |
901 } | |
902 | |
903 log = LABEL_ALIGN (insn); | |
904 if (max_log < log) | |
905 { | |
906 max_log = log; | |
907 max_skip = LABEL_ALIGN_MAX_SKIP; | |
908 } | |
909 next = next_nonnote_insn (insn); | |
910 /* ADDR_VECs only take room if read-only data goes into the text | |
911 section. */ | |
912 if (JUMP_TABLES_IN_TEXT_SECTION | |
913 || readonly_data_section == text_section) | |
914 if (next && JUMP_P (next)) | |
915 { | |
916 rtx nextbody = PATTERN (next); | |
917 if (GET_CODE (nextbody) == ADDR_VEC | |
918 || GET_CODE (nextbody) == ADDR_DIFF_VEC) | |
919 { | |
920 log = ADDR_VEC_ALIGN (next); | |
921 if (max_log < log) | |
922 { | |
923 max_log = log; | |
924 max_skip = LABEL_ALIGN_MAX_SKIP; | |
925 } | |
926 } | |
927 } | |
928 LABEL_TO_ALIGNMENT (insn) = max_log; | |
929 LABEL_TO_MAX_SKIP (insn) = max_skip; | |
930 max_log = 0; | |
931 max_skip = 0; | |
932 } | |
933 else if (BARRIER_P (insn)) | |
934 { | |
935 rtx label; | |
936 | |
937 for (label = insn; label && ! INSN_P (label); | |
938 label = NEXT_INSN (label)) | |
939 if (LABEL_P (label)) | |
940 { | |
941 log = LABEL_ALIGN_AFTER_BARRIER (insn); | |
942 if (max_log < log) | |
943 { | |
944 max_log = log; | |
945 max_skip = LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP; | |
946 } | |
947 break; | |
948 } | |
949 } | |
950 } | |
951 #ifdef HAVE_ATTR_length | |
952 | |
953 /* Allocate the rest of the arrays. */ | |
954 insn_lengths = XNEWVEC (int, max_uid); | |
955 insn_lengths_max_uid = max_uid; | |
956 /* Syntax errors can lead to labels being outside of the main insn stream. | |
957 Initialize insn_addresses, so that we get reproducible results. */ | |
958 INSN_ADDRESSES_ALLOC (max_uid); | |
959 | |
960 varying_length = XCNEWVEC (char, max_uid); | |
961 | |
962 /* Initialize uid_align. We scan instructions | |
963 from end to start, and keep in align_tab[n] the last seen insn | |
964 that does an alignment of at least n+1, i.e. the successor | |
965 in the alignment chain for an insn that does / has a known | |
966 alignment of n. */ | |
967 uid_align = XCNEWVEC (rtx, max_uid); | |
968 | |
969 for (i = MAX_CODE_ALIGN; --i >= 0;) | |
970 align_tab[i] = NULL_RTX; | |
971 seq = get_last_insn (); | |
972 for (; seq; seq = PREV_INSN (seq)) | |
973 { | |
974 int uid = INSN_UID (seq); | |
975 int log; | |
976 log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq) : 0); | |
977 uid_align[uid] = align_tab[0]; | |
978 if (log) | |
979 { | |
980 /* Found an alignment label. */ | |
981 uid_align[uid] = align_tab[log]; | |
982 for (i = log - 1; i >= 0; i--) | |
983 align_tab[i] = seq; | |
984 } | |
985 } | |
986 #ifdef CASE_VECTOR_SHORTEN_MODE | |
987 if (optimize) | |
988 { | |
989 /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum | |
990 label fields. */ | |
991 | |
992 int min_shuid = INSN_SHUID (get_insns ()) - 1; | |
993 int max_shuid = INSN_SHUID (get_last_insn ()) + 1; | |
994 int rel; | |
995 | |
996 for (insn = first; insn != 0; insn = NEXT_INSN (insn)) | |
997 { | |
998 rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat; | |
999 int len, i, min, max, insn_shuid; | |
1000 int min_align; | |
1001 addr_diff_vec_flags flags; | |
1002 | |
1003 if (!JUMP_P (insn) | |
1004 || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC) | |
1005 continue; | |
1006 pat = PATTERN (insn); | |
1007 len = XVECLEN (pat, 1); | |
1008 gcc_assert (len > 0); | |
1009 min_align = MAX_CODE_ALIGN; | |
1010 for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--) | |
1011 { | |
1012 rtx lab = XEXP (XVECEXP (pat, 1, i), 0); | |
1013 int shuid = INSN_SHUID (lab); | |
1014 if (shuid < min) | |
1015 { | |
1016 min = shuid; | |
1017 min_lab = lab; | |
1018 } | |
1019 if (shuid > max) | |
1020 { | |
1021 max = shuid; | |
1022 max_lab = lab; | |
1023 } | |
1024 if (min_align > LABEL_TO_ALIGNMENT (lab)) | |
1025 min_align = LABEL_TO_ALIGNMENT (lab); | |
1026 } | |
1027 XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab); | |
1028 XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab); | |
1029 insn_shuid = INSN_SHUID (insn); | |
1030 rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0)); | |
1031 memset (&flags, 0, sizeof (flags)); | |
1032 flags.min_align = min_align; | |
1033 flags.base_after_vec = rel > insn_shuid; | |
1034 flags.min_after_vec = min > insn_shuid; | |
1035 flags.max_after_vec = max > insn_shuid; | |
1036 flags.min_after_base = min > rel; | |
1037 flags.max_after_base = max > rel; | |
1038 ADDR_DIFF_VEC_FLAGS (pat) = flags; | |
1039 } | |
1040 } | |
1041 #endif /* CASE_VECTOR_SHORTEN_MODE */ | |
1042 | |
1043 /* Compute initial lengths, addresses, and varying flags for each insn. */ | |
1044 for (insn_current_address = 0, insn = first; | |
1045 insn != 0; | |
1046 insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn)) | |
1047 { | |
1048 uid = INSN_UID (insn); | |
1049 | |
1050 insn_lengths[uid] = 0; | |
1051 | |
1052 if (LABEL_P (insn)) | |
1053 { | |
1054 int log = LABEL_TO_ALIGNMENT (insn); | |
1055 if (log) | |
1056 { | |
1057 int align = 1 << log; | |
1058 int new_address = (insn_current_address + align - 1) & -align; | |
1059 insn_lengths[uid] = new_address - insn_current_address; | |
1060 } | |
1061 } | |
1062 | |
1063 INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid]; | |
1064 | |
1065 if (NOTE_P (insn) || BARRIER_P (insn) | |
1066 || LABEL_P (insn)) | |
1067 continue; | |
1068 if (INSN_DELETED_P (insn)) | |
1069 continue; | |
1070 | |
1071 body = PATTERN (insn); | |
1072 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) | |
1073 { | |
1074 /* This only takes room if read-only data goes into the text | |
1075 section. */ | |
1076 if (JUMP_TABLES_IN_TEXT_SECTION | |
1077 || readonly_data_section == text_section) | |
1078 insn_lengths[uid] = (XVECLEN (body, | |
1079 GET_CODE (body) == ADDR_DIFF_VEC) | |
1080 * GET_MODE_SIZE (GET_MODE (body))); | |
1081 /* Alignment is handled by ADDR_VEC_ALIGN. */ | |
1082 } | |
1083 else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) | |
1084 insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn); | |
1085 else if (GET_CODE (body) == SEQUENCE) | |
1086 { | |
1087 int i; | |
1088 int const_delay_slots; | |
1089 #ifdef DELAY_SLOTS | |
1090 const_delay_slots = const_num_delay_slots (XVECEXP (body, 0, 0)); | |
1091 #else | |
1092 const_delay_slots = 0; | |
1093 #endif | |
1094 /* Inside a delay slot sequence, we do not do any branch shortening | |
1095 if the shortening could change the number of delay slots | |
1096 of the branch. */ | |
1097 for (i = 0; i < XVECLEN (body, 0); i++) | |
1098 { | |
1099 rtx inner_insn = XVECEXP (body, 0, i); | |
1100 int inner_uid = INSN_UID (inner_insn); | |
1101 int inner_length; | |
1102 | |
1103 if (GET_CODE (body) == ASM_INPUT | |
1104 || asm_noperands (PATTERN (XVECEXP (body, 0, i))) >= 0) | |
1105 inner_length = (asm_insn_count (PATTERN (inner_insn)) | |
1106 * insn_default_length (inner_insn)); | |
1107 else | |
1108 inner_length = insn_default_length (inner_insn); | |
1109 | |
1110 insn_lengths[inner_uid] = inner_length; | |
1111 if (const_delay_slots) | |
1112 { | |
1113 if ((varying_length[inner_uid] | |
1114 = insn_variable_length_p (inner_insn)) != 0) | |
1115 varying_length[uid] = 1; | |
1116 INSN_ADDRESSES (inner_uid) = (insn_current_address | |
1117 + insn_lengths[uid]); | |
1118 } | |
1119 else | |
1120 varying_length[inner_uid] = 0; | |
1121 insn_lengths[uid] += inner_length; | |
1122 } | |
1123 } | |
1124 else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER) | |
1125 { | |
1126 insn_lengths[uid] = insn_default_length (insn); | |
1127 varying_length[uid] = insn_variable_length_p (insn); | |
1128 } | |
1129 | |
1130 /* If needed, do any adjustment. */ | |
1131 #ifdef ADJUST_INSN_LENGTH | |
1132 ADJUST_INSN_LENGTH (insn, insn_lengths[uid]); | |
1133 if (insn_lengths[uid] < 0) | |
1134 fatal_insn ("negative insn length", insn); | |
1135 #endif | |
1136 } | |
1137 | |
1138 /* Now loop over all the insns finding varying length insns. For each, | |
1139 get the current insn length. If it has changed, reflect the change. | |
1140 When nothing changes for a full pass, we are done. */ | |
1141 | |
1142 while (something_changed) | |
1143 { | |
1144 something_changed = 0; | |
1145 insn_current_align = MAX_CODE_ALIGN - 1; | |
1146 for (insn_current_address = 0, insn = first; | |
1147 insn != 0; | |
1148 insn = NEXT_INSN (insn)) | |
1149 { | |
1150 int new_length; | |
1151 #ifdef ADJUST_INSN_LENGTH | |
1152 int tmp_length; | |
1153 #endif | |
1154 int length_align; | |
1155 | |
1156 uid = INSN_UID (insn); | |
1157 | |
1158 if (LABEL_P (insn)) | |
1159 { | |
1160 int log = LABEL_TO_ALIGNMENT (insn); | |
1161 if (log > insn_current_align) | |
1162 { | |
1163 int align = 1 << log; | |
1164 int new_address= (insn_current_address + align - 1) & -align; | |
1165 insn_lengths[uid] = new_address - insn_current_address; | |
1166 insn_current_align = log; | |
1167 insn_current_address = new_address; | |
1168 } | |
1169 else | |
1170 insn_lengths[uid] = 0; | |
1171 INSN_ADDRESSES (uid) = insn_current_address; | |
1172 continue; | |
1173 } | |
1174 | |
1175 length_align = INSN_LENGTH_ALIGNMENT (insn); | |
1176 if (length_align < insn_current_align) | |
1177 insn_current_align = length_align; | |
1178 | |
1179 insn_last_address = INSN_ADDRESSES (uid); | |
1180 INSN_ADDRESSES (uid) = insn_current_address; | |
1181 | |
1182 #ifdef CASE_VECTOR_SHORTEN_MODE | |
1183 if (optimize && JUMP_P (insn) | |
1184 && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) | |
1185 { | |
1186 rtx body = PATTERN (insn); | |
1187 int old_length = insn_lengths[uid]; | |
1188 rtx rel_lab = XEXP (XEXP (body, 0), 0); | |
1189 rtx min_lab = XEXP (XEXP (body, 2), 0); | |
1190 rtx max_lab = XEXP (XEXP (body, 3), 0); | |
1191 int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab)); | |
1192 int min_addr = INSN_ADDRESSES (INSN_UID (min_lab)); | |
1193 int max_addr = INSN_ADDRESSES (INSN_UID (max_lab)); | |
1194 rtx prev; | |
1195 int rel_align = 0; | |
1196 addr_diff_vec_flags flags; | |
1197 | |
1198 /* Avoid automatic aggregate initialization. */ | |
1199 flags = ADDR_DIFF_VEC_FLAGS (body); | |
1200 | |
1201 /* Try to find a known alignment for rel_lab. */ | |
1202 for (prev = rel_lab; | |
1203 prev | |
1204 && ! insn_lengths[INSN_UID (prev)] | |
1205 && ! (varying_length[INSN_UID (prev)] & 1); | |
1206 prev = PREV_INSN (prev)) | |
1207 if (varying_length[INSN_UID (prev)] & 2) | |
1208 { | |
1209 rel_align = LABEL_TO_ALIGNMENT (prev); | |
1210 break; | |
1211 } | |
1212 | |
1213 /* See the comment on addr_diff_vec_flags in rtl.h for the | |
1214 meaning of the flags values. base: REL_LAB vec: INSN */ | |
1215 /* Anything after INSN has still addresses from the last | |
1216 pass; adjust these so that they reflect our current | |
1217 estimate for this pass. */ | |
1218 if (flags.base_after_vec) | |
1219 rel_addr += insn_current_address - insn_last_address; | |
1220 if (flags.min_after_vec) | |
1221 min_addr += insn_current_address - insn_last_address; | |
1222 if (flags.max_after_vec) | |
1223 max_addr += insn_current_address - insn_last_address; | |
1224 /* We want to know the worst case, i.e. lowest possible value | |
1225 for the offset of MIN_LAB. If MIN_LAB is after REL_LAB, | |
1226 its offset is positive, and we have to be wary of code shrink; | |
1227 otherwise, it is negative, and we have to be vary of code | |
1228 size increase. */ | |
1229 if (flags.min_after_base) | |
1230 { | |
1231 /* If INSN is between REL_LAB and MIN_LAB, the size | |
1232 changes we are about to make can change the alignment | |
1233 within the observed offset, therefore we have to break | |
1234 it up into two parts that are independent. */ | |
1235 if (! flags.base_after_vec && flags.min_after_vec) | |
1236 { | |
1237 min_addr -= align_fuzz (rel_lab, insn, rel_align, 0); | |
1238 min_addr -= align_fuzz (insn, min_lab, 0, 0); | |
1239 } | |
1240 else | |
1241 min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0); | |
1242 } | |
1243 else | |
1244 { | |
1245 if (flags.base_after_vec && ! flags.min_after_vec) | |
1246 { | |
1247 min_addr -= align_fuzz (min_lab, insn, 0, ~0); | |
1248 min_addr -= align_fuzz (insn, rel_lab, 0, ~0); | |
1249 } | |
1250 else | |
1251 min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0); | |
1252 } | |
1253 /* Likewise, determine the highest lowest possible value | |
1254 for the offset of MAX_LAB. */ | |
1255 if (flags.max_after_base) | |
1256 { | |
1257 if (! flags.base_after_vec && flags.max_after_vec) | |
1258 { | |
1259 max_addr += align_fuzz (rel_lab, insn, rel_align, ~0); | |
1260 max_addr += align_fuzz (insn, max_lab, 0, ~0); | |
1261 } | |
1262 else | |
1263 max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0); | |
1264 } | |
1265 else | |
1266 { | |
1267 if (flags.base_after_vec && ! flags.max_after_vec) | |
1268 { | |
1269 max_addr += align_fuzz (max_lab, insn, 0, 0); | |
1270 max_addr += align_fuzz (insn, rel_lab, 0, 0); | |
1271 } | |
1272 else | |
1273 max_addr += align_fuzz (max_lab, rel_lab, 0, 0); | |
1274 } | |
1275 PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr, | |
1276 max_addr - rel_addr, | |
1277 body)); | |
1278 if (JUMP_TABLES_IN_TEXT_SECTION | |
1279 || readonly_data_section == text_section) | |
1280 { | |
1281 insn_lengths[uid] | |
1282 = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body))); | |
1283 insn_current_address += insn_lengths[uid]; | |
1284 if (insn_lengths[uid] != old_length) | |
1285 something_changed = 1; | |
1286 } | |
1287 | |
1288 continue; | |
1289 } | |
1290 #endif /* CASE_VECTOR_SHORTEN_MODE */ | |
1291 | |
1292 if (! (varying_length[uid])) | |
1293 { | |
1294 if (NONJUMP_INSN_P (insn) | |
1295 && GET_CODE (PATTERN (insn)) == SEQUENCE) | |
1296 { | |
1297 int i; | |
1298 | |
1299 body = PATTERN (insn); | |
1300 for (i = 0; i < XVECLEN (body, 0); i++) | |
1301 { | |
1302 rtx inner_insn = XVECEXP (body, 0, i); | |
1303 int inner_uid = INSN_UID (inner_insn); | |
1304 | |
1305 INSN_ADDRESSES (inner_uid) = insn_current_address; | |
1306 | |
1307 insn_current_address += insn_lengths[inner_uid]; | |
1308 } | |
1309 } | |
1310 else | |
1311 insn_current_address += insn_lengths[uid]; | |
1312 | |
1313 continue; | |
1314 } | |
1315 | |
1316 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) | |
1317 { | |
1318 int i; | |
1319 | |
1320 body = PATTERN (insn); | |
1321 new_length = 0; | |
1322 for (i = 0; i < XVECLEN (body, 0); i++) | |
1323 { | |
1324 rtx inner_insn = XVECEXP (body, 0, i); | |
1325 int inner_uid = INSN_UID (inner_insn); | |
1326 int inner_length; | |
1327 | |
1328 INSN_ADDRESSES (inner_uid) = insn_current_address; | |
1329 | |
1330 /* insn_current_length returns 0 for insns with a | |
1331 non-varying length. */ | |
1332 if (! varying_length[inner_uid]) | |
1333 inner_length = insn_lengths[inner_uid]; | |
1334 else | |
1335 inner_length = insn_current_length (inner_insn); | |
1336 | |
1337 if (inner_length != insn_lengths[inner_uid]) | |
1338 { | |
1339 insn_lengths[inner_uid] = inner_length; | |
1340 something_changed = 1; | |
1341 } | |
1342 insn_current_address += insn_lengths[inner_uid]; | |
1343 new_length += inner_length; | |
1344 } | |
1345 } | |
1346 else | |
1347 { | |
1348 new_length = insn_current_length (insn); | |
1349 insn_current_address += new_length; | |
1350 } | |
1351 | |
1352 #ifdef ADJUST_INSN_LENGTH | |
1353 /* If needed, do any adjustment. */ | |
1354 tmp_length = new_length; | |
1355 ADJUST_INSN_LENGTH (insn, new_length); | |
1356 insn_current_address += (new_length - tmp_length); | |
1357 #endif | |
1358 | |
1359 if (new_length != insn_lengths[uid]) | |
1360 { | |
1361 insn_lengths[uid] = new_length; | |
1362 something_changed = 1; | |
1363 } | |
1364 } | |
1365 /* For a non-optimizing compile, do only a single pass. */ | |
1366 if (!optimize) | |
1367 break; | |
1368 } | |
1369 | |
1370 free (varying_length); | |
1371 | |
1372 #endif /* HAVE_ATTR_length */ | |
1373 } | |
1374 | |
1375 #ifdef HAVE_ATTR_length | |
1376 /* Given the body of an INSN known to be generated by an ASM statement, return | |
1377 the number of machine instructions likely to be generated for this insn. | |
1378 This is used to compute its length. */ | |
1379 | |
1380 static int | |
1381 asm_insn_count (rtx body) | |
1382 { | |
1383 const char *templ; | |
1384 int count = 1; | |
1385 | |
1386 if (GET_CODE (body) == ASM_INPUT) | |
1387 templ = XSTR (body, 0); | |
1388 else | |
1389 templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL); | |
1390 | |
1391 if (!*templ) | |
1392 return 0; | |
1393 | |
1394 for (; *templ; templ++) | |
1395 if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ) | |
1396 || *templ == '\n') | |
1397 count++; | |
1398 | |
1399 return count; | |
1400 } | |
1401 #endif | |
1402 | |
1403 /* ??? This is probably the wrong place for these. */ | |
1404 /* Structure recording the mapping from source file and directory | |
1405 names at compile time to those to be embedded in debug | |
1406 information. */ | |
1407 typedef struct debug_prefix_map | |
1408 { | |
1409 const char *old_prefix; | |
1410 const char *new_prefix; | |
1411 size_t old_len; | |
1412 size_t new_len; | |
1413 struct debug_prefix_map *next; | |
1414 } debug_prefix_map; | |
1415 | |
1416 /* Linked list of such structures. */ | |
1417 debug_prefix_map *debug_prefix_maps; | |
1418 | |
1419 | |
1420 /* Record a debug file prefix mapping. ARG is the argument to | |
1421 -fdebug-prefix-map and must be of the form OLD=NEW. */ | |
1422 | |
1423 void | |
1424 add_debug_prefix_map (const char *arg) | |
1425 { | |
1426 debug_prefix_map *map; | |
1427 const char *p; | |
1428 | |
1429 p = strchr (arg, '='); | |
1430 if (!p) | |
1431 { | |
1432 error ("invalid argument %qs to -fdebug-prefix-map", arg); | |
1433 return; | |
1434 } | |
1435 map = XNEW (debug_prefix_map); | |
1436 map->old_prefix = ggc_alloc_string (arg, p - arg); | |
1437 map->old_len = p - arg; | |
1438 p++; | |
1439 map->new_prefix = ggc_strdup (p); | |
1440 map->new_len = strlen (p); | |
1441 map->next = debug_prefix_maps; | |
1442 debug_prefix_maps = map; | |
1443 } | |
1444 | |
1445 /* Perform user-specified mapping of debug filename prefixes. Return | |
1446 the new name corresponding to FILENAME. */ | |
1447 | |
1448 const char * | |
1449 remap_debug_filename (const char *filename) | |
1450 { | |
1451 debug_prefix_map *map; | |
1452 char *s; | |
1453 const char *name; | |
1454 size_t name_len; | |
1455 | |
1456 for (map = debug_prefix_maps; map; map = map->next) | |
1457 if (strncmp (filename, map->old_prefix, map->old_len) == 0) | |
1458 break; | |
1459 if (!map) | |
1460 return filename; | |
1461 name = filename + map->old_len; | |
1462 name_len = strlen (name) + 1; | |
1463 s = (char *) alloca (name_len + map->new_len); | |
1464 memcpy (s, map->new_prefix, map->new_len); | |
1465 memcpy (s + map->new_len, name, name_len); | |
1466 return ggc_strdup (s); | |
1467 } | |
1468 | |
1469 /* Output assembler code for the start of a function, | |
1470 and initialize some of the variables in this file | |
1471 for the new function. The label for the function and associated | |
1472 assembler pseudo-ops have already been output in `assemble_start_function'. | |
1473 | |
1474 FIRST is the first insn of the rtl for the function being compiled. | |
1475 FILE is the file to write assembler code to. | |
1476 OPTIMIZE is nonzero if we should eliminate redundant | |
1477 test and compare insns. */ | |
1478 | |
1479 void | |
1480 final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, | |
1481 int optimize ATTRIBUTE_UNUSED) | |
1482 { | |
1483 block_depth = 0; | |
1484 | |
1485 this_is_asm_operands = 0; | |
1486 | |
1487 last_filename = locator_file (prologue_locator); | |
1488 last_linenum = locator_line (prologue_locator); | |
1489 | |
1490 high_block_linenum = high_function_linenum = last_linenum; | |
1491 | |
1492 (*debug_hooks->begin_prologue) (last_linenum, last_filename); | |
1493 | |
1494 #if defined (DWARF2_UNWIND_INFO) || defined (TARGET_UNWIND_INFO) | |
1495 if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG) | |
1496 dwarf2out_begin_prologue (0, NULL); | |
1497 #endif | |
1498 | |
1499 #ifdef LEAF_REG_REMAP | |
1500 if (current_function_uses_only_leaf_regs) | |
1501 leaf_renumber_regs (first); | |
1502 #endif | |
1503 | |
1504 /* The Sun386i and perhaps other machines don't work right | |
1505 if the profiling code comes after the prologue. */ | |
1506 #ifdef PROFILE_BEFORE_PROLOGUE | |
1507 if (crtl->profile) | |
1508 profile_function (file); | |
1509 #endif /* PROFILE_BEFORE_PROLOGUE */ | |
1510 | |
1511 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue) | |
1512 if (dwarf2out_do_frame ()) | |
1513 dwarf2out_frame_debug (NULL_RTX, false); | |
1514 #endif | |
1515 | |
1516 /* If debugging, assign block numbers to all of the blocks in this | |
1517 function. */ | |
1518 if (write_symbols) | |
1519 { | |
1520 reemit_insn_block_notes (); | |
1521 number_blocks (current_function_decl); | |
1522 /* We never actually put out begin/end notes for the top-level | |
1523 block in the function. But, conceptually, that block is | |
1524 always needed. */ | |
1525 TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1; | |
1526 } | |
1527 | |
1528 if (warn_frame_larger_than | |
1529 && get_frame_size () > frame_larger_than_size) | |
1530 { | |
1531 /* Issue a warning */ | |
1532 warning (OPT_Wframe_larger_than_, | |
1533 "the frame size of %wd bytes is larger than %wd bytes", | |
1534 get_frame_size (), frame_larger_than_size); | |
1535 } | |
1536 | |
1537 /* First output the function prologue: code to set up the stack frame. */ | |
1538 targetm.asm_out.function_prologue (file, get_frame_size ()); | |
1539 | |
1540 /* If the machine represents the prologue as RTL, the profiling code must | |
1541 be emitted when NOTE_INSN_PROLOGUE_END is scanned. */ | |
1542 #ifdef HAVE_prologue | |
1543 if (! HAVE_prologue) | |
1544 #endif | |
1545 profile_after_prologue (file); | |
1546 } | |
1547 | |
1548 static void | |
1549 profile_after_prologue (FILE *file ATTRIBUTE_UNUSED) | |
1550 { | |
1551 #ifndef PROFILE_BEFORE_PROLOGUE | |
1552 if (crtl->profile) | |
1553 profile_function (file); | |
1554 #endif /* not PROFILE_BEFORE_PROLOGUE */ | |
1555 } | |
1556 | |
1557 static void | |
1558 profile_function (FILE *file ATTRIBUTE_UNUSED) | |
1559 { | |
1560 #ifndef NO_PROFILE_COUNTERS | |
1561 # define NO_PROFILE_COUNTERS 0 | |
1562 #endif | |
1563 #if defined(ASM_OUTPUT_REG_PUSH) | |
1564 int sval = cfun->returns_struct; | |
1565 rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1); | |
1566 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM) | |
1567 int cxt = cfun->static_chain_decl != NULL; | |
1568 #endif | |
1569 #endif /* ASM_OUTPUT_REG_PUSH */ | |
1570 | |
1571 if (! NO_PROFILE_COUNTERS) | |
1572 { | |
1573 int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE); | |
1574 switch_to_section (data_section); | |
1575 ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); | |
1576 targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no); | |
1577 assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1); | |
1578 } | |
1579 | |
1580 switch_to_section (current_function_section ()); | |
1581 | |
1582 #if defined(ASM_OUTPUT_REG_PUSH) | |
1583 if (sval && svrtx != NULL_RTX && REG_P (svrtx)) | |
1584 { | |
1585 ASM_OUTPUT_REG_PUSH (file, REGNO (svrtx)); | |
1586 } | |
1587 #endif | |
1588 | |
1589 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) | |
1590 if (cxt) | |
1591 ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_INCOMING_REGNUM); | |
1592 #else | |
1593 #if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) | |
1594 if (cxt) | |
1595 { | |
1596 ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM); | |
1597 } | |
1598 #endif | |
1599 #endif | |
1600 | |
1601 FUNCTION_PROFILER (file, current_function_funcdef_no); | |
1602 | |
1603 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) | |
1604 if (cxt) | |
1605 ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM); | |
1606 #else | |
1607 #if defined(STATIC_CHAIN_REGNUM) && defined(ASM_OUTPUT_REG_PUSH) | |
1608 if (cxt) | |
1609 { | |
1610 ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_REGNUM); | |
1611 } | |
1612 #endif | |
1613 #endif | |
1614 | |
1615 #if defined(ASM_OUTPUT_REG_PUSH) | |
1616 if (sval && svrtx != NULL_RTX && REG_P (svrtx)) | |
1617 { | |
1618 ASM_OUTPUT_REG_POP (file, REGNO (svrtx)); | |
1619 } | |
1620 #endif | |
1621 } | |
1622 | |
1623 /* Output assembler code for the end of a function. | |
1624 For clarity, args are same as those of `final_start_function' | |
1625 even though not all of them are needed. */ | |
1626 | |
1627 void | |
1628 final_end_function (void) | |
1629 { | |
1630 app_disable (); | |
1631 | |
1632 (*debug_hooks->end_function) (high_function_linenum); | |
1633 | |
1634 /* Finally, output the function epilogue: | |
1635 code to restore the stack frame and return to the caller. */ | |
1636 targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ()); | |
1637 | |
1638 /* And debug output. */ | |
1639 (*debug_hooks->end_epilogue) (last_linenum, last_filename); | |
1640 | |
1641 #if defined (DWARF2_UNWIND_INFO) | |
1642 if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG | |
1643 && dwarf2out_do_frame ()) | |
1644 dwarf2out_end_epilogue (last_linenum, last_filename); | |
1645 #endif | |
1646 } | |
1647 | |
1648 /* Output assembler code for some insns: all or part of a function. | |
1649 For description of args, see `final_start_function', above. */ | |
1650 | |
1651 void | |
1652 final (rtx first, FILE *file, int optimize) | |
1653 { | |
1654 rtx insn; | |
1655 int max_uid = 0; | |
1656 int seen = 0; | |
1657 | |
1658 last_ignored_compare = 0; | |
1659 | |
1660 for (insn = first; insn; insn = NEXT_INSN (insn)) | |
1661 { | |
1662 if (INSN_UID (insn) > max_uid) /* Find largest UID. */ | |
1663 max_uid = INSN_UID (insn); | |
1664 #ifdef HAVE_cc0 | |
1665 /* If CC tracking across branches is enabled, record the insn which | |
1666 jumps to each branch only reached from one place. */ | |
1667 if (optimize && JUMP_P (insn)) | |
1668 { | |
1669 rtx lab = JUMP_LABEL (insn); | |
1670 if (lab && LABEL_NUSES (lab) == 1) | |
1671 { | |
1672 LABEL_REFS (lab) = insn; | |
1673 } | |
1674 } | |
1675 #endif | |
1676 } | |
1677 | |
1678 init_recog (); | |
1679 | |
1680 CC_STATUS_INIT; | |
1681 | |
1682 /* Output the insns. */ | |
1683 for (insn = first; insn;) | |
1684 { | |
1685 #ifdef HAVE_ATTR_length | |
1686 if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ()) | |
1687 { | |
1688 /* This can be triggered by bugs elsewhere in the compiler if | |
1689 new insns are created after init_insn_lengths is called. */ | |
1690 gcc_assert (NOTE_P (insn)); | |
1691 insn_current_address = -1; | |
1692 } | |
1693 else | |
1694 insn_current_address = INSN_ADDRESSES (INSN_UID (insn)); | |
1695 #endif /* HAVE_ATTR_length */ | |
1696 | |
1697 insn = final_scan_insn (insn, file, optimize, 0, &seen); | |
1698 } | |
1699 } | |
1700 | |
1701 const char * | |
1702 get_insn_template (int code, rtx insn) | |
1703 { | |
1704 switch (insn_data[code].output_format) | |
1705 { | |
1706 case INSN_OUTPUT_FORMAT_SINGLE: | |
1707 return insn_data[code].output.single; | |
1708 case INSN_OUTPUT_FORMAT_MULTI: | |
1709 return insn_data[code].output.multi[which_alternative]; | |
1710 case INSN_OUTPUT_FORMAT_FUNCTION: | |
1711 gcc_assert (insn); | |
1712 return (*insn_data[code].output.function) (recog_data.operand, insn); | |
1713 | |
1714 default: | |
1715 gcc_unreachable (); | |
1716 } | |
1717 } | |
1718 | |
1719 /* Emit the appropriate declaration for an alternate-entry-point | |
1720 symbol represented by INSN, to FILE. INSN is a CODE_LABEL with | |
1721 LABEL_KIND != LABEL_NORMAL. | |
1722 | |
1723 The case fall-through in this function is intentional. */ | |
1724 static void | |
1725 output_alternate_entry_point (FILE *file, rtx insn) | |
1726 { | |
1727 const char *name = LABEL_NAME (insn); | |
1728 | |
1729 switch (LABEL_KIND (insn)) | |
1730 { | |
1731 case LABEL_WEAK_ENTRY: | |
1732 #ifdef ASM_WEAKEN_LABEL | |
1733 ASM_WEAKEN_LABEL (file, name); | |
1734 #endif | |
1735 case LABEL_GLOBAL_ENTRY: | |
1736 targetm.asm_out.globalize_label (file, name); | |
1737 case LABEL_STATIC_ENTRY: | |
1738 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE | |
1739 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); | |
1740 #endif | |
1741 ASM_OUTPUT_LABEL (file, name); | |
1742 break; | |
1743 | |
1744 case LABEL_NORMAL: | |
1745 default: | |
1746 gcc_unreachable (); | |
1747 } | |
1748 } | |
1749 | |
1750 /* Given a CALL_INSN, find and return the nested CALL. */ | |
1751 static rtx | |
1752 call_from_call_insn (rtx insn) | |
1753 { | |
1754 rtx x; | |
1755 gcc_assert (CALL_P (insn)); | |
1756 x = PATTERN (insn); | |
1757 | |
1758 while (GET_CODE (x) != CALL) | |
1759 { | |
1760 switch (GET_CODE (x)) | |
1761 { | |
1762 default: | |
1763 gcc_unreachable (); | |
1764 case COND_EXEC: | |
1765 x = COND_EXEC_CODE (x); | |
1766 break; | |
1767 case PARALLEL: | |
1768 x = XVECEXP (x, 0, 0); | |
1769 break; | |
1770 case SET: | |
1771 x = XEXP (x, 1); | |
1772 break; | |
1773 } | |
1774 } | |
1775 return x; | |
1776 } | |
1777 | |
1778 /* The final scan for one insn, INSN. | |
1779 Args are same as in `final', except that INSN | |
1780 is the insn being scanned. | |
1781 Value returned is the next insn to be scanned. | |
1782 | |
1783 NOPEEPHOLES is the flag to disallow peephole processing (currently | |
1784 used for within delayed branch sequence output). | |
1785 | |
1786 SEEN is used to track the end of the prologue, for emitting | |
1787 debug information. We force the emission of a line note after | |
1788 both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG, or | |
1789 at the beginning of the second basic block, whichever comes | |
1790 first. */ | |
1791 | |
1792 rtx | |
1793 final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, | |
1794 int nopeepholes ATTRIBUTE_UNUSED, int *seen) | |
1795 { | |
1796 #ifdef HAVE_cc0 | |
1797 rtx set; | |
1798 #endif | |
1799 rtx next; | |
1800 | |
1801 insn_counter++; | |
1802 | |
1803 /* Ignore deleted insns. These can occur when we split insns (due to a | |
1804 template of "#") while not optimizing. */ | |
1805 if (INSN_DELETED_P (insn)) | |
1806 return NEXT_INSN (insn); | |
1807 | |
1808 switch (GET_CODE (insn)) | |
1809 { | |
1810 case NOTE: | |
1811 switch (NOTE_KIND (insn)) | |
1812 { | |
1813 case NOTE_INSN_DELETED: | |
1814 break; | |
1815 | |
1816 case NOTE_INSN_SWITCH_TEXT_SECTIONS: | |
1817 in_cold_section_p = !in_cold_section_p; | |
1818 #ifdef DWARF2_UNWIND_INFO | |
1819 if (dwarf2out_do_frame ()) | |
1820 dwarf2out_switch_text_section (); | |
1821 else | |
1822 #endif | |
1823 (*debug_hooks->switch_text_section) (); | |
1824 | |
1825 switch_to_section (current_function_section ()); | |
1826 break; | |
1827 | |
1828 case NOTE_INSN_BASIC_BLOCK: | |
1829 #ifdef TARGET_UNWIND_INFO | |
1830 targetm.asm_out.unwind_emit (asm_out_file, insn); | |
1831 #endif | |
1832 | |
1833 if (flag_debug_asm) | |
1834 fprintf (asm_out_file, "\t%s basic block %d\n", | |
1835 ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index); | |
1836 | |
1837 if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB) | |
1838 { | |
1839 *seen |= SEEN_EMITTED; | |
1840 force_source_line = true; | |
1841 } | |
1842 else | |
1843 *seen |= SEEN_BB; | |
1844 | |
1845 break; | |
1846 | |
1847 case NOTE_INSN_EH_REGION_BEG: | |
1848 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB", | |
1849 NOTE_EH_HANDLER (insn)); | |
1850 break; | |
1851 | |
1852 case NOTE_INSN_EH_REGION_END: | |
1853 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE", | |
1854 NOTE_EH_HANDLER (insn)); | |
1855 break; | |
1856 | |
1857 case NOTE_INSN_PROLOGUE_END: | |
1858 targetm.asm_out.function_end_prologue (file); | |
1859 profile_after_prologue (file); | |
1860 | |
1861 if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE) | |
1862 { | |
1863 *seen |= SEEN_EMITTED; | |
1864 force_source_line = true; | |
1865 } | |
1866 else | |
1867 *seen |= SEEN_NOTE; | |
1868 | |
1869 break; | |
1870 | |
1871 case NOTE_INSN_EPILOGUE_BEG: | |
1872 targetm.asm_out.function_begin_epilogue (file); | |
1873 break; | |
1874 | |
1875 case NOTE_INSN_FUNCTION_BEG: | |
1876 app_disable (); | |
1877 (*debug_hooks->end_prologue) (last_linenum, last_filename); | |
1878 | |
1879 if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE) | |
1880 { | |
1881 *seen |= SEEN_EMITTED; | |
1882 force_source_line = true; | |
1883 } | |
1884 else | |
1885 *seen |= SEEN_NOTE; | |
1886 | |
1887 break; | |
1888 | |
1889 case NOTE_INSN_BLOCK_BEG: | |
1890 if (debug_info_level == DINFO_LEVEL_NORMAL | |
1891 || debug_info_level == DINFO_LEVEL_VERBOSE | |
1892 || write_symbols == DWARF2_DEBUG | |
1893 || write_symbols == VMS_AND_DWARF2_DEBUG | |
1894 || write_symbols == VMS_DEBUG) | |
1895 { | |
1896 int n = BLOCK_NUMBER (NOTE_BLOCK (insn)); | |
1897 | |
1898 app_disable (); | |
1899 ++block_depth; | |
1900 high_block_linenum = last_linenum; | |
1901 | |
1902 /* Output debugging info about the symbol-block beginning. */ | |
1903 (*debug_hooks->begin_block) (last_linenum, n); | |
1904 | |
1905 /* Mark this block as output. */ | |
1906 TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1; | |
1907 } | |
1908 if (write_symbols == DBX_DEBUG | |
1909 || write_symbols == SDB_DEBUG) | |
1910 { | |
1911 location_t *locus_ptr | |
1912 = block_nonartificial_location (NOTE_BLOCK (insn)); | |
1913 | |
1914 if (locus_ptr != NULL) | |
1915 { | |
1916 override_filename = LOCATION_FILE (*locus_ptr); | |
1917 override_linenum = LOCATION_LINE (*locus_ptr); | |
1918 } | |
1919 } | |
1920 break; | |
1921 | |
1922 case NOTE_INSN_BLOCK_END: | |
1923 if (debug_info_level == DINFO_LEVEL_NORMAL | |
1924 || debug_info_level == DINFO_LEVEL_VERBOSE | |
1925 || write_symbols == DWARF2_DEBUG | |
1926 || write_symbols == VMS_AND_DWARF2_DEBUG | |
1927 || write_symbols == VMS_DEBUG) | |
1928 { | |
1929 int n = BLOCK_NUMBER (NOTE_BLOCK (insn)); | |
1930 | |
1931 app_disable (); | |
1932 | |
1933 /* End of a symbol-block. */ | |
1934 --block_depth; | |
1935 gcc_assert (block_depth >= 0); | |
1936 | |
1937 (*debug_hooks->end_block) (high_block_linenum, n); | |
1938 } | |
1939 if (write_symbols == DBX_DEBUG | |
1940 || write_symbols == SDB_DEBUG) | |
1941 { | |
1942 tree outer_block = BLOCK_SUPERCONTEXT (NOTE_BLOCK (insn)); | |
1943 location_t *locus_ptr | |
1944 = block_nonartificial_location (outer_block); | |
1945 | |
1946 if (locus_ptr != NULL) | |
1947 { | |
1948 override_filename = LOCATION_FILE (*locus_ptr); | |
1949 override_linenum = LOCATION_LINE (*locus_ptr); | |
1950 } | |
1951 else | |
1952 { | |
1953 override_filename = NULL; | |
1954 override_linenum = 0; | |
1955 } | |
1956 } | |
1957 break; | |
1958 | |
1959 case NOTE_INSN_DELETED_LABEL: | |
1960 /* Emit the label. We may have deleted the CODE_LABEL because | |
1961 the label could be proved to be unreachable, though still | |
1962 referenced (in the form of having its address taken. */ | |
1963 ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); | |
1964 break; | |
1965 | |
1966 case NOTE_INSN_VAR_LOCATION: | |
1967 (*debug_hooks->var_location) (insn); | |
1968 break; | |
1969 | |
1970 default: | |
1971 gcc_unreachable (); | |
1972 break; | |
1973 } | |
1974 break; | |
1975 | |
1976 case BARRIER: | |
1977 #if defined (DWARF2_UNWIND_INFO) | |
1978 if (dwarf2out_do_frame ()) | |
1979 dwarf2out_frame_debug (insn, false); | |
1980 #endif | |
1981 break; | |
1982 | |
1983 case CODE_LABEL: | |
1984 /* The target port might emit labels in the output function for | |
1985 some insn, e.g. sh.c output_branchy_insn. */ | |
1986 if (CODE_LABEL_NUMBER (insn) <= max_labelno) | |
1987 { | |
1988 int align = LABEL_TO_ALIGNMENT (insn); | |
1989 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN | |
1990 int max_skip = LABEL_TO_MAX_SKIP (insn); | |
1991 #endif | |
1992 | |
1993 if (align && NEXT_INSN (insn)) | |
1994 { | |
1995 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN | |
1996 ASM_OUTPUT_MAX_SKIP_ALIGN (file, align, max_skip); | |
1997 #else | |
1998 #ifdef ASM_OUTPUT_ALIGN_WITH_NOP | |
1999 ASM_OUTPUT_ALIGN_WITH_NOP (file, align); | |
2000 #else | |
2001 ASM_OUTPUT_ALIGN (file, align); | |
2002 #endif | |
2003 #endif | |
2004 } | |
2005 } | |
2006 #ifdef HAVE_cc0 | |
2007 CC_STATUS_INIT; | |
2008 #endif | |
2009 | |
2010 if (LABEL_NAME (insn)) | |
2011 (*debug_hooks->label) (insn); | |
2012 | |
2013 app_disable (); | |
2014 | |
2015 next = next_nonnote_insn (insn); | |
2016 if (next != 0 && JUMP_P (next)) | |
2017 { | |
2018 rtx nextbody = PATTERN (next); | |
2019 | |
2020 /* If this label is followed by a jump-table, | |
2021 make sure we put the label in the read-only section. Also | |
2022 possibly write the label and jump table together. */ | |
2023 | |
2024 if (GET_CODE (nextbody) == ADDR_VEC | |
2025 || GET_CODE (nextbody) == ADDR_DIFF_VEC) | |
2026 { | |
2027 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC) | |
2028 /* In this case, the case vector is being moved by the | |
2029 target, so don't output the label at all. Leave that | |
2030 to the back end macros. */ | |
2031 #else | |
2032 if (! JUMP_TABLES_IN_TEXT_SECTION) | |
2033 { | |
2034 int log_align; | |
2035 | |
2036 switch_to_section (targetm.asm_out.function_rodata_section | |
2037 (current_function_decl)); | |
2038 | |
2039 #ifdef ADDR_VEC_ALIGN | |
2040 log_align = ADDR_VEC_ALIGN (next); | |
2041 #else | |
2042 log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); | |
2043 #endif | |
2044 ASM_OUTPUT_ALIGN (file, log_align); | |
2045 } | |
2046 else | |
2047 switch_to_section (current_function_section ()); | |
2048 | |
2049 #ifdef ASM_OUTPUT_CASE_LABEL | |
2050 ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), | |
2051 next); | |
2052 #else | |
2053 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); | |
2054 #endif | |
2055 #endif | |
2056 break; | |
2057 } | |
2058 } | |
2059 if (LABEL_ALT_ENTRY_P (insn)) | |
2060 output_alternate_entry_point (file, insn); | |
2061 else | |
2062 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); | |
2063 break; | |
2064 | |
2065 default: | |
2066 { | |
2067 rtx body = PATTERN (insn); | |
2068 int insn_code_number; | |
2069 const char *templ; | |
2070 | |
2071 #ifdef HAVE_conditional_execution | |
2072 /* Reset this early so it is correct for ASM statements. */ | |
2073 current_insn_predicate = NULL_RTX; | |
2074 #endif | |
2075 /* An INSN, JUMP_INSN or CALL_INSN. | |
2076 First check for special kinds that recog doesn't recognize. */ | |
2077 | |
2078 if (GET_CODE (body) == USE /* These are just declarations. */ | |
2079 || GET_CODE (body) == CLOBBER) | |
2080 break; | |
2081 | |
2082 #ifdef HAVE_cc0 | |
2083 { | |
2084 /* If there is a REG_CC_SETTER note on this insn, it means that | |
2085 the setting of the condition code was done in the delay slot | |
2086 of the insn that branched here. So recover the cc status | |
2087 from the insn that set it. */ | |
2088 | |
2089 rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX); | |
2090 if (note) | |
2091 { | |
2092 NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0)); | |
2093 cc_prev_status = cc_status; | |
2094 } | |
2095 } | |
2096 #endif | |
2097 | |
2098 /* Detect insns that are really jump-tables | |
2099 and output them as such. */ | |
2100 | |
2101 if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC) | |
2102 { | |
2103 #if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)) | |
2104 int vlen, idx; | |
2105 #endif | |
2106 | |
2107 if (! JUMP_TABLES_IN_TEXT_SECTION) | |
2108 switch_to_section (targetm.asm_out.function_rodata_section | |
2109 (current_function_decl)); | |
2110 else | |
2111 switch_to_section (current_function_section ()); | |
2112 | |
2113 app_disable (); | |
2114 | |
2115 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC) | |
2116 if (GET_CODE (body) == ADDR_VEC) | |
2117 { | |
2118 #ifdef ASM_OUTPUT_ADDR_VEC | |
2119 ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body); | |
2120 #else | |
2121 gcc_unreachable (); | |
2122 #endif | |
2123 } | |
2124 else | |
2125 { | |
2126 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC | |
2127 ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body); | |
2128 #else | |
2129 gcc_unreachable (); | |
2130 #endif | |
2131 } | |
2132 #else | |
2133 vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC); | |
2134 for (idx = 0; idx < vlen; idx++) | |
2135 { | |
2136 if (GET_CODE (body) == ADDR_VEC) | |
2137 { | |
2138 #ifdef ASM_OUTPUT_ADDR_VEC_ELT | |
2139 ASM_OUTPUT_ADDR_VEC_ELT | |
2140 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); | |
2141 #else | |
2142 gcc_unreachable (); | |
2143 #endif | |
2144 } | |
2145 else | |
2146 { | |
2147 #ifdef ASM_OUTPUT_ADDR_DIFF_ELT | |
2148 ASM_OUTPUT_ADDR_DIFF_ELT | |
2149 (file, | |
2150 body, | |
2151 CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), | |
2152 CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0))); | |
2153 #else | |
2154 gcc_unreachable (); | |
2155 #endif | |
2156 } | |
2157 } | |
2158 #ifdef ASM_OUTPUT_CASE_END | |
2159 ASM_OUTPUT_CASE_END (file, | |
2160 CODE_LABEL_NUMBER (PREV_INSN (insn)), | |
2161 insn); | |
2162 #endif | |
2163 #endif | |
2164 | |
2165 switch_to_section (current_function_section ()); | |
2166 | |
2167 break; | |
2168 } | |
2169 /* Output this line note if it is the first or the last line | |
2170 note in a row. */ | |
2171 if (notice_source_line (insn)) | |
2172 { | |
2173 (*debug_hooks->source_line) (last_linenum, last_filename); | |
2174 } | |
2175 | |
2176 if (GET_CODE (body) == ASM_INPUT) | |
2177 { | |
2178 const char *string = XSTR (body, 0); | |
2179 | |
2180 /* There's no telling what that did to the condition codes. */ | |
2181 CC_STATUS_INIT; | |
2182 | |
2183 if (string[0]) | |
2184 { | |
2185 expanded_location loc; | |
2186 | |
2187 app_enable (); | |
2188 loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body)); | |
2189 if (*loc.file && loc.line) | |
2190 fprintf (asm_out_file, "%s %i \"%s\" 1\n", | |
2191 ASM_COMMENT_START, loc.line, loc.file); | |
2192 fprintf (asm_out_file, "\t%s\n", string); | |
2193 #if HAVE_AS_LINE_ZERO | |
2194 if (*loc.file && loc.line) | |
2195 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START); | |
2196 #endif | |
2197 } | |
2198 break; | |
2199 } | |
2200 | |
2201 /* Detect `asm' construct with operands. */ | |
2202 if (asm_noperands (body) >= 0) | |
2203 { | |
2204 unsigned int noperands = asm_noperands (body); | |
2205 rtx *ops = XALLOCAVEC (rtx, noperands); | |
2206 const char *string; | |
2207 location_t loc; | |
2208 expanded_location expanded; | |
2209 | |
2210 /* There's no telling what that did to the condition codes. */ | |
2211 CC_STATUS_INIT; | |
2212 | |
2213 /* Get out the operand values. */ | |
2214 string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc); | |
2215 /* Inhibit dying on what would otherwise be compiler bugs. */ | |
2216 insn_noperands = noperands; | |
2217 this_is_asm_operands = insn; | |
2218 expanded = expand_location (loc); | |
2219 | |
2220 #ifdef FINAL_PRESCAN_INSN | |
2221 FINAL_PRESCAN_INSN (insn, ops, insn_noperands); | |
2222 #endif | |
2223 | |
2224 /* Output the insn using them. */ | |
2225 if (string[0]) | |
2226 { | |
2227 app_enable (); | |
2228 if (expanded.file && expanded.line) | |
2229 fprintf (asm_out_file, "%s %i \"%s\" 1\n", | |
2230 ASM_COMMENT_START, expanded.line, expanded.file); | |
2231 output_asm_insn (string, ops); | |
2232 #if HAVE_AS_LINE_ZERO | |
2233 if (expanded.file && expanded.line) | |
2234 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START); | |
2235 #endif | |
2236 } | |
2237 | |
2238 this_is_asm_operands = 0; | |
2239 break; | |
2240 } | |
2241 | |
2242 app_disable (); | |
2243 | |
2244 if (GET_CODE (body) == SEQUENCE) | |
2245 { | |
2246 /* A delayed-branch sequence */ | |
2247 int i; | |
2248 | |
2249 final_sequence = body; | |
2250 | |
2251 /* Record the delay slots' frame information before the branch. | |
2252 This is needed for delayed calls: see execute_cfa_program(). */ | |
2253 #if defined (DWARF2_UNWIND_INFO) | |
2254 if (dwarf2out_do_frame ()) | |
2255 for (i = 1; i < XVECLEN (body, 0); i++) | |
2256 dwarf2out_frame_debug (XVECEXP (body, 0, i), false); | |
2257 #endif | |
2258 | |
2259 /* The first insn in this SEQUENCE might be a JUMP_INSN that will | |
2260 force the restoration of a comparison that was previously | |
2261 thought unnecessary. If that happens, cancel this sequence | |
2262 and cause that insn to be restored. */ | |
2263 | |
2264 next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, 1, seen); | |
2265 if (next != XVECEXP (body, 0, 1)) | |
2266 { | |
2267 final_sequence = 0; | |
2268 return next; | |
2269 } | |
2270 | |
2271 for (i = 1; i < XVECLEN (body, 0); i++) | |
2272 { | |
2273 rtx insn = XVECEXP (body, 0, i); | |
2274 rtx next = NEXT_INSN (insn); | |
2275 /* We loop in case any instruction in a delay slot gets | |
2276 split. */ | |
2277 do | |
2278 insn = final_scan_insn (insn, file, 0, 1, seen); | |
2279 while (insn != next); | |
2280 } | |
2281 #ifdef DBR_OUTPUT_SEQEND | |
2282 DBR_OUTPUT_SEQEND (file); | |
2283 #endif | |
2284 final_sequence = 0; | |
2285 | |
2286 /* If the insn requiring the delay slot was a CALL_INSN, the | |
2287 insns in the delay slot are actually executed before the | |
2288 called function. Hence we don't preserve any CC-setting | |
2289 actions in these insns and the CC must be marked as being | |
2290 clobbered by the function. */ | |
2291 if (CALL_P (XVECEXP (body, 0, 0))) | |
2292 { | |
2293 CC_STATUS_INIT; | |
2294 } | |
2295 break; | |
2296 } | |
2297 | |
2298 /* We have a real machine instruction as rtl. */ | |
2299 | |
2300 body = PATTERN (insn); | |
2301 | |
2302 #ifdef HAVE_cc0 | |
2303 set = single_set (insn); | |
2304 | |
2305 /* Check for redundant test and compare instructions | |
2306 (when the condition codes are already set up as desired). | |
2307 This is done only when optimizing; if not optimizing, | |
2308 it should be possible for the user to alter a variable | |
2309 with the debugger in between statements | |
2310 and the next statement should reexamine the variable | |
2311 to compute the condition codes. */ | |
2312 | |
2313 if (optimize) | |
2314 { | |
2315 if (set | |
2316 && GET_CODE (SET_DEST (set)) == CC0 | |
2317 && insn != last_ignored_compare) | |
2318 { | |
2319 if (GET_CODE (SET_SRC (set)) == SUBREG) | |
2320 SET_SRC (set) = alter_subreg (&SET_SRC (set)); | |
2321 else if (GET_CODE (SET_SRC (set)) == COMPARE) | |
2322 { | |
2323 if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG) | |
2324 XEXP (SET_SRC (set), 0) | |
2325 = alter_subreg (&XEXP (SET_SRC (set), 0)); | |
2326 if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG) | |
2327 XEXP (SET_SRC (set), 1) | |
2328 = alter_subreg (&XEXP (SET_SRC (set), 1)); | |
2329 } | |
2330 if ((cc_status.value1 != 0 | |
2331 && rtx_equal_p (SET_SRC (set), cc_status.value1)) | |
2332 || (cc_status.value2 != 0 | |
2333 && rtx_equal_p (SET_SRC (set), cc_status.value2))) | |
2334 { | |
2335 /* Don't delete insn if it has an addressing side-effect. */ | |
2336 if (! FIND_REG_INC_NOTE (insn, NULL_RTX) | |
2337 /* or if anything in it is volatile. */ | |
2338 && ! volatile_refs_p (PATTERN (insn))) | |
2339 { | |
2340 /* We don't really delete the insn; just ignore it. */ | |
2341 last_ignored_compare = insn; | |
2342 break; | |
2343 } | |
2344 } | |
2345 } | |
2346 } | |
2347 #endif | |
2348 | |
2349 #ifdef HAVE_cc0 | |
2350 /* If this is a conditional branch, maybe modify it | |
2351 if the cc's are in a nonstandard state | |
2352 so that it accomplishes the same thing that it would | |
2353 do straightforwardly if the cc's were set up normally. */ | |
2354 | |
2355 if (cc_status.flags != 0 | |
2356 && JUMP_P (insn) | |
2357 && GET_CODE (body) == SET | |
2358 && SET_DEST (body) == pc_rtx | |
2359 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE | |
2360 && COMPARISON_P (XEXP (SET_SRC (body), 0)) | |
2361 && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx) | |
2362 { | |
2363 /* This function may alter the contents of its argument | |
2364 and clear some of the cc_status.flags bits. | |
2365 It may also return 1 meaning condition now always true | |
2366 or -1 meaning condition now always false | |
2367 or 2 meaning condition nontrivial but altered. */ | |
2368 int result = alter_cond (XEXP (SET_SRC (body), 0)); | |
2369 /* If condition now has fixed value, replace the IF_THEN_ELSE | |
2370 with its then-operand or its else-operand. */ | |
2371 if (result == 1) | |
2372 SET_SRC (body) = XEXP (SET_SRC (body), 1); | |
2373 if (result == -1) | |
2374 SET_SRC (body) = XEXP (SET_SRC (body), 2); | |
2375 | |
2376 /* The jump is now either unconditional or a no-op. | |
2377 If it has become a no-op, don't try to output it. | |
2378 (It would not be recognized.) */ | |
2379 if (SET_SRC (body) == pc_rtx) | |
2380 { | |
2381 delete_insn (insn); | |
2382 break; | |
2383 } | |
2384 else if (GET_CODE (SET_SRC (body)) == RETURN) | |
2385 /* Replace (set (pc) (return)) with (return). */ | |
2386 PATTERN (insn) = body = SET_SRC (body); | |
2387 | |
2388 /* Rerecognize the instruction if it has changed. */ | |
2389 if (result != 0) | |
2390 INSN_CODE (insn) = -1; | |
2391 } | |
2392 | |
2393 /* If this is a conditional trap, maybe modify it if the cc's | |
2394 are in a nonstandard state so that it accomplishes the same | |
2395 thing that it would do straightforwardly if the cc's were | |
2396 set up normally. */ | |
2397 if (cc_status.flags != 0 | |
2398 && NONJUMP_INSN_P (insn) | |
2399 && GET_CODE (body) == TRAP_IF | |
2400 && COMPARISON_P (TRAP_CONDITION (body)) | |
2401 && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx) | |
2402 { | |
2403 /* This function may alter the contents of its argument | |
2404 and clear some of the cc_status.flags bits. | |
2405 It may also return 1 meaning condition now always true | |
2406 or -1 meaning condition now always false | |
2407 or 2 meaning condition nontrivial but altered. */ | |
2408 int result = alter_cond (TRAP_CONDITION (body)); | |
2409 | |
2410 /* If TRAP_CONDITION has become always false, delete the | |
2411 instruction. */ | |
2412 if (result == -1) | |
2413 { | |
2414 delete_insn (insn); | |
2415 break; | |
2416 } | |
2417 | |
2418 /* If TRAP_CONDITION has become always true, replace | |
2419 TRAP_CONDITION with const_true_rtx. */ | |
2420 if (result == 1) | |
2421 TRAP_CONDITION (body) = const_true_rtx; | |
2422 | |
2423 /* Rerecognize the instruction if it has changed. */ | |
2424 if (result != 0) | |
2425 INSN_CODE (insn) = -1; | |
2426 } | |
2427 | |
2428 /* Make same adjustments to instructions that examine the | |
2429 condition codes without jumping and instructions that | |
2430 handle conditional moves (if this machine has either one). */ | |
2431 | |
2432 if (cc_status.flags != 0 | |
2433 && set != 0) | |
2434 { | |
2435 rtx cond_rtx, then_rtx, else_rtx; | |
2436 | |
2437 if (!JUMP_P (insn) | |
2438 && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE) | |
2439 { | |
2440 cond_rtx = XEXP (SET_SRC (set), 0); | |
2441 then_rtx = XEXP (SET_SRC (set), 1); | |
2442 else_rtx = XEXP (SET_SRC (set), 2); | |
2443 } | |
2444 else | |
2445 { | |
2446 cond_rtx = SET_SRC (set); | |
2447 then_rtx = const_true_rtx; | |
2448 else_rtx = const0_rtx; | |
2449 } | |
2450 | |
2451 switch (GET_CODE (cond_rtx)) | |
2452 { | |
2453 case GTU: | |
2454 case GT: | |
2455 case LTU: | |
2456 case LT: | |
2457 case GEU: | |
2458 case GE: | |
2459 case LEU: | |
2460 case LE: | |
2461 case EQ: | |
2462 case NE: | |
2463 { | |
2464 int result; | |
2465 if (XEXP (cond_rtx, 0) != cc0_rtx) | |
2466 break; | |
2467 result = alter_cond (cond_rtx); | |
2468 if (result == 1) | |
2469 validate_change (insn, &SET_SRC (set), then_rtx, 0); | |
2470 else if (result == -1) | |
2471 validate_change (insn, &SET_SRC (set), else_rtx, 0); | |
2472 else if (result == 2) | |
2473 INSN_CODE (insn) = -1; | |
2474 if (SET_DEST (set) == SET_SRC (set)) | |
2475 delete_insn (insn); | |
2476 } | |
2477 break; | |
2478 | |
2479 default: | |
2480 break; | |
2481 } | |
2482 } | |
2483 | |
2484 #endif | |
2485 | |
2486 #ifdef HAVE_peephole | |
2487 /* Do machine-specific peephole optimizations if desired. */ | |
2488 | |
2489 if (optimize && !flag_no_peephole && !nopeepholes) | |
2490 { | |
2491 rtx next = peephole (insn); | |
2492 /* When peepholing, if there were notes within the peephole, | |
2493 emit them before the peephole. */ | |
2494 if (next != 0 && next != NEXT_INSN (insn)) | |
2495 { | |
2496 rtx note, prev = PREV_INSN (insn); | |
2497 | |
2498 for (note = NEXT_INSN (insn); note != next; | |
2499 note = NEXT_INSN (note)) | |
2500 final_scan_insn (note, file, optimize, nopeepholes, seen); | |
2501 | |
2502 /* Put the notes in the proper position for a later | |
2503 rescan. For example, the SH target can do this | |
2504 when generating a far jump in a delayed branch | |
2505 sequence. */ | |
2506 note = NEXT_INSN (insn); | |
2507 PREV_INSN (note) = prev; | |
2508 NEXT_INSN (prev) = note; | |
2509 NEXT_INSN (PREV_INSN (next)) = insn; | |
2510 PREV_INSN (insn) = PREV_INSN (next); | |
2511 NEXT_INSN (insn) = next; | |
2512 PREV_INSN (next) = insn; | |
2513 } | |
2514 | |
2515 /* PEEPHOLE might have changed this. */ | |
2516 body = PATTERN (insn); | |
2517 } | |
2518 #endif | |
2519 | |
2520 /* Try to recognize the instruction. | |
2521 If successful, verify that the operands satisfy the | |
2522 constraints for the instruction. Crash if they don't, | |
2523 since `reload' should have changed them so that they do. */ | |
2524 | |
2525 insn_code_number = recog_memoized (insn); | |
2526 cleanup_subreg_operands (insn); | |
2527 | |
2528 /* Dump the insn in the assembly for debugging. */ | |
2529 if (flag_dump_rtl_in_asm) | |
2530 { | |
2531 print_rtx_head = ASM_COMMENT_START; | |
2532 print_rtl_single (asm_out_file, insn); | |
2533 print_rtx_head = ""; | |
2534 } | |
2535 | |
2536 if (! constrain_operands_cached (1)) | |
2537 fatal_insn_not_found (insn); | |
2538 | |
2539 /* Some target machines need to prescan each insn before | |
2540 it is output. */ | |
2541 | |
2542 #ifdef FINAL_PRESCAN_INSN | |
2543 FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands); | |
2544 #endif | |
2545 | |
2546 #ifdef HAVE_conditional_execution | |
2547 if (GET_CODE (PATTERN (insn)) == COND_EXEC) | |
2548 current_insn_predicate = COND_EXEC_TEST (PATTERN (insn)); | |
2549 #endif | |
2550 | |
2551 #ifdef HAVE_cc0 | |
2552 cc_prev_status = cc_status; | |
2553 | |
2554 /* Update `cc_status' for this instruction. | |
2555 The instruction's output routine may change it further. | |
2556 If the output routine for a jump insn needs to depend | |
2557 on the cc status, it should look at cc_prev_status. */ | |
2558 | |
2559 NOTICE_UPDATE_CC (body, insn); | |
2560 #endif | |
2561 | |
2562 current_output_insn = debug_insn = insn; | |
2563 | |
2564 #if defined (DWARF2_UNWIND_INFO) | |
2565 if (CALL_P (insn) && dwarf2out_do_frame ()) | |
2566 dwarf2out_frame_debug (insn, false); | |
2567 #endif | |
2568 | |
2569 /* Find the proper template for this insn. */ | |
2570 templ = get_insn_template (insn_code_number, insn); | |
2571 | |
2572 /* If the C code returns 0, it means that it is a jump insn | |
2573 which follows a deleted test insn, and that test insn | |
2574 needs to be reinserted. */ | |
2575 if (templ == 0) | |
2576 { | |
2577 rtx prev; | |
2578 | |
2579 gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare); | |
2580 | |
2581 /* We have already processed the notes between the setter and | |
2582 the user. Make sure we don't process them again, this is | |
2583 particularly important if one of the notes is a block | |
2584 scope note or an EH note. */ | |
2585 for (prev = insn; | |
2586 prev != last_ignored_compare; | |
2587 prev = PREV_INSN (prev)) | |
2588 { | |
2589 if (NOTE_P (prev)) | |
2590 delete_insn (prev); /* Use delete_note. */ | |
2591 } | |
2592 | |
2593 return prev; | |
2594 } | |
2595 | |
2596 /* If the template is the string "#", it means that this insn must | |
2597 be split. */ | |
2598 if (templ[0] == '#' && templ[1] == '\0') | |
2599 { | |
2600 rtx new_rtx = try_split (body, insn, 0); | |
2601 | |
2602 /* If we didn't split the insn, go away. */ | |
2603 if (new_rtx == insn && PATTERN (new_rtx) == body) | |
2604 fatal_insn ("could not split insn", insn); | |
2605 | |
2606 #ifdef HAVE_ATTR_length | |
2607 /* This instruction should have been split in shorten_branches, | |
2608 to ensure that we would have valid length info for the | |
2609 splitees. */ | |
2610 gcc_unreachable (); | |
2611 #endif | |
2612 | |
2613 return new_rtx; | |
2614 } | |
2615 | |
2616 #ifdef TARGET_UNWIND_INFO | |
2617 /* ??? This will put the directives in the wrong place if | |
2618 get_insn_template outputs assembly directly. However calling it | |
2619 before get_insn_template breaks if the insns is split. */ | |
2620 targetm.asm_out.unwind_emit (asm_out_file, insn); | |
2621 #endif | |
2622 | |
2623 if (CALL_P (insn)) | |
2624 { | |
2625 rtx x = call_from_call_insn (insn); | |
2626 x = XEXP (x, 0); | |
2627 if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF) | |
2628 { | |
2629 tree t; | |
2630 x = XEXP (x, 0); | |
2631 t = SYMBOL_REF_DECL (x); | |
2632 if (t) | |
2633 assemble_external (t); | |
2634 } | |
2635 } | |
2636 | |
2637 /* Output assembler code from the template. */ | |
2638 output_asm_insn (templ, recog_data.operand); | |
2639 | |
2640 /* If necessary, report the effect that the instruction has on | |
2641 the unwind info. We've already done this for delay slots | |
2642 and call instructions. */ | |
2643 #if defined (DWARF2_UNWIND_INFO) | |
2644 if (final_sequence == 0 | |
2645 #if !defined (HAVE_prologue) | |
2646 && !ACCUMULATE_OUTGOING_ARGS | |
2647 #endif | |
2648 && dwarf2out_do_frame ()) | |
2649 dwarf2out_frame_debug (insn, true); | |
2650 #endif | |
2651 | |
2652 current_output_insn = debug_insn = 0; | |
2653 } | |
2654 } | |
2655 return NEXT_INSN (insn); | |
2656 } | |
2657 | |
2658 /* Return whether a source line note needs to be emitted before INSN. */ | |
2659 | |
2660 static bool | |
2661 notice_source_line (rtx insn) | |
2662 { | |
2663 const char *filename; | |
2664 int linenum; | |
2665 | |
2666 if (override_filename) | |
2667 { | |
2668 filename = override_filename; | |
2669 linenum = override_linenum; | |
2670 } | |
2671 else | |
2672 { | |
2673 filename = insn_file (insn); | |
2674 linenum = insn_line (insn); | |
2675 } | |
2676 | |
2677 if (filename | |
2678 && (force_source_line | |
2679 || filename != last_filename | |
2680 || last_linenum != linenum)) | |
2681 { | |
2682 force_source_line = false; | |
2683 last_filename = filename; | |
2684 last_linenum = linenum; | |
2685 high_block_linenum = MAX (last_linenum, high_block_linenum); | |
2686 high_function_linenum = MAX (last_linenum, high_function_linenum); | |
2687 return true; | |
2688 } | |
2689 return false; | |
2690 } | |
2691 | |
2692 /* For each operand in INSN, simplify (subreg (reg)) so that it refers | |
2693 directly to the desired hard register. */ | |
2694 | |
2695 void | |
2696 cleanup_subreg_operands (rtx insn) | |
2697 { | |
2698 int i; | |
2699 bool changed = false; | |
2700 extract_insn_cached (insn); | |
2701 for (i = 0; i < recog_data.n_operands; i++) | |
2702 { | |
2703 /* The following test cannot use recog_data.operand when testing | |
2704 for a SUBREG: the underlying object might have been changed | |
2705 already if we are inside a match_operator expression that | |
2706 matches the else clause. Instead we test the underlying | |
2707 expression directly. */ | |
2708 if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG) | |
2709 { | |
2710 recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]); | |
2711 changed = true; | |
2712 } | |
2713 else if (GET_CODE (recog_data.operand[i]) == PLUS | |
2714 || GET_CODE (recog_data.operand[i]) == MULT | |
2715 || MEM_P (recog_data.operand[i])) | |
2716 recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed); | |
2717 } | |
2718 | |
2719 for (i = 0; i < recog_data.n_dups; i++) | |
2720 { | |
2721 if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG) | |
2722 { | |
2723 *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]); | |
2724 changed = true; | |
2725 } | |
2726 else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS | |
2727 || GET_CODE (*recog_data.dup_loc[i]) == MULT | |
2728 || MEM_P (*recog_data.dup_loc[i])) | |
2729 *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed); | |
2730 } | |
2731 if (changed) | |
2732 df_insn_rescan (insn); | |
2733 } | |
2734 | |
2735 /* If X is a SUBREG, replace it with a REG or a MEM, | |
2736 based on the thing it is a subreg of. */ | |
2737 | |
2738 rtx | |
2739 alter_subreg (rtx *xp) | |
2740 { | |
2741 rtx x = *xp; | |
2742 rtx y = SUBREG_REG (x); | |
2743 | |
2744 /* simplify_subreg does not remove subreg from volatile references. | |
2745 We are required to. */ | |
2746 if (MEM_P (y)) | |
2747 { | |
2748 int offset = SUBREG_BYTE (x); | |
2749 | |
2750 /* For paradoxical subregs on big-endian machines, SUBREG_BYTE | |
2751 contains 0 instead of the proper offset. See simplify_subreg. */ | |
2752 if (offset == 0 | |
2753 && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x))) | |
2754 { | |
2755 int difference = GET_MODE_SIZE (GET_MODE (y)) | |
2756 - GET_MODE_SIZE (GET_MODE (x)); | |
2757 if (WORDS_BIG_ENDIAN) | |
2758 offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD; | |
2759 if (BYTES_BIG_ENDIAN) | |
2760 offset += difference % UNITS_PER_WORD; | |
2761 } | |
2762 | |
2763 *xp = adjust_address (y, GET_MODE (x), offset); | |
2764 } | |
2765 else | |
2766 { | |
2767 rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y), | |
2768 SUBREG_BYTE (x)); | |
2769 | |
2770 if (new_rtx != 0) | |
2771 *xp = new_rtx; | |
2772 else if (REG_P (y)) | |
2773 { | |
2774 /* Simplify_subreg can't handle some REG cases, but we have to. */ | |
2775 unsigned int regno; | |
2776 HOST_WIDE_INT offset; | |
2777 | |
2778 regno = subreg_regno (x); | |
2779 if (subreg_lowpart_p (x)) | |
2780 offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y)); | |
2781 else | |
2782 offset = SUBREG_BYTE (x); | |
2783 *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset); | |
2784 } | |
2785 } | |
2786 | |
2787 return *xp; | |
2788 } | |
2789 | |
2790 /* Do alter_subreg on all the SUBREGs contained in X. */ | |
2791 | |
2792 static rtx | |
2793 walk_alter_subreg (rtx *xp, bool *changed) | |
2794 { | |
2795 rtx x = *xp; | |
2796 switch (GET_CODE (x)) | |
2797 { | |
2798 case PLUS: | |
2799 case MULT: | |
2800 case AND: | |
2801 XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed); | |
2802 XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed); | |
2803 break; | |
2804 | |
2805 case MEM: | |
2806 case ZERO_EXTEND: | |
2807 XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed); | |
2808 break; | |
2809 | |
2810 case SUBREG: | |
2811 *changed = true; | |
2812 return alter_subreg (xp); | |
2813 | |
2814 default: | |
2815 break; | |
2816 } | |
2817 | |
2818 return *xp; | |
2819 } | |
2820 | |
2821 #ifdef HAVE_cc0 | |
2822 | |
2823 /* Given BODY, the body of a jump instruction, alter the jump condition | |
2824 as required by the bits that are set in cc_status.flags. | |
2825 Not all of the bits there can be handled at this level in all cases. | |
2826 | |
2827 The value is normally 0. | |
2828 1 means that the condition has become always true. | |
2829 -1 means that the condition has become always false. | |
2830 2 means that COND has been altered. */ | |
2831 | |
2832 static int | |
2833 alter_cond (rtx cond) | |
2834 { | |
2835 int value = 0; | |
2836 | |
2837 if (cc_status.flags & CC_REVERSED) | |
2838 { | |
2839 value = 2; | |
2840 PUT_CODE (cond, swap_condition (GET_CODE (cond))); | |
2841 } | |
2842 | |
2843 if (cc_status.flags & CC_INVERTED) | |
2844 { | |
2845 value = 2; | |
2846 PUT_CODE (cond, reverse_condition (GET_CODE (cond))); | |
2847 } | |
2848 | |
2849 if (cc_status.flags & CC_NOT_POSITIVE) | |
2850 switch (GET_CODE (cond)) | |
2851 { | |
2852 case LE: | |
2853 case LEU: | |
2854 case GEU: | |
2855 /* Jump becomes unconditional. */ | |
2856 return 1; | |
2857 | |
2858 case GT: | |
2859 case GTU: | |
2860 case LTU: | |
2861 /* Jump becomes no-op. */ | |
2862 return -1; | |
2863 | |
2864 case GE: | |
2865 PUT_CODE (cond, EQ); | |
2866 value = 2; | |
2867 break; | |
2868 | |
2869 case LT: | |
2870 PUT_CODE (cond, NE); | |
2871 value = 2; | |
2872 break; | |
2873 | |
2874 default: | |
2875 break; | |
2876 } | |
2877 | |
2878 if (cc_status.flags & CC_NOT_NEGATIVE) | |
2879 switch (GET_CODE (cond)) | |
2880 { | |
2881 case GE: | |
2882 case GEU: | |
2883 /* Jump becomes unconditional. */ | |
2884 return 1; | |
2885 | |
2886 case LT: | |
2887 case LTU: | |
2888 /* Jump becomes no-op. */ | |
2889 return -1; | |
2890 | |
2891 case LE: | |
2892 case LEU: | |
2893 PUT_CODE (cond, EQ); | |
2894 value = 2; | |
2895 break; | |
2896 | |
2897 case GT: | |
2898 case GTU: | |
2899 PUT_CODE (cond, NE); | |
2900 value = 2; | |
2901 break; | |
2902 | |
2903 default: | |
2904 break; | |
2905 } | |
2906 | |
2907 if (cc_status.flags & CC_NO_OVERFLOW) | |
2908 switch (GET_CODE (cond)) | |
2909 { | |
2910 case GEU: | |
2911 /* Jump becomes unconditional. */ | |
2912 return 1; | |
2913 | |
2914 case LEU: | |
2915 PUT_CODE (cond, EQ); | |
2916 value = 2; | |
2917 break; | |
2918 | |
2919 case GTU: | |
2920 PUT_CODE (cond, NE); | |
2921 value = 2; | |
2922 break; | |
2923 | |
2924 case LTU: | |
2925 /* Jump becomes no-op. */ | |
2926 return -1; | |
2927 | |
2928 default: | |
2929 break; | |
2930 } | |
2931 | |
2932 if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N)) | |
2933 switch (GET_CODE (cond)) | |
2934 { | |
2935 default: | |
2936 gcc_unreachable (); | |
2937 | |
2938 case NE: | |
2939 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT); | |
2940 value = 2; | |
2941 break; | |
2942 | |
2943 case EQ: | |
2944 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE); | |
2945 value = 2; | |
2946 break; | |
2947 } | |
2948 | |
2949 if (cc_status.flags & CC_NOT_SIGNED) | |
2950 /* The flags are valid if signed condition operators are converted | |
2951 to unsigned. */ | |
2952 switch (GET_CODE (cond)) | |
2953 { | |
2954 case LE: | |
2955 PUT_CODE (cond, LEU); | |
2956 value = 2; | |
2957 break; | |
2958 | |
2959 case LT: | |
2960 PUT_CODE (cond, LTU); | |
2961 value = 2; | |
2962 break; | |
2963 | |
2964 case GT: | |
2965 PUT_CODE (cond, GTU); | |
2966 value = 2; | |
2967 break; | |
2968 | |
2969 case GE: | |
2970 PUT_CODE (cond, GEU); | |
2971 value = 2; | |
2972 break; | |
2973 | |
2974 default: | |
2975 break; | |
2976 } | |
2977 | |
2978 return value; | |
2979 } | |
2980 #endif | |
2981 | |
2982 /* Report inconsistency between the assembler template and the operands. | |
2983 In an `asm', it's the user's fault; otherwise, the compiler's fault. */ | |
2984 | |
2985 void | |
2986 output_operand_lossage (const char *cmsgid, ...) | |
2987 { | |
2988 char *fmt_string; | |
2989 char *new_message; | |
2990 const char *pfx_str; | |
2991 va_list ap; | |
2992 | |
2993 va_start (ap, cmsgid); | |
2994 | |
2995 pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: "; | |
2996 asprintf (&fmt_string, "%s%s", pfx_str, _(cmsgid)); | |
2997 vasprintf (&new_message, fmt_string, ap); | |
2998 | |
2999 if (this_is_asm_operands) | |
3000 error_for_asm (this_is_asm_operands, "%s", new_message); | |
3001 else | |
3002 internal_error ("%s", new_message); | |
3003 | |
3004 free (fmt_string); | |
3005 free (new_message); | |
3006 va_end (ap); | |
3007 } | |
3008 | |
3009 /* Output of assembler code from a template, and its subroutines. */ | |
3010 | |
3011 /* Annotate the assembly with a comment describing the pattern and | |
3012 alternative used. */ | |
3013 | |
3014 static void | |
3015 output_asm_name (void) | |
3016 { | |
3017 if (debug_insn) | |
3018 { | |
3019 int num = INSN_CODE (debug_insn); | |
3020 fprintf (asm_out_file, "\t%s %d\t%s", | |
3021 ASM_COMMENT_START, INSN_UID (debug_insn), | |
3022 insn_data[num].name); | |
3023 if (insn_data[num].n_alternatives > 1) | |
3024 fprintf (asm_out_file, "/%d", which_alternative + 1); | |
3025 #ifdef HAVE_ATTR_length | |
3026 fprintf (asm_out_file, "\t[length = %d]", | |
3027 get_attr_length (debug_insn)); | |
3028 #endif | |
3029 /* Clear this so only the first assembler insn | |
3030 of any rtl insn will get the special comment for -dp. */ | |
3031 debug_insn = 0; | |
3032 } | |
3033 } | |
3034 | |
3035 /* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it | |
3036 or its address, return that expr . Set *PADDRESSP to 1 if the expr | |
3037 corresponds to the address of the object and 0 if to the object. */ | |
3038 | |
3039 static tree | |
3040 get_mem_expr_from_op (rtx op, int *paddressp) | |
3041 { | |
3042 tree expr; | |
3043 int inner_addressp; | |
3044 | |
3045 *paddressp = 0; | |
3046 | |
3047 if (REG_P (op)) | |
3048 return REG_EXPR (op); | |
3049 else if (!MEM_P (op)) | |
3050 return 0; | |
3051 | |
3052 if (MEM_EXPR (op) != 0) | |
3053 return MEM_EXPR (op); | |
3054 | |
3055 /* Otherwise we have an address, so indicate it and look at the address. */ | |
3056 *paddressp = 1; | |
3057 op = XEXP (op, 0); | |
3058 | |
3059 /* First check if we have a decl for the address, then look at the right side | |
3060 if it is a PLUS. Otherwise, strip off arithmetic and keep looking. | |
3061 But don't allow the address to itself be indirect. */ | |
3062 if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp) | |
3063 return expr; | |
3064 else if (GET_CODE (op) == PLUS | |
3065 && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp))) | |
3066 return expr; | |
3067 | |
3068 while (GET_RTX_CLASS (GET_CODE (op)) == RTX_UNARY | |
3069 || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH) | |
3070 op = XEXP (op, 0); | |
3071 | |
3072 expr = get_mem_expr_from_op (op, &inner_addressp); | |
3073 return inner_addressp ? 0 : expr; | |
3074 } | |
3075 | |
3076 /* Output operand names for assembler instructions. OPERANDS is the | |
3077 operand vector, OPORDER is the order to write the operands, and NOPS | |
3078 is the number of operands to write. */ | |
3079 | |
3080 static void | |
3081 output_asm_operand_names (rtx *operands, int *oporder, int nops) | |
3082 { | |
3083 int wrote = 0; | |
3084 int i; | |
3085 | |
3086 for (i = 0; i < nops; i++) | |
3087 { | |
3088 int addressp; | |
3089 rtx op = operands[oporder[i]]; | |
3090 tree expr = get_mem_expr_from_op (op, &addressp); | |
3091 | |
3092 fprintf (asm_out_file, "%c%s", | |
3093 wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START); | |
3094 wrote = 1; | |
3095 if (expr) | |
3096 { | |
3097 fprintf (asm_out_file, "%s", | |
3098 addressp ? "*" : ""); | |
3099 print_mem_expr (asm_out_file, expr); | |
3100 wrote = 1; | |
3101 } | |
3102 else if (REG_P (op) && ORIGINAL_REGNO (op) | |
3103 && ORIGINAL_REGNO (op) != REGNO (op)) | |
3104 fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op)); | |
3105 } | |
3106 } | |
3107 | |
3108 /* Output text from TEMPLATE to the assembler output file, | |
3109 obeying %-directions to substitute operands taken from | |
3110 the vector OPERANDS. | |
3111 | |
3112 %N (for N a digit) means print operand N in usual manner. | |
3113 %lN means require operand N to be a CODE_LABEL or LABEL_REF | |
3114 and print the label name with no punctuation. | |
3115 %cN means require operand N to be a constant | |
3116 and print the constant expression with no punctuation. | |
3117 %aN means expect operand N to be a memory address | |
3118 (not a memory reference!) and print a reference | |
3119 to that address. | |
3120 %nN means expect operand N to be a constant | |
3121 and print a constant expression for minus the value | |
3122 of the operand, with no other punctuation. */ | |
3123 | |
3124 void | |
3125 output_asm_insn (const char *templ, rtx *operands) | |
3126 { | |
3127 const char *p; | |
3128 int c; | |
3129 #ifdef ASSEMBLER_DIALECT | |
3130 int dialect = 0; | |
3131 #endif | |
3132 int oporder[MAX_RECOG_OPERANDS]; | |
3133 char opoutput[MAX_RECOG_OPERANDS]; | |
3134 int ops = 0; | |
3135 | |
3136 /* An insn may return a null string template | |
3137 in a case where no assembler code is needed. */ | |
3138 if (*templ == 0) | |
3139 return; | |
3140 | |
3141 memset (opoutput, 0, sizeof opoutput); | |
3142 p = templ; | |
3143 putc ('\t', asm_out_file); | |
3144 | |
3145 #ifdef ASM_OUTPUT_OPCODE | |
3146 ASM_OUTPUT_OPCODE (asm_out_file, p); | |
3147 #endif | |
3148 | |
3149 while ((c = *p++)) | |
3150 switch (c) | |
3151 { | |
3152 case '\n': | |
3153 if (flag_verbose_asm) | |
3154 output_asm_operand_names (operands, oporder, ops); | |
3155 if (flag_print_asm_name) | |
3156 output_asm_name (); | |
3157 | |
3158 ops = 0; | |
3159 memset (opoutput, 0, sizeof opoutput); | |
3160 | |
3161 putc (c, asm_out_file); | |
3162 #ifdef ASM_OUTPUT_OPCODE | |
3163 while ((c = *p) == '\t') | |
3164 { | |
3165 putc (c, asm_out_file); | |
3166 p++; | |
3167 } | |
3168 ASM_OUTPUT_OPCODE (asm_out_file, p); | |
3169 #endif | |
3170 break; | |
3171 | |
3172 #ifdef ASSEMBLER_DIALECT | |
3173 case '{': | |
3174 { | |
3175 int i; | |
3176 | |
3177 if (dialect) | |
3178 output_operand_lossage ("nested assembly dialect alternatives"); | |
3179 else | |
3180 dialect = 1; | |
3181 | |
3182 /* If we want the first dialect, do nothing. Otherwise, skip | |
3183 DIALECT_NUMBER of strings ending with '|'. */ | |
3184 for (i = 0; i < dialect_number; i++) | |
3185 { | |
3186 while (*p && *p != '}' && *p++ != '|') | |
3187 ; | |
3188 if (*p == '}') | |
3189 break; | |
3190 if (*p == '|') | |
3191 p++; | |
3192 } | |
3193 | |
3194 if (*p == '\0') | |
3195 output_operand_lossage ("unterminated assembly dialect alternative"); | |
3196 } | |
3197 break; | |
3198 | |
3199 case '|': | |
3200 if (dialect) | |
3201 { | |
3202 /* Skip to close brace. */ | |
3203 do | |
3204 { | |
3205 if (*p == '\0') | |
3206 { | |
3207 output_operand_lossage ("unterminated assembly dialect alternative"); | |
3208 break; | |
3209 } | |
3210 } | |
3211 while (*p++ != '}'); | |
3212 dialect = 0; | |
3213 } | |
3214 else | |
3215 putc (c, asm_out_file); | |
3216 break; | |
3217 | |
3218 case '}': | |
3219 if (! dialect) | |
3220 putc (c, asm_out_file); | |
3221 dialect = 0; | |
3222 break; | |
3223 #endif | |
3224 | |
3225 case '%': | |
3226 /* %% outputs a single %. */ | |
3227 if (*p == '%') | |
3228 { | |
3229 p++; | |
3230 putc (c, asm_out_file); | |
3231 } | |
3232 /* %= outputs a number which is unique to each insn in the entire | |
3233 compilation. This is useful for making local labels that are | |
3234 referred to more than once in a given insn. */ | |
3235 else if (*p == '=') | |
3236 { | |
3237 p++; | |
3238 fprintf (asm_out_file, "%d", insn_counter); | |
3239 } | |
3240 /* % followed by a letter and some digits | |
3241 outputs an operand in a special way depending on the letter. | |
3242 Letters `acln' are implemented directly. | |
3243 Other letters are passed to `output_operand' so that | |
3244 the PRINT_OPERAND macro can define them. */ | |
3245 else if (ISALPHA (*p)) | |
3246 { | |
3247 int letter = *p++; | |
3248 unsigned long opnum; | |
3249 char *endptr; | |
3250 | |
3251 opnum = strtoul (p, &endptr, 10); | |
3252 | |
3253 if (endptr == p) | |
3254 output_operand_lossage ("operand number missing " | |
3255 "after %%-letter"); | |
3256 else if (this_is_asm_operands && opnum >= insn_noperands) | |
3257 output_operand_lossage ("operand number out of range"); | |
3258 else if (letter == 'l') | |
3259 output_asm_label (operands[opnum]); | |
3260 else if (letter == 'a') | |
3261 output_address (operands[opnum]); | |
3262 else if (letter == 'c') | |
3263 { | |
3264 if (CONSTANT_ADDRESS_P (operands[opnum])) | |
3265 output_addr_const (asm_out_file, operands[opnum]); | |
3266 else | |
3267 output_operand (operands[opnum], 'c'); | |
3268 } | |
3269 else if (letter == 'n') | |
3270 { | |
3271 if (GET_CODE (operands[opnum]) == CONST_INT) | |
3272 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, | |
3273 - INTVAL (operands[opnum])); | |
3274 else | |
3275 { | |
3276 putc ('-', asm_out_file); | |
3277 output_addr_const (asm_out_file, operands[opnum]); | |
3278 } | |
3279 } | |
3280 else | |
3281 output_operand (operands[opnum], letter); | |
3282 | |
3283 if (!opoutput[opnum]) | |
3284 oporder[ops++] = opnum; | |
3285 opoutput[opnum] = 1; | |
3286 | |
3287 p = endptr; | |
3288 c = *p; | |
3289 } | |
3290 /* % followed by a digit outputs an operand the default way. */ | |
3291 else if (ISDIGIT (*p)) | |
3292 { | |
3293 unsigned long opnum; | |
3294 char *endptr; | |
3295 | |
3296 opnum = strtoul (p, &endptr, 10); | |
3297 if (this_is_asm_operands && opnum >= insn_noperands) | |
3298 output_operand_lossage ("operand number out of range"); | |
3299 else | |
3300 output_operand (operands[opnum], 0); | |
3301 | |
3302 if (!opoutput[opnum]) | |
3303 oporder[ops++] = opnum; | |
3304 opoutput[opnum] = 1; | |
3305 | |
3306 p = endptr; | |
3307 c = *p; | |
3308 } | |
3309 /* % followed by punctuation: output something for that | |
3310 punctuation character alone, with no operand. | |
3311 The PRINT_OPERAND macro decides what is actually done. */ | |
3312 #ifdef PRINT_OPERAND_PUNCT_VALID_P | |
3313 else if (PRINT_OPERAND_PUNCT_VALID_P ((unsigned char) *p)) | |
3314 output_operand (NULL_RTX, *p++); | |
3315 #endif | |
3316 else | |
3317 output_operand_lossage ("invalid %%-code"); | |
3318 break; | |
3319 | |
3320 default: | |
3321 putc (c, asm_out_file); | |
3322 } | |
3323 | |
3324 /* Write out the variable names for operands, if we know them. */ | |
3325 if (flag_verbose_asm) | |
3326 output_asm_operand_names (operands, oporder, ops); | |
3327 if (flag_print_asm_name) | |
3328 output_asm_name (); | |
3329 | |
3330 putc ('\n', asm_out_file); | |
3331 } | |
3332 | |
3333 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ | |
3334 | |
3335 void | |
3336 output_asm_label (rtx x) | |
3337 { | |
3338 char buf[256]; | |
3339 | |
3340 if (GET_CODE (x) == LABEL_REF) | |
3341 x = XEXP (x, 0); | |
3342 if (LABEL_P (x) | |
3343 || (NOTE_P (x) | |
3344 && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL)) | |
3345 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); | |
3346 else | |
3347 output_operand_lossage ("'%%l' operand isn't a label"); | |
3348 | |
3349 assemble_name (asm_out_file, buf); | |
3350 } | |
3351 | |
3352 /* Helper rtx-iteration-function for mark_symbol_refs_as_used and | |
3353 output_operand. Marks SYMBOL_REFs as referenced through use of | |
3354 assemble_external. */ | |
3355 | |
3356 static int | |
3357 mark_symbol_ref_as_used (rtx *xp, void *dummy ATTRIBUTE_UNUSED) | |
3358 { | |
3359 rtx x = *xp; | |
3360 | |
3361 /* If we have a used symbol, we may have to emit assembly | |
3362 annotations corresponding to whether the symbol is external, weak | |
3363 or has non-default visibility. */ | |
3364 if (GET_CODE (x) == SYMBOL_REF) | |
3365 { | |
3366 tree t; | |
3367 | |
3368 t = SYMBOL_REF_DECL (x); | |
3369 if (t) | |
3370 assemble_external (t); | |
3371 | |
3372 return -1; | |
3373 } | |
3374 | |
3375 return 0; | |
3376 } | |
3377 | |
3378 /* Marks SYMBOL_REFs in x as referenced through use of assemble_external. */ | |
3379 | |
3380 void | |
3381 mark_symbol_refs_as_used (rtx x) | |
3382 { | |
3383 for_each_rtx (&x, mark_symbol_ref_as_used, NULL); | |
3384 } | |
3385 | |
3386 /* Print operand X using machine-dependent assembler syntax. | |
3387 The macro PRINT_OPERAND is defined just to control this function. | |
3388 CODE is a non-digit that preceded the operand-number in the % spec, | |
3389 such as 'z' if the spec was `%z3'. CODE is 0 if there was no char | |
3390 between the % and the digits. | |
3391 When CODE is a non-letter, X is 0. | |
3392 | |
3393 The meanings of the letters are machine-dependent and controlled | |
3394 by PRINT_OPERAND. */ | |
3395 | |
3396 static void | |
3397 output_operand (rtx x, int code ATTRIBUTE_UNUSED) | |
3398 { | |
3399 if (x && GET_CODE (x) == SUBREG) | |
3400 x = alter_subreg (&x); | |
3401 | |
3402 /* X must not be a pseudo reg. */ | |
3403 gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); | |
3404 | |
3405 PRINT_OPERAND (asm_out_file, x, code); | |
3406 | |
3407 if (x == NULL_RTX) | |
3408 return; | |
3409 | |
3410 for_each_rtx (&x, mark_symbol_ref_as_used, NULL); | |
3411 } | |
3412 | |
3413 /* Print a memory reference operand for address X | |
3414 using machine-dependent assembler syntax. | |
3415 The macro PRINT_OPERAND_ADDRESS exists just to control this function. */ | |
3416 | |
3417 void | |
3418 output_address (rtx x) | |
3419 { | |
3420 bool changed = false; | |
3421 walk_alter_subreg (&x, &changed); | |
3422 PRINT_OPERAND_ADDRESS (asm_out_file, x); | |
3423 } | |
3424 | |
3425 /* Print an integer constant expression in assembler syntax. | |
3426 Addition and subtraction are the only arithmetic | |
3427 that may appear in these expressions. */ | |
3428 | |
3429 void | |
3430 output_addr_const (FILE *file, rtx x) | |
3431 { | |
3432 char buf[256]; | |
3433 | |
3434 restart: | |
3435 switch (GET_CODE (x)) | |
3436 { | |
3437 case PC: | |
3438 putc ('.', file); | |
3439 break; | |
3440 | |
3441 case SYMBOL_REF: | |
3442 if (SYMBOL_REF_DECL (x)) | |
3443 { | |
3444 mark_decl_referenced (SYMBOL_REF_DECL (x)); | |
3445 assemble_external (SYMBOL_REF_DECL (x)); | |
3446 } | |
3447 #ifdef ASM_OUTPUT_SYMBOL_REF | |
3448 ASM_OUTPUT_SYMBOL_REF (file, x); | |
3449 #else | |
3450 assemble_name (file, XSTR (x, 0)); | |
3451 #endif | |
3452 break; | |
3453 | |
3454 case LABEL_REF: | |
3455 x = XEXP (x, 0); | |
3456 /* Fall through. */ | |
3457 case CODE_LABEL: | |
3458 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); | |
3459 #ifdef ASM_OUTPUT_LABEL_REF | |
3460 ASM_OUTPUT_LABEL_REF (file, buf); | |
3461 #else | |
3462 assemble_name (file, buf); | |
3463 #endif | |
3464 break; | |
3465 | |
3466 case CONST_INT: | |
3467 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); | |
3468 break; | |
3469 | |
3470 case CONST: | |
3471 /* This used to output parentheses around the expression, | |
3472 but that does not work on the 386 (either ATT or BSD assembler). */ | |
3473 output_addr_const (file, XEXP (x, 0)); | |
3474 break; | |
3475 | |
3476 case CONST_DOUBLE: | |
3477 if (GET_MODE (x) == VOIDmode) | |
3478 { | |
3479 /* We can use %d if the number is one word and positive. */ | |
3480 if (CONST_DOUBLE_HIGH (x)) | |
3481 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, | |
3482 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x), | |
3483 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); | |
3484 else if (CONST_DOUBLE_LOW (x) < 0) | |
3485 fprintf (file, HOST_WIDE_INT_PRINT_HEX, | |
3486 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); | |
3487 else | |
3488 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); | |
3489 } | |
3490 else | |
3491 /* We can't handle floating point constants; | |
3492 PRINT_OPERAND must handle them. */ | |
3493 output_operand_lossage ("floating constant misused"); | |
3494 break; | |
3495 | |
3496 case CONST_FIXED: | |
3497 fprintf (file, HOST_WIDE_INT_PRINT_HEX, | |
3498 (unsigned HOST_WIDE_INT) CONST_FIXED_VALUE_LOW (x)); | |
3499 break; | |
3500 | |
3501 case PLUS: | |
3502 /* Some assemblers need integer constants to appear last (eg masm). */ | |
3503 if (GET_CODE (XEXP (x, 0)) == CONST_INT) | |
3504 { | |
3505 output_addr_const (file, XEXP (x, 1)); | |
3506 if (INTVAL (XEXP (x, 0)) >= 0) | |
3507 fprintf (file, "+"); | |
3508 output_addr_const (file, XEXP (x, 0)); | |
3509 } | |
3510 else | |
3511 { | |
3512 output_addr_const (file, XEXP (x, 0)); | |
3513 if (GET_CODE (XEXP (x, 1)) != CONST_INT | |
3514 || INTVAL (XEXP (x, 1)) >= 0) | |
3515 fprintf (file, "+"); | |
3516 output_addr_const (file, XEXP (x, 1)); | |
3517 } | |
3518 break; | |
3519 | |
3520 case MINUS: | |
3521 /* Avoid outputting things like x-x or x+5-x, | |
3522 since some assemblers can't handle that. */ | |
3523 x = simplify_subtraction (x); | |
3524 if (GET_CODE (x) != MINUS) | |
3525 goto restart; | |
3526 | |
3527 output_addr_const (file, XEXP (x, 0)); | |
3528 fprintf (file, "-"); | |
3529 if ((GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0) | |
3530 || GET_CODE (XEXP (x, 1)) == PC | |
3531 || GET_CODE (XEXP (x, 1)) == SYMBOL_REF) | |
3532 output_addr_const (file, XEXP (x, 1)); | |
3533 else | |
3534 { | |
3535 fputs (targetm.asm_out.open_paren, file); | |
3536 output_addr_const (file, XEXP (x, 1)); | |
3537 fputs (targetm.asm_out.close_paren, file); | |
3538 } | |
3539 break; | |
3540 | |
3541 case ZERO_EXTEND: | |
3542 case SIGN_EXTEND: | |
3543 case SUBREG: | |
3544 case TRUNCATE: | |
3545 output_addr_const (file, XEXP (x, 0)); | |
3546 break; | |
3547 | |
3548 default: | |
3549 #ifdef OUTPUT_ADDR_CONST_EXTRA | |
3550 OUTPUT_ADDR_CONST_EXTRA (file, x, fail); | |
3551 break; | |
3552 | |
3553 fail: | |
3554 #endif | |
3555 output_operand_lossage ("invalid expression as operand"); | |
3556 } | |
3557 } | |
3558 | |
3559 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U. | |
3560 %R prints the value of REGISTER_PREFIX. | |
3561 %L prints the value of LOCAL_LABEL_PREFIX. | |
3562 %U prints the value of USER_LABEL_PREFIX. | |
3563 %I prints the value of IMMEDIATE_PREFIX. | |
3564 %O runs ASM_OUTPUT_OPCODE to transform what follows in the string. | |
3565 Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%. | |
3566 | |
3567 We handle alternate assembler dialects here, just like output_asm_insn. */ | |
3568 | |
3569 void | |
3570 asm_fprintf (FILE *file, const char *p, ...) | |
3571 { | |
3572 char buf[10]; | |
3573 char *q, c; | |
3574 va_list argptr; | |
3575 | |
3576 va_start (argptr, p); | |
3577 | |
3578 buf[0] = '%'; | |
3579 | |
3580 while ((c = *p++)) | |
3581 switch (c) | |
3582 { | |
3583 #ifdef ASSEMBLER_DIALECT | |
3584 case '{': | |
3585 { | |
3586 int i; | |
3587 | |
3588 /* If we want the first dialect, do nothing. Otherwise, skip | |
3589 DIALECT_NUMBER of strings ending with '|'. */ | |
3590 for (i = 0; i < dialect_number; i++) | |
3591 { | |
3592 while (*p && *p++ != '|') | |
3593 ; | |
3594 | |
3595 if (*p == '|') | |
3596 p++; | |
3597 } | |
3598 } | |
3599 break; | |
3600 | |
3601 case '|': | |
3602 /* Skip to close brace. */ | |
3603 while (*p && *p++ != '}') | |
3604 ; | |
3605 break; | |
3606 | |
3607 case '}': | |
3608 break; | |
3609 #endif | |
3610 | |
3611 case '%': | |
3612 c = *p++; | |
3613 q = &buf[1]; | |
3614 while (strchr ("-+ #0", c)) | |
3615 { | |
3616 *q++ = c; | |
3617 c = *p++; | |
3618 } | |
3619 while (ISDIGIT (c) || c == '.') | |
3620 { | |
3621 *q++ = c; | |
3622 c = *p++; | |
3623 } | |
3624 switch (c) | |
3625 { | |
3626 case '%': | |
3627 putc ('%', file); | |
3628 break; | |
3629 | |
3630 case 'd': case 'i': case 'u': | |
3631 case 'x': case 'X': case 'o': | |
3632 case 'c': | |
3633 *q++ = c; | |
3634 *q = 0; | |
3635 fprintf (file, buf, va_arg (argptr, int)); | |
3636 break; | |
3637 | |
3638 case 'w': | |
3639 /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and | |
3640 'o' cases, but we do not check for those cases. It | |
3641 means that the value is a HOST_WIDE_INT, which may be | |
3642 either `long' or `long long'. */ | |
3643 memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT)); | |
3644 q += strlen (HOST_WIDE_INT_PRINT); | |
3645 *q++ = *p++; | |
3646 *q = 0; | |
3647 fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT)); | |
3648 break; | |
3649 | |
3650 case 'l': | |
3651 *q++ = c; | |
3652 #ifdef HAVE_LONG_LONG | |
3653 if (*p == 'l') | |
3654 { | |
3655 *q++ = *p++; | |
3656 *q++ = *p++; | |
3657 *q = 0; | |
3658 fprintf (file, buf, va_arg (argptr, long long)); | |
3659 } | |
3660 else | |
3661 #endif | |
3662 { | |
3663 *q++ = *p++; | |
3664 *q = 0; | |
3665 fprintf (file, buf, va_arg (argptr, long)); | |
3666 } | |
3667 | |
3668 break; | |
3669 | |
3670 case 's': | |
3671 *q++ = c; | |
3672 *q = 0; | |
3673 fprintf (file, buf, va_arg (argptr, char *)); | |
3674 break; | |
3675 | |
3676 case 'O': | |
3677 #ifdef ASM_OUTPUT_OPCODE | |
3678 ASM_OUTPUT_OPCODE (asm_out_file, p); | |
3679 #endif | |
3680 break; | |
3681 | |
3682 case 'R': | |
3683 #ifdef REGISTER_PREFIX | |
3684 fprintf (file, "%s", REGISTER_PREFIX); | |
3685 #endif | |
3686 break; | |
3687 | |
3688 case 'I': | |
3689 #ifdef IMMEDIATE_PREFIX | |
3690 fprintf (file, "%s", IMMEDIATE_PREFIX); | |
3691 #endif | |
3692 break; | |
3693 | |
3694 case 'L': | |
3695 #ifdef LOCAL_LABEL_PREFIX | |
3696 fprintf (file, "%s", LOCAL_LABEL_PREFIX); | |
3697 #endif | |
3698 break; | |
3699 | |
3700 case 'U': | |
3701 fputs (user_label_prefix, file); | |
3702 break; | |
3703 | |
3704 #ifdef ASM_FPRINTF_EXTENSIONS | |
3705 /* Uppercase letters are reserved for general use by asm_fprintf | |
3706 and so are not available to target specific code. In order to | |
3707 prevent the ASM_FPRINTF_EXTENSIONS macro from using them then, | |
3708 they are defined here. As they get turned into real extensions | |
3709 to asm_fprintf they should be removed from this list. */ | |
3710 case 'A': case 'B': case 'C': case 'D': case 'E': | |
3711 case 'F': case 'G': case 'H': case 'J': case 'K': | |
3712 case 'M': case 'N': case 'P': case 'Q': case 'S': | |
3713 case 'T': case 'V': case 'W': case 'Y': case 'Z': | |
3714 break; | |
3715 | |
3716 ASM_FPRINTF_EXTENSIONS (file, argptr, p) | |
3717 #endif | |
3718 default: | |
3719 gcc_unreachable (); | |
3720 } | |
3721 break; | |
3722 | |
3723 default: | |
3724 putc (c, file); | |
3725 } | |
3726 va_end (argptr); | |
3727 } | |
3728 | |
3729 /* Split up a CONST_DOUBLE or integer constant rtx | |
3730 into two rtx's for single words, | |
3731 storing in *FIRST the word that comes first in memory in the target | |
3732 and in *SECOND the other. */ | |
3733 | |
3734 void | |
3735 split_double (rtx value, rtx *first, rtx *second) | |
3736 { | |
3737 if (GET_CODE (value) == CONST_INT) | |
3738 { | |
3739 if (HOST_BITS_PER_WIDE_INT >= (2 * BITS_PER_WORD)) | |
3740 { | |
3741 /* In this case the CONST_INT holds both target words. | |
3742 Extract the bits from it into two word-sized pieces. | |
3743 Sign extend each half to HOST_WIDE_INT. */ | |
3744 unsigned HOST_WIDE_INT low, high; | |
3745 unsigned HOST_WIDE_INT mask, sign_bit, sign_extend; | |
3746 | |
3747 /* Set sign_bit to the most significant bit of a word. */ | |
3748 sign_bit = 1; | |
3749 sign_bit <<= BITS_PER_WORD - 1; | |
3750 | |
3751 /* Set mask so that all bits of the word are set. We could | |
3752 have used 1 << BITS_PER_WORD instead of basing the | |
3753 calculation on sign_bit. However, on machines where | |
3754 HOST_BITS_PER_WIDE_INT == BITS_PER_WORD, it could cause a | |
3755 compiler warning, even though the code would never be | |
3756 executed. */ | |
3757 mask = sign_bit << 1; | |
3758 mask--; | |
3759 | |
3760 /* Set sign_extend as any remaining bits. */ | |
3761 sign_extend = ~mask; | |
3762 | |
3763 /* Pick the lower word and sign-extend it. */ | |
3764 low = INTVAL (value); | |
3765 low &= mask; | |
3766 if (low & sign_bit) | |
3767 low |= sign_extend; | |
3768 | |
3769 /* Pick the higher word, shifted to the least significant | |
3770 bits, and sign-extend it. */ | |
3771 high = INTVAL (value); | |
3772 high >>= BITS_PER_WORD - 1; | |
3773 high >>= 1; | |
3774 high &= mask; | |
3775 if (high & sign_bit) | |
3776 high |= sign_extend; | |
3777 | |
3778 /* Store the words in the target machine order. */ | |
3779 if (WORDS_BIG_ENDIAN) | |
3780 { | |
3781 *first = GEN_INT (high); | |
3782 *second = GEN_INT (low); | |
3783 } | |
3784 else | |
3785 { | |
3786 *first = GEN_INT (low); | |
3787 *second = GEN_INT (high); | |
3788 } | |
3789 } | |
3790 else | |
3791 { | |
3792 /* The rule for using CONST_INT for a wider mode | |
3793 is that we regard the value as signed. | |
3794 So sign-extend it. */ | |
3795 rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx); | |
3796 if (WORDS_BIG_ENDIAN) | |
3797 { | |
3798 *first = high; | |
3799 *second = value; | |
3800 } | |
3801 else | |
3802 { | |
3803 *first = value; | |
3804 *second = high; | |
3805 } | |
3806 } | |
3807 } | |
3808 else if (GET_CODE (value) != CONST_DOUBLE) | |
3809 { | |
3810 if (WORDS_BIG_ENDIAN) | |
3811 { | |
3812 *first = const0_rtx; | |
3813 *second = value; | |
3814 } | |
3815 else | |
3816 { | |
3817 *first = value; | |
3818 *second = const0_rtx; | |
3819 } | |
3820 } | |
3821 else if (GET_MODE (value) == VOIDmode | |
3822 /* This is the old way we did CONST_DOUBLE integers. */ | |
3823 || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT) | |
3824 { | |
3825 /* In an integer, the words are defined as most and least significant. | |
3826 So order them by the target's convention. */ | |
3827 if (WORDS_BIG_ENDIAN) | |
3828 { | |
3829 *first = GEN_INT (CONST_DOUBLE_HIGH (value)); | |
3830 *second = GEN_INT (CONST_DOUBLE_LOW (value)); | |
3831 } | |
3832 else | |
3833 { | |
3834 *first = GEN_INT (CONST_DOUBLE_LOW (value)); | |
3835 *second = GEN_INT (CONST_DOUBLE_HIGH (value)); | |
3836 } | |
3837 } | |
3838 else | |
3839 { | |
3840 REAL_VALUE_TYPE r; | |
3841 long l[2]; | |
3842 REAL_VALUE_FROM_CONST_DOUBLE (r, value); | |
3843 | |
3844 /* Note, this converts the REAL_VALUE_TYPE to the target's | |
3845 format, splits up the floating point double and outputs | |
3846 exactly 32 bits of it into each of l[0] and l[1] -- | |
3847 not necessarily BITS_PER_WORD bits. */ | |
3848 REAL_VALUE_TO_TARGET_DOUBLE (r, l); | |
3849 | |
3850 /* If 32 bits is an entire word for the target, but not for the host, | |
3851 then sign-extend on the host so that the number will look the same | |
3852 way on the host that it would on the target. See for instance | |
3853 simplify_unary_operation. The #if is needed to avoid compiler | |
3854 warnings. */ | |
3855 | |
3856 #if HOST_BITS_PER_LONG > 32 | |
3857 if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32) | |
3858 { | |
3859 if (l[0] & ((long) 1 << 31)) | |
3860 l[0] |= ((long) (-1) << 32); | |
3861 if (l[1] & ((long) 1 << 31)) | |
3862 l[1] |= ((long) (-1) << 32); | |
3863 } | |
3864 #endif | |
3865 | |
3866 *first = GEN_INT (l[0]); | |
3867 *second = GEN_INT (l[1]); | |
3868 } | |
3869 } | |
3870 | |
3871 /* Return nonzero if this function has no function calls. */ | |
3872 | |
3873 int | |
3874 leaf_function_p (void) | |
3875 { | |
3876 rtx insn; | |
3877 rtx link; | |
3878 | |
3879 if (crtl->profile || profile_arc_flag) | |
3880 return 0; | |
3881 | |
3882 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | |
3883 { | |
3884 if (CALL_P (insn) | |
3885 && ! SIBLING_CALL_P (insn)) | |
3886 return 0; | |
3887 if (NONJUMP_INSN_P (insn) | |
3888 && GET_CODE (PATTERN (insn)) == SEQUENCE | |
3889 && CALL_P (XVECEXP (PATTERN (insn), 0, 0)) | |
3890 && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0))) | |
3891 return 0; | |
3892 } | |
3893 for (link = crtl->epilogue_delay_list; | |
3894 link; | |
3895 link = XEXP (link, 1)) | |
3896 { | |
3897 insn = XEXP (link, 0); | |
3898 | |
3899 if (CALL_P (insn) | |
3900 && ! SIBLING_CALL_P (insn)) | |
3901 return 0; | |
3902 if (NONJUMP_INSN_P (insn) | |
3903 && GET_CODE (PATTERN (insn)) == SEQUENCE | |
3904 && CALL_P (XVECEXP (PATTERN (insn), 0, 0)) | |
3905 && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0))) | |
3906 return 0; | |
3907 } | |
3908 | |
3909 return 1; | |
3910 } | |
3911 | |
3912 /* Return 1 if branch is a forward branch. | |
3913 Uses insn_shuid array, so it works only in the final pass. May be used by | |
3914 output templates to customary add branch prediction hints. | |
3915 */ | |
3916 int | |
3917 final_forward_branch_p (rtx insn) | |
3918 { | |
3919 int insn_id, label_id; | |
3920 | |
3921 gcc_assert (uid_shuid); | |
3922 insn_id = INSN_SHUID (insn); | |
3923 label_id = INSN_SHUID (JUMP_LABEL (insn)); | |
3924 /* We've hit some insns that does not have id information available. */ | |
3925 gcc_assert (insn_id && label_id); | |
3926 return insn_id < label_id; | |
3927 } | |
3928 | |
3929 /* On some machines, a function with no call insns | |
3930 can run faster if it doesn't create its own register window. | |
3931 When output, the leaf function should use only the "output" | |
3932 registers. Ordinarily, the function would be compiled to use | |
3933 the "input" registers to find its arguments; it is a candidate | |
3934 for leaf treatment if it uses only the "input" registers. | |
3935 Leaf function treatment means renumbering so the function | |
3936 uses the "output" registers instead. */ | |
3937 | |
3938 #ifdef LEAF_REGISTERS | |
3939 | |
3940 /* Return 1 if this function uses only the registers that can be | |
3941 safely renumbered. */ | |
3942 | |
3943 int | |
3944 only_leaf_regs_used (void) | |
3945 { | |
3946 int i; | |
3947 const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS; | |
3948 | |
3949 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
3950 if ((df_regs_ever_live_p (i) || global_regs[i]) | |
3951 && ! permitted_reg_in_leaf_functions[i]) | |
3952 return 0; | |
3953 | |
3954 if (crtl->uses_pic_offset_table | |
3955 && pic_offset_table_rtx != 0 | |
3956 && REG_P (pic_offset_table_rtx) | |
3957 && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)]) | |
3958 return 0; | |
3959 | |
3960 return 1; | |
3961 } | |
3962 | |
3963 /* Scan all instructions and renumber all registers into those | |
3964 available in leaf functions. */ | |
3965 | |
3966 static void | |
3967 leaf_renumber_regs (rtx first) | |
3968 { | |
3969 rtx insn; | |
3970 | |
3971 /* Renumber only the actual patterns. | |
3972 The reg-notes can contain frame pointer refs, | |
3973 and renumbering them could crash, and should not be needed. */ | |
3974 for (insn = first; insn; insn = NEXT_INSN (insn)) | |
3975 if (INSN_P (insn)) | |
3976 leaf_renumber_regs_insn (PATTERN (insn)); | |
3977 for (insn = crtl->epilogue_delay_list; | |
3978 insn; | |
3979 insn = XEXP (insn, 1)) | |
3980 if (INSN_P (XEXP (insn, 0))) | |
3981 leaf_renumber_regs_insn (PATTERN (XEXP (insn, 0))); | |
3982 } | |
3983 | |
3984 /* Scan IN_RTX and its subexpressions, and renumber all regs into those | |
3985 available in leaf functions. */ | |
3986 | |
3987 void | |
3988 leaf_renumber_regs_insn (rtx in_rtx) | |
3989 { | |
3990 int i, j; | |
3991 const char *format_ptr; | |
3992 | |
3993 if (in_rtx == 0) | |
3994 return; | |
3995 | |
3996 /* Renumber all input-registers into output-registers. | |
3997 renumbered_regs would be 1 for an output-register; | |
3998 they */ | |
3999 | |
4000 if (REG_P (in_rtx)) | |
4001 { | |
4002 int newreg; | |
4003 | |
4004 /* Don't renumber the same reg twice. */ | |
4005 if (in_rtx->used) | |
4006 return; | |
4007 | |
4008 newreg = REGNO (in_rtx); | |
4009 /* Don't try to renumber pseudo regs. It is possible for a pseudo reg | |
4010 to reach here as part of a REG_NOTE. */ | |
4011 if (newreg >= FIRST_PSEUDO_REGISTER) | |
4012 { | |
4013 in_rtx->used = 1; | |
4014 return; | |
4015 } | |
4016 newreg = LEAF_REG_REMAP (newreg); | |
4017 gcc_assert (newreg >= 0); | |
4018 df_set_regs_ever_live (REGNO (in_rtx), false); | |
4019 df_set_regs_ever_live (newreg, true); | |
4020 SET_REGNO (in_rtx, newreg); | |
4021 in_rtx->used = 1; | |
4022 } | |
4023 | |
4024 if (INSN_P (in_rtx)) | |
4025 { | |
4026 /* Inside a SEQUENCE, we find insns. | |
4027 Renumber just the patterns of these insns, | |
4028 just as we do for the top-level insns. */ | |
4029 leaf_renumber_regs_insn (PATTERN (in_rtx)); | |
4030 return; | |
4031 } | |
4032 | |
4033 format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); | |
4034 | |
4035 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) | |
4036 switch (*format_ptr++) | |
4037 { | |
4038 case 'e': | |
4039 leaf_renumber_regs_insn (XEXP (in_rtx, i)); | |
4040 break; | |
4041 | |
4042 case 'E': | |
4043 if (NULL != XVEC (in_rtx, i)) | |
4044 { | |
4045 for (j = 0; j < XVECLEN (in_rtx, i); j++) | |
4046 leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j)); | |
4047 } | |
4048 break; | |
4049 | |
4050 case 'S': | |
4051 case 's': | |
4052 case '0': | |
4053 case 'i': | |
4054 case 'w': | |
4055 case 'n': | |
4056 case 'u': | |
4057 break; | |
4058 | |
4059 default: | |
4060 gcc_unreachable (); | |
4061 } | |
4062 } | |
4063 #endif | |
4064 | |
4065 | |
4066 /* When -gused is used, emit debug info for only used symbols. But in | |
4067 addition to the standard intercepted debug_hooks there are some direct | |
4068 calls into this file, i.e., dbxout_symbol, dbxout_parms, and dbxout_reg_params. | |
4069 Those routines may also be called from a higher level intercepted routine. So | |
4070 to prevent recording data for an inner call to one of these for an intercept, | |
4071 we maintain an intercept nesting counter (debug_nesting). We only save the | |
4072 intercepted arguments if the nesting is 1. */ | |
4073 int debug_nesting = 0; | |
4074 | |
4075 static tree *symbol_queue; | |
4076 int symbol_queue_index = 0; | |
4077 static int symbol_queue_size = 0; | |
4078 | |
4079 /* Generate the symbols for any queued up type symbols we encountered | |
4080 while generating the type info for some originally used symbol. | |
4081 This might generate additional entries in the queue. Only when | |
4082 the nesting depth goes to 0 is this routine called. */ | |
4083 | |
4084 void | |
4085 debug_flush_symbol_queue (void) | |
4086 { | |
4087 int i; | |
4088 | |
4089 /* Make sure that additionally queued items are not flushed | |
4090 prematurely. */ | |
4091 | |
4092 ++debug_nesting; | |
4093 | |
4094 for (i = 0; i < symbol_queue_index; ++i) | |
4095 { | |
4096 /* If we pushed queued symbols then such symbols must be | |
4097 output no matter what anyone else says. Specifically, | |
4098 we need to make sure dbxout_symbol() thinks the symbol was | |
4099 used and also we need to override TYPE_DECL_SUPPRESS_DEBUG | |
4100 which may be set for outside reasons. */ | |
4101 int saved_tree_used = TREE_USED (symbol_queue[i]); | |
4102 int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]); | |
4103 TREE_USED (symbol_queue[i]) = 1; | |
4104 TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0; | |
4105 | |
4106 #ifdef DBX_DEBUGGING_INFO | |
4107 dbxout_symbol (symbol_queue[i], 0); | |
4108 #endif | |
4109 | |
4110 TREE_USED (symbol_queue[i]) = saved_tree_used; | |
4111 TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug; | |
4112 } | |
4113 | |
4114 symbol_queue_index = 0; | |
4115 --debug_nesting; | |
4116 } | |
4117 | |
4118 /* Queue a type symbol needed as part of the definition of a decl | |
4119 symbol. These symbols are generated when debug_flush_symbol_queue() | |
4120 is called. */ | |
4121 | |
4122 void | |
4123 debug_queue_symbol (tree decl) | |
4124 { | |
4125 if (symbol_queue_index >= symbol_queue_size) | |
4126 { | |
4127 symbol_queue_size += 10; | |
4128 symbol_queue = XRESIZEVEC (tree, symbol_queue, symbol_queue_size); | |
4129 } | |
4130 | |
4131 symbol_queue[symbol_queue_index++] = decl; | |
4132 } | |
4133 | |
4134 /* Free symbol queue. */ | |
4135 void | |
4136 debug_free_queue (void) | |
4137 { | |
4138 if (symbol_queue) | |
4139 { | |
4140 free (symbol_queue); | |
4141 symbol_queue = NULL; | |
4142 symbol_queue_size = 0; | |
4143 } | |
4144 } | |
4145 | |
4146 /* Turn the RTL into assembly. */ | |
4147 static unsigned int | |
4148 rest_of_handle_final (void) | |
4149 { | |
4150 rtx x; | |
4151 const char *fnname; | |
4152 | |
4153 /* Get the function's name, as described by its RTL. This may be | |
4154 different from the DECL_NAME name used in the source file. */ | |
4155 | |
4156 x = DECL_RTL (current_function_decl); | |
4157 gcc_assert (MEM_P (x)); | |
4158 x = XEXP (x, 0); | |
4159 gcc_assert (GET_CODE (x) == SYMBOL_REF); | |
4160 fnname = XSTR (x, 0); | |
4161 | |
4162 assemble_start_function (current_function_decl, fnname); | |
4163 final_start_function (get_insns (), asm_out_file, optimize); | |
4164 final (get_insns (), asm_out_file, optimize); | |
4165 final_end_function (); | |
4166 | |
4167 #ifdef TARGET_UNWIND_INFO | |
4168 /* ??? The IA-64 ".handlerdata" directive must be issued before | |
4169 the ".endp" directive that closes the procedure descriptor. */ | |
4170 output_function_exception_table (fnname); | |
4171 #endif | |
4172 | |
4173 assemble_end_function (current_function_decl, fnname); | |
4174 | |
4175 #ifndef TARGET_UNWIND_INFO | |
4176 /* Otherwise, it feels unclean to switch sections in the middle. */ | |
4177 output_function_exception_table (fnname); | |
4178 #endif | |
4179 | |
4180 user_defined_section_attribute = false; | |
4181 | |
4182 /* Free up reg info memory. */ | |
4183 free_reg_info (); | |
4184 | |
4185 if (! quiet_flag) | |
4186 fflush (asm_out_file); | |
4187 | |
4188 /* Write DBX symbols if requested. */ | |
4189 | |
4190 /* Note that for those inline functions where we don't initially | |
4191 know for certain that we will be generating an out-of-line copy, | |
4192 the first invocation of this routine (rest_of_compilation) will | |
4193 skip over this code by doing a `goto exit_rest_of_compilation;'. | |
4194 Later on, wrapup_global_declarations will (indirectly) call | |
4195 rest_of_compilation again for those inline functions that need | |
4196 to have out-of-line copies generated. During that call, we | |
4197 *will* be routed past here. */ | |
4198 | |
4199 timevar_push (TV_SYMOUT); | |
4200 (*debug_hooks->function_decl) (current_function_decl); | |
4201 timevar_pop (TV_SYMOUT); | |
4202 | |
4203 /* Release the blocks that are linked to DECL_INITIAL() to free the memory. */ | |
4204 DECL_INITIAL (current_function_decl) = error_mark_node; | |
4205 | |
4206 if (DECL_STATIC_CONSTRUCTOR (current_function_decl) | |
4207 && targetm.have_ctors_dtors) | |
4208 targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0), | |
4209 decl_init_priority_lookup | |
4210 (current_function_decl)); | |
4211 if (DECL_STATIC_DESTRUCTOR (current_function_decl) | |
4212 && targetm.have_ctors_dtors) | |
4213 targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0), | |
4214 decl_fini_priority_lookup | |
4215 (current_function_decl)); | |
4216 return 0; | |
4217 } | |
4218 | |
4219 struct rtl_opt_pass pass_final = | |
4220 { | |
4221 { | |
4222 RTL_PASS, | |
4223 NULL, /* name */ | |
4224 NULL, /* gate */ | |
4225 rest_of_handle_final, /* execute */ | |
4226 NULL, /* sub */ | |
4227 NULL, /* next */ | |
4228 0, /* static_pass_number */ | |
4229 TV_FINAL, /* tv_id */ | |
4230 0, /* properties_required */ | |
4231 0, /* properties_provided */ | |
4232 0, /* properties_destroyed */ | |
4233 0, /* todo_flags_start */ | |
4234 TODO_ggc_collect /* todo_flags_finish */ | |
4235 } | |
4236 }; | |
4237 | |
4238 | |
4239 static unsigned int | |
4240 rest_of_handle_shorten_branches (void) | |
4241 { | |
4242 /* Shorten branches. */ | |
4243 shorten_branches (get_insns ()); | |
4244 return 0; | |
4245 } | |
4246 | |
4247 struct rtl_opt_pass pass_shorten_branches = | |
4248 { | |
4249 { | |
4250 RTL_PASS, | |
4251 "shorten", /* name */ | |
4252 NULL, /* gate */ | |
4253 rest_of_handle_shorten_branches, /* execute */ | |
4254 NULL, /* sub */ | |
4255 NULL, /* next */ | |
4256 0, /* static_pass_number */ | |
4257 TV_FINAL, /* tv_id */ | |
4258 0, /* properties_required */ | |
4259 0, /* properties_provided */ | |
4260 0, /* properties_destroyed */ | |
4261 0, /* todo_flags_start */ | |
4262 TODO_dump_func /* todo_flags_finish */ | |
4263 } | |
4264 }; | |
4265 | |
4266 | |
4267 static unsigned int | |
4268 rest_of_clean_state (void) | |
4269 { | |
4270 rtx insn, next; | |
4271 | |
4272 /* It is very important to decompose the RTL instruction chain here: | |
4273 debug information keeps pointing into CODE_LABEL insns inside the function | |
4274 body. If these remain pointing to the other insns, we end up preserving | |
4275 whole RTL chain and attached detailed debug info in memory. */ | |
4276 for (insn = get_insns (); insn; insn = next) | |
4277 { | |
4278 next = NEXT_INSN (insn); | |
4279 NEXT_INSN (insn) = NULL; | |
4280 PREV_INSN (insn) = NULL; | |
4281 } | |
4282 | |
4283 /* In case the function was not output, | |
4284 don't leave any temporary anonymous types | |
4285 queued up for sdb output. */ | |
4286 #ifdef SDB_DEBUGGING_INFO | |
4287 if (write_symbols == SDB_DEBUG) | |
4288 sdbout_types (NULL_TREE); | |
4289 #endif | |
4290 | |
4291 reload_completed = 0; | |
4292 epilogue_completed = 0; | |
4293 #ifdef STACK_REGS | |
4294 regstack_completed = 0; | |
4295 #endif | |
4296 | |
4297 /* Clear out the insn_length contents now that they are no | |
4298 longer valid. */ | |
4299 init_insn_lengths (); | |
4300 | |
4301 /* Show no temporary slots allocated. */ | |
4302 init_temp_slots (); | |
4303 | |
4304 free_bb_for_insn (); | |
4305 | |
4306 if (targetm.binds_local_p (current_function_decl)) | |
4307 { | |
4308 unsigned int pref = crtl->preferred_stack_boundary; | |
4309 if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary) | |
4310 pref = crtl->stack_alignment_needed; | |
4311 cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary | |
4312 = pref; | |
4313 } | |
4314 | |
4315 /* Make sure volatile mem refs aren't considered valid operands for | |
4316 arithmetic insns. We must call this here if this is a nested inline | |
4317 function, since the above code leaves us in the init_recog state, | |
4318 and the function context push/pop code does not save/restore volatile_ok. | |
4319 | |
4320 ??? Maybe it isn't necessary for expand_start_function to call this | |
4321 anymore if we do it here? */ | |
4322 | |
4323 init_recog_no_volatile (); | |
4324 | |
4325 /* We're done with this function. Free up memory if we can. */ | |
4326 free_after_parsing (cfun); | |
4327 free_after_compilation (cfun); | |
4328 return 0; | |
4329 } | |
4330 | |
4331 struct rtl_opt_pass pass_clean_state = | |
4332 { | |
4333 { | |
4334 RTL_PASS, | |
4335 NULL, /* name */ | |
4336 NULL, /* gate */ | |
4337 rest_of_clean_state, /* execute */ | |
4338 NULL, /* sub */ | |
4339 NULL, /* next */ | |
4340 0, /* static_pass_number */ | |
4341 TV_FINAL, /* tv_id */ | |
4342 0, /* properties_required */ | |
4343 0, /* properties_provided */ | |
4344 PROP_rtl, /* properties_destroyed */ | |
4345 0, /* todo_flags_start */ | |
4346 0 /* todo_flags_finish */ | |
4347 } | |
4348 }; | |
4349 |