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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [sched-vis.c] - Blame information for rev 20

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

Line No. Rev Author Line
1 12 jlechner
/* Instruction scheduling pass.
2
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
   Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5
   and currently maintained by, Jim Wilson (wilson@cygnus.com)
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 2, 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 COPYING.  If not, write to the Free
21
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.  */
23
 
24
#include "config.h"
25
#include "system.h"
26
#include "coretypes.h"
27
#include "tm.h"
28
#include "toplev.h"
29
#include "rtl.h"
30
#include "tm_p.h"
31
#include "regs.h"
32
#include "hard-reg-set.h"
33
#include "basic-block.h"
34
#include "insn-attr.h"
35
#include "real.h"
36
#include "sched-int.h"
37
#include "target.h"
38
 
39
#ifdef INSN_SCHEDULING
40
 
41
static char *safe_concat (char *, char *, const char *);
42
static void print_exp (char *, rtx, int);
43
static void print_value (char *, rtx, int);
44
static void print_pattern (char *, rtx, int);
45
 
46
#define BUF_LEN 2048
47
 
48
static char *
49
safe_concat (char *buf, char *cur, const char *str)
50
{
51
  char *end = buf + BUF_LEN - 2;        /* Leave room for null.  */
52
  int c;
53
 
54
  if (cur > end)
55
    {
56
      *end = '\0';
57
      return end;
58
    }
59
 
60
  while (cur < end && (c = *str++) != '\0')
61
    *cur++ = c;
62
 
63
  *cur = '\0';
64
  return cur;
65
}
66
 
67
/* This recognizes rtx, I classified as expressions.  These are always
68
   represent some action on values or results of other expression, that
69
   may be stored in objects representing values.  */
70
 
