OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [final.c] - Blame information for rev 165

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.