1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5 and currently maintained by, Jim Wilson (wilson@cygnus.com)
7 This file is part of GCC.
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
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
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, 59 Temple Place - Suite 330, Boston, MA
26 #include "coretypes.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "insn-attr.h"
36 #include "sched-int.h"
39 #ifdef INSN_SCHEDULING
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);
49 safe_concat (char *buf
, char *cur
, const char *str
)
51 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
60 while (cur
< end
&& (c
= *str
++) != '\0')
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. */
72 print_exp (char *buf
, rtx x
, int verbose
)
77 const char *fun
= (char *) 0;
82 for (i
= 0; i
< 4; i
++)
92 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
93 && INTVAL (XEXP (x
, 1)) < 0)
96 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
276 fun
= (verbose
) ? "sign_extract" : "sxt";
282 fun
= (verbose
) ? "zero_extract" : "zxt";
288 fun
= (verbose
) ? "sign_extend" : "sxn";
292 fun
= (verbose
) ? "zero_extend" : "zxn";
296 fun
= (verbose
) ? "float_extend" : "fxn";
300 fun
= (verbose
) ? "trunc" : "trn";
304 fun
= (verbose
) ? "float_trunc" : "ftr";
308 fun
= (verbose
) ? "float" : "flt";
312 fun
= (verbose
) ? "uns_float" : "ufl";
320 fun
= (verbose
) ? "uns_fix" : "ufx";
359 op
[0] = TRAP_CONDITION (x
);
368 case UNSPEC_VOLATILE
:
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
, "[");
375 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
377 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
378 cur
= safe_concat (buf
, cur
, sep
);
379 cur
= safe_concat (buf
, cur
, tmp
);
382 cur
= safe_concat (buf
, cur
, "] ");
383 sprintf (tmp
, "%d", XINT (x
, 1));
384 cur
= safe_concat (buf
, cur
, tmp
);
388 /* If (verbose) debug_rtx (x); */
389 st
[0] = GET_RTX_NAME (GET_CODE (x
));
393 /* Print this as a function? */
396 cur
= safe_concat (buf
, cur
, fun
);
397 cur
= safe_concat (buf
, cur
, "(");
400 for (i
= 0; i
< 4; i
++)
403 cur
= safe_concat (buf
, cur
, st
[i
]);
408 cur
= safe_concat (buf
, cur
, ",");
410 print_value (tmp
, op
[i
], verbose
);
411 cur
= safe_concat (buf
, cur
, tmp
);
416 cur
= safe_concat (buf
, cur
, ")");
419 /* Prints rtxes, I customarily classified as values. They're constants,
420 registers, labels, symbols and memory accesses. */
423 print_value (char *buf
, rtx x
, int verbose
)
428 switch (GET_CODE (x
))
431 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
432 cur
= safe_concat (buf
, cur
, t
);
435 if (FLOAT_MODE_P (GET_MODE (x
)))
436 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
438 sprintf (t
, "<0x%lx,0x%lx>", (long) XWINT (x
, 2), (long) XWINT (x
, 3));
439 cur
= safe_concat (buf
, cur
, t
);
442 cur
= safe_concat (buf
, cur
, "\"");
443 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
444 cur
= safe_concat (buf
, cur
, "\"");
447 cur
= safe_concat (buf
, cur
, "`");
448 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
449 cur
= safe_concat (buf
, cur
, "'");
452 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
453 cur
= safe_concat (buf
, cur
, t
);
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
, ")");
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
, ")");
468 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
470 int c
= reg_names
[REGNO (x
)][0];
472 cur
= safe_concat (buf
, cur
, "%");
474 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
478 sprintf (t
, "r%d", REGNO (x
));
479 cur
= safe_concat (buf
, cur
, t
);
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
);
489 cur
= safe_concat (buf
, cur
, "scratch");
492 cur
= safe_concat (buf
, cur
, "cc0");
495 cur
= safe_concat (buf
, cur
, "pc");
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
, "]");
504 print_exp (t
, x
, verbose
);
505 cur
= safe_concat (buf
, cur
, t
);
510 /* The next step in insn detalization, its pattern recognition. */
513 print_pattern (char *buf
, rtx x
, int verbose
)
515 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
517 switch (GET_CODE (x
))
520 print_value (t1
, SET_DEST (x
), verbose
);
521 print_value (t2
, SET_SRC (x
), verbose
);
522 sprintf (buf
, "%s=%s", t1
, t2
);
525 sprintf (buf
, "return");
528 print_exp (buf
, x
, verbose
);
531 print_value (t1
, XEXP (x
, 0), verbose
);
532 sprintf (buf
, "clobber %s", t1
);
535 print_value (t1
, XEXP (x
, 0), verbose
);
536 sprintf (buf
, "use %s", t1
);
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
)
546 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
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
);
558 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
560 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
561 sprintf (t3
, "%s%s;", t1
, t2
);
564 sprintf (buf
, "%s}", t1
);
568 /* Should never see SEQUENCE codes until after reorg. */
572 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
577 print_value (buf
, XEXP (x
, 0), verbose
);
580 print_value (t1
, TRAP_CONDITION (x
), verbose
);
581 sprintf (buf
, "trap_if %s", t1
);
587 sprintf (t1
, "unspec{");
588 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
590 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
591 sprintf (t3
, "%s%s;", t1
, t2
);
594 sprintf (buf
, "%s}", t1
);
597 case UNSPEC_VOLATILE
:
601 sprintf (t1
, "unspec/v{");
602 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
604 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
605 sprintf (t3
, "%s%s;", t1
, t2
);
608 sprintf (buf
, "%s}", t1
);
612 print_value (buf
, x
, verbose
);
614 } /* print_pattern */
616 /* This is the main function in rtl visualization mechanism. It
617 accepts an rtx and tries to recognize it as an insn, then prints it
618 properly in human readable form, resembling assembler mnemonics.
619 For every insn it prints its UID and BB the insn belongs too.
620 (Probably the last "option" should be extended somehow, since it
621 depends now on sched.c inner variables ...) */
624 print_insn (char *buf
, rtx x
, int verbose
)
629 switch (GET_CODE (x
))
632 print_pattern (t
, PATTERN (x
), verbose
);
634 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
637 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
640 print_pattern (t
, PATTERN (x
), verbose
);
642 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
645 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
649 if (GET_CODE (x
) == PARALLEL
)
651 x
= XVECEXP (x
, 0, 0);
652 print_pattern (t
, x
, verbose
);
655 strcpy (t
, "call <...>");
657 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
659 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
662 sprintf (buf
, "L%d:", INSN_UID (x
));
665 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
668 if (NOTE_LINE_NUMBER (x
) > 0)
670 expanded_location xloc
;
671 NOTE_EXPANDED_LOCATION (xloc
, x
);
672 sprintf (buf
, "%4d note \"%s\" %d", INSN_UID (x
),
673 xloc
.file
, xloc
.line
);
676 sprintf (buf
, "%4d %s", INSN_UID (x
),
677 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
682 sprintf (buf
, "Not an INSN at all\n");
686 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));