71
static void
72
print_exp (char *buf, rtx x, int verbose)
73
{
74
  char tmp[BUF_LEN];
75
  const char *st[4];
76
  char *cur = buf;
77
  const char *fun = (char *) 0;
78
  const char *sep;
79
  rtx op[4];
80
  int i;
81
 
82
  for (i = 0; i < 4; i++)
83
    {
84
      st[i] = (char *) 0;
85
      op[i] = NULL_RTX;
86
    }
87
 
88
  switch (GET_CODE (x))
89
    {
90
    case PLUS:
91
      op[0] = XEXP (x, 0);
92
      if (GET_CODE (XEXP (x, 1)) == CONST_INT
93
          && INTVAL (XEXP (x, 1)) < 0)
94
        {
95
          st[1] = "-";
96
          op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
97
        }
98
      else
99
        {
100
          st[1] = "+";
101
          op[1] = XEXP (x, 1);
102
        }
103
      break;
104
    case LO_SUM:
105
      op[0] = XEXP (x, 0);
106
      st[1] = "+low(";
107
      op[1] = XEXP (x, 1);
108
      st[2] = ")";
109
      break;
110
    case MINUS:
111
      op[0] = XEXP (x, 0);
112
      st[1] = "-";
113
      op[1] = XEXP (x, 1);
114
      break;
115
    case COMPARE:
116
      fun = "cmp";
117
      op[0] = XEXP (x, 0);
118
      op[1] = XEXP (x, 1);
119
      break;
120
    case NEG:
121
      st[0] = "-";
122
      op[0] = XEXP (x, 0);
123
      break;
124
    case MULT:
125
      op[0] = XEXP (x, 0);
126
      st[1] = "*";
127
      op[1] = XEXP (x, 1);
128
      break;
129
    case DIV:
130
      op[0] = XEXP (x, 0);
131
      st[1] = "/";
132
      op[1] = XEXP (x, 1);
133
      break;
134
    case UDIV:
135
      fun = "udiv";
136
      op[0] = XEXP (x, 0);
137
      op[1] = XEXP (x, 1);
138
      break;
139
    case MOD:
140
      op[0] = XEXP (x, 0);
141
      st[1] = "%";
142
      op[1] = XEXP (x, 1);
143
      break;
144
    case UMOD:
145
      fun = "umod";
146
      op[0] = XEXP (x, 0);
147
      op[1] = XEXP (x, 1);
148
      break;
149
    case SMIN:
150
      fun = "smin";
151
      op[0] = XEXP (x, 0);
152
      op[1] = XEXP (x, 1);
153
      break;
154
    case SMAX:
155
      fun = "smax";
156
      op[0] = XEXP (x, 0);
157
      op[1] = XEXP (x, 1);
158
      break;
159
    case UMIN:
160
      fun = "umin";
161
      op[0] = XEXP (x, 0);
162
      op[1] = XEXP (x, 1);
163
      break;
164
    case UMAX:
165
      fun = "umax";
166
      op[0] = XEXP (x, 0);
167
      op[1] = XEXP (x, 1);
168
      break;
169
    case NOT:
170
      st[0] = "!";
171
      op[0] = XEXP (x, 0);
172
      break;
173
    case AND:
174
      op[0] = XEXP (x, 0);
175
      st[1] = "&";
176
      op[1] = XEXP (x, 1);
177
      break;
178
    case IOR:
179
      op[0] = XEXP (x, 0);
180
      st[1] = "|";
181
      op[1] = XEXP (x, 1);
182
      break;
183
    case XOR:
184
      op[0] = XEXP (x, 0);
185
      st[1] = "^";
186
      op[1] = XEXP (x, 1);
187
      break;
188
    case ASHIFT:
189
      op[0] = XEXP (x, 0);
190
      st[1] = "<<";
191
      op[1] = XEXP (x, 1);
192
      break;
193
    case LSHIFTRT:
194
      op[0] = XEXP (x, 0);
195
      st[1] = " 0>>";
196
      op[1] = XEXP (x, 1);
197
      break;
198
    case ASHIFTRT:
199
      op[0] = XEXP (x, 0);
200
      st[1] = ">>";
201
      op[1] = XEXP (x, 1);
202
      break;
203
    case ROTATE:
204
      op[0] = XEXP (x, 0);
205
      st[1] = "<-<";
206
      op[1] = XEXP (x, 1);
207
      break;
208
    case ROTATERT:
209
      op[0] = XEXP (x, 0);
210
      st[1] = ">->";
211
      op[1] = XEXP (x, 1);
212
      break;
213
    case ABS:
214
      fun = "abs";
215
      op[0] = XEXP (x, 0);
216
      break;
217
    case SQRT:
218
      fun = "sqrt";
219
      op[0] = XEXP (x, 0);
220
      break;
221
    case FFS:
222
      fun = "ffs";
223
      op[0] = XEXP (x, 0);
224
      break;
225
    case EQ:
226
      op[0] = XEXP (x, 0);
227
      st[1] = "==";
228
      op[1] = XEXP (x, 1);
229
      break;
230
    case NE:
231
      op[0] = XEXP (x, 0);
232
      st[1] = "!=";
233
      op[1] = XEXP (x, 1);
234
      break;
235
    case GT:
236
      op[0] = XEXP (x, 0);
237
      st[1] = ">";
238
      op[1] = XEXP (x, 1);
239
      break;
240
    case GTU:
241
      fun = "gtu";
242
      op[0] = XEXP (x, 0);
243
      op[1] = XEXP (x, 1);
244
      break;
245
    case LT:
246
      op[0] = XEXP (x, 0);
247
      st[1] = "<";
248
      op[1] = XEXP (x, 1);
249
      break;
250
    case LTU:
251
      fun = "ltu";
252
      op[0] = XEXP (x, 0);
253
      op[1] = XEXP (x, 1);
254
      break;
255
    case GE:
256
      op[0] = XEXP (x, 0);
257
      st[1] = ">=";
258
      op[1] = XEXP (x, 1);
259
      break;
260
    case GEU:
261
      fun = "geu";
262
      op[0] = XEXP (x, 0);
263
      op[1] = XEXP (x, 1);
264
      break;
265
    case LE:
266
      op[0] = XEXP (x, 0);
267
      st[1] = "<=";
268
      op[1] = XEXP (x, 1);
269
      break;
270
    case LEU:
271
      fun = "leu";
272
      op[0] = XEXP (x, 0);
273
      op[1] = XEXP (x, 1);
274
      break;
275
    case SIGN_EXTRACT:
276
      fun = (verbose) ? "sign_extract" : "sxt";
277
      op[0] = XEXP (x, 0);
278
      op[1] = XEXP (x, 1);
279
      op[2] = XEXP (x, 2);
280
      break;
281
    case ZERO_EXTRACT:
282
      fun = (verbose) ? "zero_extract" : "zxt";
283
      op[0] = XEXP (x, 0);
284
      op[1] = XEXP (x, 1);
285
      op[2] = XEXP (x, 2);
286
      break;
287
    case SIGN_EXTEND:
288
      fun = (verbose) ? "sign_extend" : "sxn";
289
      op[0] = XEXP (x, 0);
290
      break;
291
    case ZERO_EXTEND:
292
      fun = (verbose) ? "zero_extend" : "zxn";
293
      op[0] = XEXP (x, 0);
294
      break;
295
    case FLOAT_EXTEND:
296
      fun = (verbose) ? "float_extend" : "fxn";
297
      op[0] = XEXP (x, 0);
298
      break;
299
    case TRUNCATE:
300
      fun = (verbose) ? "trunc" : "trn";
301
      op[0] = XEXP (x, 0);
302
      break;
303
    case FLOAT_TRUNCATE:
304
      fun = (verbose) ? "float_trunc" : "ftr";
305
      op[0] = XEXP (x, 0);
306
      break;
307
    case FLOAT:
308
      fun = (verbose) ? "float" : "flt";
309
      op[0] = XEXP (x, 0);
310
      break;
311
    case UNSIGNED_FLOAT:
312
      fun = (verbose) ? "uns_float" : "ufl";
313
      op[0] = XEXP (x, 0);
314
      break;
315
    case FIX:
316
      fun = "fix";
317
      op[0] = XEXP (x, 0);
318
      break;
319
    case UNSIGNED_FIX:
320
      fun = (verbose) ? "uns_fix" : "ufx";
321
      op[0] = XEXP (x, 0);
322
      break;
323
    case PRE_DEC:
324
      st[0] = "--";
325
      op[0] = XEXP (x, 0);
326
      break;
327
    case PRE_INC:
328
      st[0] = "++";
329
      op[0] = XEXP (x, 0);
330
      break;
331
    case POST_DEC:
332
      op[0] = XEXP (x, 0);
333
      st[1] = "--";
334
      break;
335
    case POST_INC:
336
      op[0] = XEXP (x, 0);
337
      st[1] = "++";
338
      break;
339
    case CALL:
340
      st[0] = "call ";
341
      op[0] = XEXP (x, 0);
342
      if (verbose)
343
        {
344
          st[1] = " argc:";
345
          op[1] = XEXP (x, 1);
346
        }
347
      break;
348
    case IF_THEN_ELSE:
349
      st[0] = "{(";
350
      op[0] = XEXP (x, 0);
351
      st[1] = ")?";
352
      op[1] = XEXP (x, 1);
353
      st[2] = ":";
354
      op[2] = XEXP (x, 2);
355
      st[3] = "}";
356
      break;
357
    case TRAP_IF:
358
      fun = "trap_if";
359
      op[0] = TRAP_CONDITION (x);
360
      break;
361
    case PREFETCH:
362
      fun = "prefetch";
363
      op[0] = XEXP (x, 0);
364
      op[1] = XEXP (x, 1);
365
      op[2] = XEXP (x, 2);
366
      break;
367
    case UNSPEC:
368
    case UNSPEC_VOLATILE:
369
      {
370
        cur = safe_concat (buf, cur, "unspec");
371
        if (GET_CODE (x) == UNSPEC_VOLATILE)
372
          cur = safe_concat (buf, cur, "/v");
373
        cur = safe_concat (buf, cur, "[");
374
        sep = "";
375
        for (i = 0; i < XVECLEN (x, 0); i++)
376
          {
377
            print_pattern (tmp, XVECEXP (x, 0, i), verbose);
378
            cur = safe_concat (buf, cur, sep);
379
            cur = safe_concat (buf, cur, tmp);
380
            sep = ",";
381
          }
382
        cur = safe_concat (buf, cur, "] ");
383
        sprintf (tmp, "%d", XINT (x, 1));
384
        cur = safe_concat (buf, cur, tmp);
385
      }
386
      break;
387
    default:
388
      /* If (verbose) debug_rtx (x);  */
389
      st[0] = GET_RTX_NAME (GET_CODE (x));
390
      break;
391
    }
392
 
393
  /* Print this as a function?  */
394
  if (fun)
395
    {
396
      cur = safe_concat (buf, cur, fun);
397
      cur = safe_concat (buf, cur, "(");
398
    }
399
 
400
  for (i = 0; i < 4; i++)
401
    {
402
      if (st[i])
403
        cur = safe_concat (buf, cur, st[i]);
404
 
405
      if (op[i])
406
        {
407
          if (fun && i != 0)
408
            cur = safe_concat (buf, cur, ",");
409
 
410
          print_value (tmp, op[i], verbose);
411
          cur = safe_concat (buf, cur, tmp);
412
        }
413
    }
414
 
415
  if (fun)
416
    cur = safe_concat (buf, cur, ")");
417
}               /* print_exp */
418
 
