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