OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [final.c] - Blame information for rev 729

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

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

powered by: WebSVN 2.1.0

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