419
/* Prints rtxes, I customarily classified as values.  They're constants,
420
   registers, labels, symbols and memory accesses.  */
421
 
422
static void
423
print_value (char *buf, rtx x, int verbose)
424
{
425
  char t[BUF_LEN];
426
  char *cur = buf;
427
 
428
  switch (GET_CODE (x))
429
    {
430
    case CONST_INT:
431
      sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
432
      cur = safe_concat (buf, cur, t);
433
      break;
434
    case CONST_DOUBLE:
435
      if (FLOAT_MODE_P (GET_MODE (x)))
436
        real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
437
      else
438
        sprintf (t, "<0x%lx,0x%lx>", (long) CONST_DOUBLE_LOW (x), (long) CONST_DOUBLE_HIGH (x));
439
      cur = safe_concat (buf, cur, t);
440
      break;
441
    case CONST_STRING:
442
      cur = safe_concat (buf, cur, "\"");
443
      cur = safe_concat (buf, cur, XSTR (x, 0));
444
      cur = safe_concat (buf, cur, "\"");
445
      break;
446
    case SYMBOL_REF:
447
      cur = safe_concat (buf, cur, "`");
448
      cur = safe_concat (buf, cur, XSTR (x, 0));
449
      cur = safe_concat (buf, cur, "'");
450
      break;
451
    case LABEL_REF:
452
      sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
453
      cur = safe_concat (buf, cur, t);
454
      break;
455
    case CONST:
456
      print_value (t, XEXP (x, 0), verbose);
457
      cur = safe_concat (buf, cur, "const(");
458
      cur = safe_concat (buf, cur, t);
459
      cur = safe_concat (buf, cur, ")");
460
      break;
461
    case HIGH:
462
      print_value (t, XEXP (x, 0), verbose);
463
      cur = safe_concat (buf, cur, "high(");
464
      cur = safe_concat (buf, cur, t);
465
      cur = safe_concat (buf, cur, ")");
466
      break;
467
    case REG:
468
      if (REGNO (x) < FIRST_PSEUDO_REGISTER)
469
        {
470
          int c = reg_names[REGNO (x)][0];
471
          if (ISDIGIT (c))
472
            cur = safe_concat (buf, cur, "%");
473
 
474
          cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
475
        }
476
      else
477
        {
478
          sprintf (t, "r%d", REGNO (x));
479
          cur = safe_concat (buf, cur, t);
480
        }
481
      break;
482
    case SUBREG:
483
      print_value (t, SUBREG_REG (x), verbose);
484
      cur = safe_concat (buf, cur, t);
485
      sprintf (t, "#%d", SUBREG_BYTE (x));
486
      cur = safe_concat (buf, cur, t);
487
      break;
488
    case SCRATCH:
489
      cur = safe_concat (buf, cur, "scratch");
490
      break;
491
    case CC0:
492
      cur = safe_concat (buf, cur, "cc0");
493
      break;
494
    case PC:
495
      cur = safe_concat (buf, cur, "pc");
496
      break;
497
    case MEM:
498
      print_value (t, XEXP (x, 0), verbose);
499
      cur = safe_concat (buf, cur, "[");
500
      cur = safe_concat (buf, cur, t);
501
      cur = safe_concat (buf, cur, "]");
502
      break;
503
    default:
504
      print_exp (t, x, verbose);
505
      cur = safe_concat (buf, cur, t);
506
      break;
507
    }
508
}                               /* print_value */
509
 
