1 /* 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)
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, 51 Franklin Street, Fifth Floor, 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) CONST_DOUBLE_LOW (x
), (long) CONST_DOUBLE_HIGH (x
));
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. */
571 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
576 print_value (buf
, XEXP (x
, 0), verbose
);
579 print_value (t1
, TRAP_CONDITION (x
), verbose
);
580 sprintf (buf
, "trap_if %s", t1
);
586 sprintf (t1
, "unspec{");
587 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
589 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
590 sprintf (t3
, "%s%s;", t1
, t2
);
593 sprintf (buf
, "%s}", t1
);
596 case UNSPEC_VOLATILE
:
600 sprintf (t1
, "unspec/v{");
601 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
603 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
604 sprintf (t3
, "%s%s;", t1
, t2
);
607 sprintf (buf
, "%s}", t1
);
611 print_value (buf
, x
, verbose
);
613 } /* print_pattern */
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 ...) */
623 print_insn (char *buf
, rtx x
, int verbose
)
628 switch (GET_CODE (x
))
631 print_pattern (t
, PATTERN (x
), verbose
);
633 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
636 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
639 print_pattern (t
, PATTERN (x
), verbose
);
641 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
644 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
648 if (GET_CODE (x
) == PARALLEL
)
650 x
= XVECEXP (x
, 0, 0);
651 print_pattern (t
, x
, verbose
);
654 strcpy (t
, "call <...>");
656 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
658 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
661 sprintf (buf
, "L%d:", INSN_UID (x
));
664 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
667 if (NOTE_LINE_NUMBER (x
) > 0)
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
);
675 sprintf (buf
, "%4d %s", INSN_UID (x
),
676 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
681 sprintf (buf
, "Not an INSN at all\n");
685 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));