190075Sobrien/* Instruction scheduling pass. 290075Sobrien Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3169689Skan 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 490075Sobrien Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by, 590075Sobrien and currently maintained by, Jim Wilson (wilson@cygnus.com) 690075Sobrien 790075SobrienThis file is part of GCC. 890075Sobrien 990075SobrienGCC is free software; you can redistribute it and/or modify it under 1090075Sobrienthe terms of the GNU General Public License as published by the Free 1190075SobrienSoftware Foundation; either version 2, or (at your option) any later 1290075Sobrienversion. 1390075Sobrien 1490075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1590075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1690075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1790075Sobrienfor more details. 1890075Sobrien 1990075SobrienYou should have received a copy of the GNU General Public License 2090075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 21169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 22169689Skan02110-1301, USA. */ 2390075Sobrien 2490075Sobrien#include "config.h" 2590075Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2890075Sobrien#include "rtl.h" 29169689Skan#include "obstack.h" 3090075Sobrien#include "hard-reg-set.h" 3190075Sobrien#include "basic-block.h" 32117395Skan#include "real.h" 3390075Sobrien#include "sched-int.h" 34169689Skan#include "tree-pass.h" 3590075Sobrien 36132718Skanstatic char *safe_concat (char *, char *, const char *); 37132718Skanstatic void print_exp (char *, rtx, int); 38132718Skanstatic void print_value (char *, rtx, int); 39132718Skanstatic void print_pattern (char *, rtx, int); 4090075Sobrien 4190075Sobrien#define BUF_LEN 2048 4290075Sobrien 4390075Sobrienstatic char * 44132718Skansafe_concat (char *buf, char *cur, const char *str) 4590075Sobrien{ 4690075Sobrien char *end = buf + BUF_LEN - 2; /* Leave room for null. */ 4790075Sobrien int c; 4890075Sobrien 4990075Sobrien if (cur > end) 5090075Sobrien { 5190075Sobrien *end = '\0'; 5290075Sobrien return end; 5390075Sobrien } 5490075Sobrien 5590075Sobrien while (cur < end && (c = *str++) != '\0') 5690075Sobrien *cur++ = c; 5790075Sobrien 5890075Sobrien *cur = '\0'; 5990075Sobrien return cur; 6090075Sobrien} 6190075Sobrien 6290075Sobrien/* This recognizes rtx, I classified as expressions. These are always 6390075Sobrien represent some action on values or results of other expression, that 6490075Sobrien may be stored in objects representing values. */ 6590075Sobrien 6690075Sobrienstatic void 67132718Skanprint_exp (char *buf, rtx x, int verbose) 6890075Sobrien{ 6990075Sobrien char tmp[BUF_LEN]; 7090075Sobrien const char *st[4]; 7190075Sobrien char *cur = buf; 7290075Sobrien const char *fun = (char *) 0; 7390075Sobrien const char *sep; 7490075Sobrien rtx op[4]; 7590075Sobrien int i; 7690075Sobrien 7790075Sobrien for (i = 0; i < 4; i++) 7890075Sobrien { 7990075Sobrien st[i] = (char *) 0; 8090075Sobrien op[i] = NULL_RTX; 8190075Sobrien } 8290075Sobrien 8390075Sobrien switch (GET_CODE (x)) 8490075Sobrien { 8590075Sobrien case PLUS: 8690075Sobrien op[0] = XEXP (x, 0); 8790075Sobrien if (GET_CODE (XEXP (x, 1)) == CONST_INT 8890075Sobrien && INTVAL (XEXP (x, 1)) < 0) 8990075Sobrien { 9090075Sobrien st[1] = "-"; 9190075Sobrien op[1] = GEN_INT (-INTVAL (XEXP (x, 1))); 9290075Sobrien } 9390075Sobrien else 9490075Sobrien { 9590075Sobrien st[1] = "+"; 9690075Sobrien op[1] = XEXP (x, 1); 9790075Sobrien } 9890075Sobrien break; 9990075Sobrien case LO_SUM: 10090075Sobrien op[0] = XEXP (x, 0); 10190075Sobrien st[1] = "+low("; 10290075Sobrien op[1] = XEXP (x, 1); 10390075Sobrien st[2] = ")"; 10490075Sobrien break; 10590075Sobrien case MINUS: 10690075Sobrien op[0] = XEXP (x, 0); 10790075Sobrien st[1] = "-"; 10890075Sobrien op[1] = XEXP (x, 1); 10990075Sobrien break; 11090075Sobrien case COMPARE: 11190075Sobrien fun = "cmp"; 11290075Sobrien op[0] = XEXP (x, 0); 11390075Sobrien op[1] = XEXP (x, 1); 11490075Sobrien break; 11590075Sobrien case NEG: 11690075Sobrien st[0] = "-"; 11790075Sobrien op[0] = XEXP (x, 0); 11890075Sobrien break; 11990075Sobrien case MULT: 12090075Sobrien op[0] = XEXP (x, 0); 12190075Sobrien st[1] = "*"; 12290075Sobrien op[1] = XEXP (x, 1); 12390075Sobrien break; 12490075Sobrien case DIV: 12590075Sobrien op[0] = XEXP (x, 0); 12690075Sobrien st[1] = "/"; 12790075Sobrien op[1] = XEXP (x, 1); 12890075Sobrien break; 12990075Sobrien case UDIV: 13090075Sobrien fun = "udiv"; 13190075Sobrien op[0] = XEXP (x, 0); 13290075Sobrien op[1] = XEXP (x, 1); 13390075Sobrien break; 13490075Sobrien case MOD: 13590075Sobrien op[0] = XEXP (x, 0); 13690075Sobrien st[1] = "%"; 13790075Sobrien op[1] = XEXP (x, 1); 13890075Sobrien break; 13990075Sobrien case UMOD: 14090075Sobrien fun = "umod"; 14190075Sobrien op[0] = XEXP (x, 0); 14290075Sobrien op[1] = XEXP (x, 1); 14390075Sobrien break; 14490075Sobrien case SMIN: 14590075Sobrien fun = "smin"; 14690075Sobrien op[0] = XEXP (x, 0); 14790075Sobrien op[1] = XEXP (x, 1); 14890075Sobrien break; 14990075Sobrien case SMAX: 15090075Sobrien fun = "smax"; 15190075Sobrien op[0] = XEXP (x, 0); 15290075Sobrien op[1] = XEXP (x, 1); 15390075Sobrien break; 15490075Sobrien case UMIN: 15590075Sobrien fun = "umin"; 15690075Sobrien op[0] = XEXP (x, 0); 15790075Sobrien op[1] = XEXP (x, 1); 15890075Sobrien break; 15990075Sobrien case UMAX: 16090075Sobrien fun = "umax"; 16190075Sobrien op[0] = XEXP (x, 0); 16290075Sobrien op[1] = XEXP (x, 1); 16390075Sobrien break; 16490075Sobrien case NOT: 16590075Sobrien st[0] = "!"; 16690075Sobrien op[0] = XEXP (x, 0); 16790075Sobrien break; 16890075Sobrien case AND: 16990075Sobrien op[0] = XEXP (x, 0); 17090075Sobrien st[1] = "&"; 17190075Sobrien op[1] = XEXP (x, 1); 17290075Sobrien break; 17390075Sobrien case IOR: 17490075Sobrien op[0] = XEXP (x, 0); 17590075Sobrien st[1] = "|"; 17690075Sobrien op[1] = XEXP (x, 1); 17790075Sobrien break; 17890075Sobrien case XOR: 17990075Sobrien op[0] = XEXP (x, 0); 18090075Sobrien st[1] = "^"; 18190075Sobrien op[1] = XEXP (x, 1); 18290075Sobrien break; 18390075Sobrien case ASHIFT: 18490075Sobrien op[0] = XEXP (x, 0); 18590075Sobrien st[1] = "<<"; 18690075Sobrien op[1] = XEXP (x, 1); 18790075Sobrien break; 18890075Sobrien case LSHIFTRT: 18990075Sobrien op[0] = XEXP (x, 0); 19090075Sobrien st[1] = " 0>>"; 19190075Sobrien op[1] = XEXP (x, 1); 19290075Sobrien break; 19390075Sobrien case ASHIFTRT: 19490075Sobrien op[0] = XEXP (x, 0); 19590075Sobrien st[1] = ">>"; 19690075Sobrien op[1] = XEXP (x, 1); 19790075Sobrien break; 19890075Sobrien case ROTATE: 19990075Sobrien op[0] = XEXP (x, 0); 20090075Sobrien st[1] = "<-<"; 20190075Sobrien op[1] = XEXP (x, 1); 20290075Sobrien break; 20390075Sobrien case ROTATERT: 20490075Sobrien op[0] = XEXP (x, 0); 20590075Sobrien st[1] = ">->"; 20690075Sobrien op[1] = XEXP (x, 1); 20790075Sobrien break; 20890075Sobrien case ABS: 20990075Sobrien fun = "abs"; 21090075Sobrien op[0] = XEXP (x, 0); 21190075Sobrien break; 21290075Sobrien case SQRT: 21390075Sobrien fun = "sqrt"; 21490075Sobrien op[0] = XEXP (x, 0); 21590075Sobrien break; 21690075Sobrien case FFS: 21790075Sobrien fun = "ffs"; 21890075Sobrien op[0] = XEXP (x, 0); 21990075Sobrien break; 22090075Sobrien case EQ: 22190075Sobrien op[0] = XEXP (x, 0); 22290075Sobrien st[1] = "=="; 22390075Sobrien op[1] = XEXP (x, 1); 22490075Sobrien break; 22590075Sobrien case NE: 22690075Sobrien op[0] = XEXP (x, 0); 22790075Sobrien st[1] = "!="; 22890075Sobrien op[1] = XEXP (x, 1); 22990075Sobrien break; 23090075Sobrien case GT: 23190075Sobrien op[0] = XEXP (x, 0); 23290075Sobrien st[1] = ">"; 23390075Sobrien op[1] = XEXP (x, 1); 23490075Sobrien break; 23590075Sobrien case GTU: 23690075Sobrien fun = "gtu"; 23790075Sobrien op[0] = XEXP (x, 0); 23890075Sobrien op[1] = XEXP (x, 1); 23990075Sobrien break; 24090075Sobrien case LT: 24190075Sobrien op[0] = XEXP (x, 0); 24290075Sobrien st[1] = "<"; 24390075Sobrien op[1] = XEXP (x, 1); 24490075Sobrien break; 24590075Sobrien case LTU: 24690075Sobrien fun = "ltu"; 24790075Sobrien op[0] = XEXP (x, 0); 24890075Sobrien op[1] = XEXP (x, 1); 24990075Sobrien break; 25090075Sobrien case GE: 25190075Sobrien op[0] = XEXP (x, 0); 25290075Sobrien st[1] = ">="; 25390075Sobrien op[1] = XEXP (x, 1); 25490075Sobrien break; 25590075Sobrien case GEU: 25690075Sobrien fun = "geu"; 25790075Sobrien op[0] = XEXP (x, 0); 25890075Sobrien op[1] = XEXP (x, 1); 25990075Sobrien break; 26090075Sobrien case LE: 26190075Sobrien op[0] = XEXP (x, 0); 26290075Sobrien st[1] = "<="; 26390075Sobrien op[1] = XEXP (x, 1); 26490075Sobrien break; 26590075Sobrien case LEU: 26690075Sobrien fun = "leu"; 26790075Sobrien op[0] = XEXP (x, 0); 26890075Sobrien op[1] = XEXP (x, 1); 26990075Sobrien break; 27090075Sobrien case SIGN_EXTRACT: 27190075Sobrien fun = (verbose) ? "sign_extract" : "sxt"; 27290075Sobrien op[0] = XEXP (x, 0); 27390075Sobrien op[1] = XEXP (x, 1); 27490075Sobrien op[2] = XEXP (x, 2); 27590075Sobrien break; 27690075Sobrien case ZERO_EXTRACT: 27790075Sobrien fun = (verbose) ? "zero_extract" : "zxt"; 27890075Sobrien op[0] = XEXP (x, 0); 27990075Sobrien op[1] = XEXP (x, 1); 28090075Sobrien op[2] = XEXP (x, 2); 28190075Sobrien break; 28290075Sobrien case SIGN_EXTEND: 28390075Sobrien fun = (verbose) ? "sign_extend" : "sxn"; 28490075Sobrien op[0] = XEXP (x, 0); 28590075Sobrien break; 28690075Sobrien case ZERO_EXTEND: 28790075Sobrien fun = (verbose) ? "zero_extend" : "zxn"; 28890075Sobrien op[0] = XEXP (x, 0); 28990075Sobrien break; 29090075Sobrien case FLOAT_EXTEND: 29190075Sobrien fun = (verbose) ? "float_extend" : "fxn"; 29290075Sobrien op[0] = XEXP (x, 0); 29390075Sobrien break; 29490075Sobrien case TRUNCATE: 29590075Sobrien fun = (verbose) ? "trunc" : "trn"; 29690075Sobrien op[0] = XEXP (x, 0); 29790075Sobrien break; 29890075Sobrien case FLOAT_TRUNCATE: 29990075Sobrien fun = (verbose) ? "float_trunc" : "ftr"; 30090075Sobrien op[0] = XEXP (x, 0); 30190075Sobrien break; 30290075Sobrien case FLOAT: 30390075Sobrien fun = (verbose) ? "float" : "flt"; 30490075Sobrien op[0] = XEXP (x, 0); 30590075Sobrien break; 30690075Sobrien case UNSIGNED_FLOAT: 30790075Sobrien fun = (verbose) ? "uns_float" : "ufl"; 30890075Sobrien op[0] = XEXP (x, 0); 30990075Sobrien break; 31090075Sobrien case FIX: 31190075Sobrien fun = "fix"; 31290075Sobrien op[0] = XEXP (x, 0); 31390075Sobrien break; 31490075Sobrien case UNSIGNED_FIX: 31590075Sobrien fun = (verbose) ? "uns_fix" : "ufx"; 31690075Sobrien op[0] = XEXP (x, 0); 31790075Sobrien break; 31890075Sobrien case PRE_DEC: 31990075Sobrien st[0] = "--"; 32090075Sobrien op[0] = XEXP (x, 0); 32190075Sobrien break; 32290075Sobrien case PRE_INC: 32390075Sobrien st[0] = "++"; 32490075Sobrien op[0] = XEXP (x, 0); 32590075Sobrien break; 32690075Sobrien case POST_DEC: 32790075Sobrien op[0] = XEXP (x, 0); 32890075Sobrien st[1] = "--"; 32990075Sobrien break; 33090075Sobrien case POST_INC: 33190075Sobrien op[0] = XEXP (x, 0); 33290075Sobrien st[1] = "++"; 33390075Sobrien break; 33490075Sobrien case CALL: 33590075Sobrien st[0] = "call "; 33690075Sobrien op[0] = XEXP (x, 0); 33790075Sobrien if (verbose) 33890075Sobrien { 33990075Sobrien st[1] = " argc:"; 34090075Sobrien op[1] = XEXP (x, 1); 34190075Sobrien } 34290075Sobrien break; 34390075Sobrien case IF_THEN_ELSE: 34490075Sobrien st[0] = "{("; 34590075Sobrien op[0] = XEXP (x, 0); 34690075Sobrien st[1] = ")?"; 34790075Sobrien op[1] = XEXP (x, 1); 34890075Sobrien st[2] = ":"; 34990075Sobrien op[2] = XEXP (x, 2); 35090075Sobrien st[3] = "}"; 35190075Sobrien break; 35290075Sobrien case TRAP_IF: 35390075Sobrien fun = "trap_if"; 35490075Sobrien op[0] = TRAP_CONDITION (x); 35590075Sobrien break; 35690075Sobrien case PREFETCH: 35790075Sobrien fun = "prefetch"; 35890075Sobrien op[0] = XEXP (x, 0); 35990075Sobrien op[1] = XEXP (x, 1); 36090075Sobrien op[2] = XEXP (x, 2); 36190075Sobrien break; 36290075Sobrien case UNSPEC: 36390075Sobrien case UNSPEC_VOLATILE: 36490075Sobrien { 36590075Sobrien cur = safe_concat (buf, cur, "unspec"); 36690075Sobrien if (GET_CODE (x) == UNSPEC_VOLATILE) 36790075Sobrien cur = safe_concat (buf, cur, "/v"); 36890075Sobrien cur = safe_concat (buf, cur, "["); 36990075Sobrien sep = ""; 37090075Sobrien for (i = 0; i < XVECLEN (x, 0); i++) 37190075Sobrien { 37290075Sobrien print_pattern (tmp, XVECEXP (x, 0, i), verbose); 37390075Sobrien cur = safe_concat (buf, cur, sep); 37490075Sobrien cur = safe_concat (buf, cur, tmp); 37590075Sobrien sep = ","; 37690075Sobrien } 37790075Sobrien cur = safe_concat (buf, cur, "] "); 37890075Sobrien sprintf (tmp, "%d", XINT (x, 1)); 37990075Sobrien cur = safe_concat (buf, cur, tmp); 38090075Sobrien } 38190075Sobrien break; 38290075Sobrien default: 38390075Sobrien /* If (verbose) debug_rtx (x); */ 38490075Sobrien st[0] = GET_RTX_NAME (GET_CODE (x)); 38590075Sobrien break; 38690075Sobrien } 38790075Sobrien 38890075Sobrien /* Print this as a function? */ 38990075Sobrien if (fun) 39090075Sobrien { 39190075Sobrien cur = safe_concat (buf, cur, fun); 39290075Sobrien cur = safe_concat (buf, cur, "("); 39390075Sobrien } 39490075Sobrien 39590075Sobrien for (i = 0; i < 4; i++) 39690075Sobrien { 39790075Sobrien if (st[i]) 39890075Sobrien cur = safe_concat (buf, cur, st[i]); 39990075Sobrien 40090075Sobrien if (op[i]) 40190075Sobrien { 40290075Sobrien if (fun && i != 0) 40390075Sobrien cur = safe_concat (buf, cur, ","); 40490075Sobrien 40590075Sobrien print_value (tmp, op[i], verbose); 40690075Sobrien cur = safe_concat (buf, cur, tmp); 40790075Sobrien } 40890075Sobrien } 40990075Sobrien 41090075Sobrien if (fun) 41190075Sobrien cur = safe_concat (buf, cur, ")"); 41290075Sobrien} /* print_exp */ 41390075Sobrien 414132718Skan/* Prints rtxes, I customarily classified as values. They're constants, 41590075Sobrien registers, labels, symbols and memory accesses. */ 41690075Sobrien 41790075Sobrienstatic void 418132718Skanprint_value (char *buf, rtx x, int verbose) 41990075Sobrien{ 42090075Sobrien char t[BUF_LEN]; 42190075Sobrien char *cur = buf; 42290075Sobrien 42390075Sobrien switch (GET_CODE (x)) 42490075Sobrien { 42590075Sobrien case CONST_INT: 42690075Sobrien sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x)); 42790075Sobrien cur = safe_concat (buf, cur, t); 42890075Sobrien break; 42990075Sobrien case CONST_DOUBLE: 430117395Skan if (FLOAT_MODE_P (GET_MODE (x))) 431117395Skan real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1); 432117395Skan else 433259947Spfg sprintf (t, 434259947Spfg "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">", 435259947Spfg (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x), 436259947Spfg (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x)); 43790075Sobrien cur = safe_concat (buf, cur, t); 43890075Sobrien break; 43990075Sobrien case CONST_STRING: 44090075Sobrien cur = safe_concat (buf, cur, "\""); 44190075Sobrien cur = safe_concat (buf, cur, XSTR (x, 0)); 44290075Sobrien cur = safe_concat (buf, cur, "\""); 44390075Sobrien break; 44490075Sobrien case SYMBOL_REF: 44590075Sobrien cur = safe_concat (buf, cur, "`"); 44690075Sobrien cur = safe_concat (buf, cur, XSTR (x, 0)); 44790075Sobrien cur = safe_concat (buf, cur, "'"); 44890075Sobrien break; 44990075Sobrien case LABEL_REF: 45090075Sobrien sprintf (t, "L%d", INSN_UID (XEXP (x, 0))); 45190075Sobrien cur = safe_concat (buf, cur, t); 45290075Sobrien break; 45390075Sobrien case CONST: 45490075Sobrien print_value (t, XEXP (x, 0), verbose); 45590075Sobrien cur = safe_concat (buf, cur, "const("); 45690075Sobrien cur = safe_concat (buf, cur, t); 45790075Sobrien cur = safe_concat (buf, cur, ")"); 45890075Sobrien break; 45990075Sobrien case HIGH: 46090075Sobrien print_value (t, XEXP (x, 0), verbose); 46190075Sobrien cur = safe_concat (buf, cur, "high("); 46290075Sobrien cur = safe_concat (buf, cur, t); 46390075Sobrien cur = safe_concat (buf, cur, ")"); 46490075Sobrien break; 46590075Sobrien case REG: 46690075Sobrien if (REGNO (x) < FIRST_PSEUDO_REGISTER) 46790075Sobrien { 46890075Sobrien int c = reg_names[REGNO (x)][0]; 46990075Sobrien if (ISDIGIT (c)) 47090075Sobrien cur = safe_concat (buf, cur, "%"); 47190075Sobrien 47290075Sobrien cur = safe_concat (buf, cur, reg_names[REGNO (x)]); 47390075Sobrien } 47490075Sobrien else 47590075Sobrien { 47690075Sobrien sprintf (t, "r%d", REGNO (x)); 47790075Sobrien cur = safe_concat (buf, cur, t); 47890075Sobrien } 479169689Skan if (verbose 480169689Skan#ifdef INSN_SCHEDULING 481169689Skan && !current_sched_info 482169689Skan#endif 483169689Skan ) 484169689Skan { 485169689Skan sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x))); 486169689Skan cur = safe_concat (buf, cur, t); 487169689Skan } 48890075Sobrien break; 48990075Sobrien case SUBREG: 49090075Sobrien print_value (t, SUBREG_REG (x), verbose); 49190075Sobrien cur = safe_concat (buf, cur, t); 49290075Sobrien sprintf (t, "#%d", SUBREG_BYTE (x)); 49390075Sobrien cur = safe_concat (buf, cur, t); 49490075Sobrien break; 49590075Sobrien case SCRATCH: 49690075Sobrien cur = safe_concat (buf, cur, "scratch"); 49790075Sobrien break; 49890075Sobrien case CC0: 49990075Sobrien cur = safe_concat (buf, cur, "cc0"); 50090075Sobrien break; 50190075Sobrien case PC: 50290075Sobrien cur = safe_concat (buf, cur, "pc"); 50390075Sobrien break; 50490075Sobrien case MEM: 50590075Sobrien print_value (t, XEXP (x, 0), verbose); 50690075Sobrien cur = safe_concat (buf, cur, "["); 50790075Sobrien cur = safe_concat (buf, cur, t); 50890075Sobrien cur = safe_concat (buf, cur, "]"); 50990075Sobrien break; 51090075Sobrien default: 51190075Sobrien print_exp (t, x, verbose); 51290075Sobrien cur = safe_concat (buf, cur, t); 51390075Sobrien break; 51490075Sobrien } 51590075Sobrien} /* print_value */ 51690075Sobrien 51790075Sobrien/* The next step in insn detalization, its pattern recognition. */ 51890075Sobrien 51990075Sobrienstatic void 520132718Skanprint_pattern (char *buf, rtx x, int verbose) 52190075Sobrien{ 52290075Sobrien char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN]; 52390075Sobrien 52490075Sobrien switch (GET_CODE (x)) 52590075Sobrien { 52690075Sobrien case SET: 52790075Sobrien print_value (t1, SET_DEST (x), verbose); 52890075Sobrien print_value (t2, SET_SRC (x), verbose); 52990075Sobrien sprintf (buf, "%s=%s", t1, t2); 53090075Sobrien break; 53190075Sobrien case RETURN: 53290075Sobrien sprintf (buf, "return"); 53390075Sobrien break; 53490075Sobrien case CALL: 53590075Sobrien print_exp (buf, x, verbose); 53690075Sobrien break; 53790075Sobrien case CLOBBER: 53890075Sobrien print_value (t1, XEXP (x, 0), verbose); 53990075Sobrien sprintf (buf, "clobber %s", t1); 54090075Sobrien break; 54190075Sobrien case USE: 54290075Sobrien print_value (t1, XEXP (x, 0), verbose); 54390075Sobrien sprintf (buf, "use %s", t1); 54490075Sobrien break; 54590075Sobrien case COND_EXEC: 54690075Sobrien if (GET_CODE (COND_EXEC_TEST (x)) == NE 54790075Sobrien && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) 54890075Sobrien print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose); 54990075Sobrien else if (GET_CODE (COND_EXEC_TEST (x)) == EQ 550117395Skan && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) 551117395Skan { 55290075Sobrien t1[0] = '!'; 55390075Sobrien print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose); 55490075Sobrien } 55590075Sobrien else 556117395Skan print_value (t1, COND_EXEC_TEST (x), verbose); 55790075Sobrien print_pattern (t2, COND_EXEC_CODE (x), verbose); 55890075Sobrien sprintf (buf, "(%s) %s", t1, t2); 55990075Sobrien break; 56090075Sobrien case PARALLEL: 56190075Sobrien { 56290075Sobrien int i; 56390075Sobrien 56490075Sobrien sprintf (t1, "{"); 56590075Sobrien for (i = 0; i < XVECLEN (x, 0); i++) 56690075Sobrien { 56790075Sobrien print_pattern (t2, XVECEXP (x, 0, i), verbose); 56890075Sobrien sprintf (t3, "%s%s;", t1, t2); 56990075Sobrien strcpy (t1, t3); 57090075Sobrien } 57190075Sobrien sprintf (buf, "%s}", t1); 57290075Sobrien } 57390075Sobrien break; 57490075Sobrien case SEQUENCE: 575117395Skan /* Should never see SEQUENCE codes until after reorg. */ 576169689Skan gcc_unreachable (); 57790075Sobrien case ASM_INPUT: 57890075Sobrien sprintf (buf, "asm {%s}", XSTR (x, 0)); 57990075Sobrien break; 58090075Sobrien case ADDR_VEC: 58190075Sobrien break; 58290075Sobrien case ADDR_DIFF_VEC: 58390075Sobrien print_value (buf, XEXP (x, 0), verbose); 58490075Sobrien break; 58590075Sobrien case TRAP_IF: 58690075Sobrien print_value (t1, TRAP_CONDITION (x), verbose); 58790075Sobrien sprintf (buf, "trap_if %s", t1); 58890075Sobrien break; 58990075Sobrien case UNSPEC: 59090075Sobrien { 59190075Sobrien int i; 59290075Sobrien 59390075Sobrien sprintf (t1, "unspec{"); 59490075Sobrien for (i = 0; i < XVECLEN (x, 0); i++) 59590075Sobrien { 59690075Sobrien print_pattern (t2, XVECEXP (x, 0, i), verbose); 59790075Sobrien sprintf (t3, "%s%s;", t1, t2); 59890075Sobrien strcpy (t1, t3); 59990075Sobrien } 60090075Sobrien sprintf (buf, "%s}", t1); 60190075Sobrien } 60290075Sobrien break; 60390075Sobrien case UNSPEC_VOLATILE: 60490075Sobrien { 60590075Sobrien int i; 60690075Sobrien 60790075Sobrien sprintf (t1, "unspec/v{"); 60890075Sobrien for (i = 0; i < XVECLEN (x, 0); i++) 60990075Sobrien { 61090075Sobrien print_pattern (t2, XVECEXP (x, 0, i), verbose); 61190075Sobrien sprintf (t3, "%s%s;", t1, t2); 61290075Sobrien strcpy (t1, t3); 61390075Sobrien } 61490075Sobrien sprintf (buf, "%s}", t1); 61590075Sobrien } 61690075Sobrien break; 61790075Sobrien default: 61890075Sobrien print_value (buf, x, verbose); 61990075Sobrien } 62090075Sobrien} /* print_pattern */ 62190075Sobrien 62290075Sobrien/* This is the main function in rtl visualization mechanism. It 62390075Sobrien accepts an rtx and tries to recognize it as an insn, then prints it 62490075Sobrien properly in human readable form, resembling assembler mnemonics. 62590075Sobrien For every insn it prints its UID and BB the insn belongs too. 62690075Sobrien (Probably the last "option" should be extended somehow, since it 62790075Sobrien depends now on sched.c inner variables ...) */ 62890075Sobrien 629117395Skanvoid 630132718Skanprint_insn (char *buf, rtx x, int verbose) 63190075Sobrien{ 63290075Sobrien char t[BUF_LEN]; 63390075Sobrien rtx insn = x; 63490075Sobrien 63590075Sobrien switch (GET_CODE (x)) 63690075Sobrien { 63790075Sobrien case INSN: 63890075Sobrien print_pattern (t, PATTERN (x), verbose); 639169689Skan#ifdef INSN_SCHEDULING 640169689Skan if (verbose && current_sched_info) 64190075Sobrien sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), 64290075Sobrien t); 64390075Sobrien else 644169689Skan#endif 645169689Skan sprintf (buf, " %4d %s", INSN_UID (x), t); 64690075Sobrien break; 64790075Sobrien case JUMP_INSN: 64890075Sobrien print_pattern (t, PATTERN (x), verbose); 649169689Skan#ifdef INSN_SCHEDULING 650169689Skan if (verbose && current_sched_info) 65190075Sobrien sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1), 65290075Sobrien t); 65390075Sobrien else 654169689Skan#endif 655169689Skan sprintf (buf, " %4d %s", INSN_UID (x), t); 65690075Sobrien break; 65790075Sobrien case CALL_INSN: 65890075Sobrien x = PATTERN (insn); 65990075Sobrien if (GET_CODE (x) == PARALLEL) 66090075Sobrien { 66190075Sobrien x = XVECEXP (x, 0, 0); 66290075Sobrien print_pattern (t, x, verbose); 66390075Sobrien } 66490075Sobrien else 66590075Sobrien strcpy (t, "call <...>"); 666169689Skan#ifdef INSN_SCHEDULING 667169689Skan if (verbose && current_sched_info) 66890075Sobrien sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t); 66990075Sobrien else 670169689Skan#endif 671169689Skan sprintf (buf, " %4d %s", INSN_UID (insn), t); 67290075Sobrien break; 67390075Sobrien case CODE_LABEL: 67490075Sobrien sprintf (buf, "L%d:", INSN_UID (x)); 67590075Sobrien break; 67690075Sobrien case BARRIER: 677169689Skan sprintf (buf, "i%4d: barrier", INSN_UID (x)); 67890075Sobrien break; 67990075Sobrien case NOTE: 68090075Sobrien if (NOTE_LINE_NUMBER (x) > 0) 681169689Skan { 682169689Skan expanded_location xloc; 683169689Skan NOTE_EXPANDED_LOCATION (xloc, x); 684169689Skan sprintf (buf, " %4d note \"%s\" %d", INSN_UID (x), 685169689Skan xloc.file, xloc.line); 686169689Skan } 68790075Sobrien else 688169689Skan sprintf (buf, " %4d %s", INSN_UID (x), 68990075Sobrien GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x))); 69090075Sobrien break; 69190075Sobrien default: 692169689Skan sprintf (buf, "i%4d <What %s?>", INSN_UID (x), 693169689Skan GET_RTX_NAME (GET_CODE (x))); 69490075Sobrien } 69590075Sobrien} /* print_insn */ 69690075Sobrien 69790075Sobrien 698169689Skan/* Emit a slim dump of X (an insn) to the file F, including any register 699169689Skan note attached to the instruction. */ 70090075Sobrienvoid 701169689Skandump_insn_slim (FILE *f, rtx x) 70290075Sobrien{ 703169689Skan char t[BUF_LEN + 32]; 704169689Skan rtx note; 70590075Sobrien 706169689Skan print_insn (t, x, 1); 707169689Skan fputs (t, f); 708169689Skan putc ('\n', f); 709169689Skan if (INSN_P (x) && REG_NOTES (x)) 710169689Skan for (note = REG_NOTES (x); note; note = XEXP (note, 1)) 711169689Skan { 712169689Skan print_value (t, XEXP (note, 0), 1); 713169689Skan fprintf (f, " %s: %s\n", 714169689Skan GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t); 715169689Skan } 71690075Sobrien} 71790075Sobrien 718169689Skan/* Emit a slim dump of X (an insn) to stderr. */ 71990075Sobrienvoid 720169689Skandebug_insn_slim (rtx x) 72190075Sobrien{ 722169689Skan dump_insn_slim (stderr, x); 72390075Sobrien} 72490075Sobrien 725169689Skan/* Provide a slim dump the instruction chain starting at FIRST to F, honoring 726169689Skan the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS 727169689Skan include more information on the basic blocks. */ 72890075Sobrienvoid 729169689Skanprint_rtl_slim_with_bb (FILE *f, rtx first, int flags) 73090075Sobrien{ 731169689Skan basic_block current_bb = NULL; 732169689Skan rtx insn; 73390075Sobrien 734169689Skan for (insn = first; NULL != insn; insn = NEXT_INSN (insn)) 73590075Sobrien { 736169689Skan if ((flags & TDF_BLOCKS) 737169689Skan && (INSN_P (insn) || GET_CODE (insn) == NOTE) 738169689Skan && BLOCK_FOR_INSN (insn) 739169689Skan && !current_bb) 740169689Skan { 741169689Skan current_bb = BLOCK_FOR_INSN (insn); 742169689Skan dump_bb_info (current_bb, true, false, flags, ";; ", f); 743169689Skan } 74490075Sobrien 745169689Skan dump_insn_slim (f, insn); 74690075Sobrien 747169689Skan if ((flags & TDF_BLOCKS) 748169689Skan && current_bb 749169689Skan && insn == BB_END (current_bb)) 75090075Sobrien { 751169689Skan dump_bb_info (current_bb, false, true, flags, ";; ", f); 752169689Skan current_bb = NULL; 75390075Sobrien } 75490075Sobrien } 75590075Sobrien} 75690075Sobrien 757