510
/* The next step in insn detalization, its pattern recognition.  */
511
 
512
static void
513
print_pattern (char *buf, rtx x, int verbose)
514
{
515
  char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
516
 
517
  switch (GET_CODE (x))
518
    {
519
    case SET:
520
      print_value (t1, SET_DEST (x), verbose);
521
      print_value (t2, SET_SRC (x), verbose);
522
      sprintf (buf, "%s=%s", t1, t2);
523
      break;
524
    case RETURN:
525
      sprintf (buf, "return");
526
      break;
527
    case CALL:
528
      print_exp (buf, x, verbose);
529
      break;
530
    case CLOBBER:
531
      print_value (t1, XEXP (x, 0), verbose);
532
      sprintf (buf, "clobber %s", t1);
533
      break;
534
    case USE:
535
      print_value (t1, XEXP (x, 0), verbose);
536
      sprintf (buf, "use %s", t1);
537
      break;
538
    case COND_EXEC:
539
      if (GET_CODE (COND_EXEC_TEST (x)) == NE
540
          && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
541
        print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
542
      else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
543
               && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
544
        {
545
          t1[0] = '!';
546
          print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
547
        }
548
      else
549
        print_value (t1, COND_EXEC_TEST (x), verbose);
550
      print_pattern (t2, COND_EXEC_CODE (x), verbose);
551
      sprintf (buf, "(%s) %s", t1, t2);
552
      break;
553
    case PARALLEL:
554
      {
555
        int i;
556
 
557
        sprintf (t1, "{");
558
        for (i = 0; i < XVECLEN (x, 0); i++)
559
          {
560
            print_pattern (t2, XVECEXP (x, 0, i), verbose);
561
            sprintf (t3, "%s%s;", t1, t2);
562
            strcpy (t1, t3);
563
          }
564
        sprintf (buf, "%s}", t1);
565
      }
566
      break;
567
    case SEQUENCE:
568
      /* Should never see SEQUENCE codes until after reorg.  */
569
      gcc_unreachable ();
570
    case ASM_INPUT:
571
      sprintf (buf, "asm {%s}", XSTR (x, 0));
572
      break;
573
    case ADDR_VEC:
574
      break;
575
    case ADDR_DIFF_VEC:
576
      print_value (buf, XEXP (x, 0), verbose);
577
      break;
578
    case TRAP_IF:
579
      print_value (t1, TRAP_CONDITION (x), verbose);
580
      sprintf (buf, "trap_if %s", t1);
581
      break;
582
    case UNSPEC:
583
      {
584
        int i;
585
 
586
        sprintf (t1, "unspec{");
587
        for (i = 0; i < XVECLEN (x, 0); i++)
588
          {
589
            print_pattern (t2, XVECEXP (x, 0, i), verbose);
590
            sprintf (t3, "%s%s;", t1, t2);
591
            strcpy (t1, t3);
592
          }
593
        sprintf (buf, "%s}", t1);
594
      }
595
      break;
596
    case UNSPEC_VOLATILE:
597
      {
598
        int i;
599
 
600
        sprintf (t1, "unspec/v{");
601
        for (i = 0; i < XVECLEN (x, 0); i++)
602
          {
603
            print_pattern (t2, XVECEXP (x, 0, i), verbose);
604
            sprintf (t3, "%s%s;", t1, t2);
605
            strcpy (t1, t3);
606
          }
607
        sprintf (buf, "%s}", t1);
608
      }
609
      break;
610
    default:
611
      print_value (buf, x, verbose);
612
    }
613
}                               /* print_pattern */
614
 
615
/* This is the main function in rtl visualization mechanism. It
616
   accepts an rtx and tries to recognize it as an insn, then prints it
617
   properly in human readable form, resembling assembler mnemonics.
618
   For every insn it prints its UID and BB the insn belongs too.
619
   (Probably the last "option" should be extended somehow, since it
620
   depends now on sched.c inner variables ...)  */
621
 
622
void
623
print_insn (char *buf, rtx x, int verbose)
624
{
625
  char t[BUF_LEN];
626
  rtx insn = x;
627
 
628
  switch (GET_CODE (x))
629
    {
630
    case INSN:
631
      print_pattern (t, PATTERN (x), verbose);
632
      if (verbose)
633
        sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
634
                 t);
635
      else
636
        sprintf (buf, "%-4d %s", INSN_UID (x), t);
637
      break;
638
    case JUMP_INSN:
639
      print_pattern (t, PATTERN (x), verbose);
640
      if (verbose)
641
        sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
642
                 t);
643
      else
644
        sprintf (buf, "%-4d %s", INSN_UID (x), t);
645
      break;
646
    case CALL_INSN:
647
      x = PATTERN (insn);
648
      if (GET_CODE (x) == PARALLEL)
649
        {
650
          x = XVECEXP (x, 0, 0);
651
          print_pattern (t, x, verbose);
652
        }
653
      else
654
        strcpy (t, "call <...>");
655
      if (verbose)
656
        sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
657
      else
658
        sprintf (buf, "%-4d %s", INSN_UID (insn), t);
659
      break;
660
    case CODE_LABEL:
661
      sprintf (buf, "L%d:", INSN_UID (x));
662
      break;
663
    case BARRIER:
664
      sprintf (buf, "i% 4d: barrier", INSN_UID (x));
665
      break;
666
    case NOTE:
667
      if (NOTE_LINE_NUMBER (x) > 0)
668
        {
669
          expanded_location xloc;
670
          NOTE_EXPANDED_LOCATION (xloc, x);
671
          sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
672
                   xloc.file, xloc.line);
673
        }
674
      else
675
        sprintf (buf, "%4d %s", INSN_UID (x),
676
                 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
677
      break;
678
    default:
679
      if (verbose)
680
        {
681
          sprintf (buf, "Not an INSN at all\n");
682
          debug_rtx (x);
683
        }
684
      else
685
        sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
686
    }
687
}                               /* print_insn */
688
 
689
#endif

powered by: WebSVN 2.1.0

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