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