下面是gcc -dr hello.c产生的hello.dr文件的一部分
(insn 6 4 7 (set (mem:SI (pre_dec:SI (reg:SI 7)))
(symbol_ref:SI ("*LC0"))) -1 (nil)
(nil))
(call_insn 7 6 9 (set (reg:SI 0)
(call (mem:QI (symbol_ref/v:SI ("printf")))
(const_int 4))) -1 (nil)
(nil))
(insn 9 7 10 (set (reg/i:SI 0)
(const_int 0)) -1 (nil)
(nil))
下面是rtl.h头文件的部分内容
#define XEXP(RTX, N) ((RTX)->fld[N].rtx)
#define XINT(RTX, N) ((RTX)->fld[N].rtint)
/* Holds a unique number for each insn.
These are not necessarily sequentially increasing. */
#define INSN_UID(INSN) ((INSN)->fld[0].rtint)
/* Chain insns together in sequence. */
#define PREV_INSN(INSN) ((INSN)->fld[1].rtx)
#define NEXT_INSN(INSN) ((INSN)->fld[2].rtx)
/* The body of an insn. */
#define PATTERN(INSN) ((INSN)->fld[3].rtx)
对于上面call_insn来说第一个,7是本条指令的号码,对应的格式符是i
第二个,6是上一条指令的号码,对应的格式符是u
第三个,9是下一条指令的号码。对应的格式符是u。
(set (reg:SI 0)
(call (mem:QI (symbol_ref/v:SI ("printf")))
(const_int 4)))
对应的格式符是e。所以要递归调用。
/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
static void
print_rtx (in_rtx)
register rtx in_rtx;
{
static int indent;
register int i, j;
register char *format_ptr;
if (sawclose)
{
fprintf (outfile, "\n%s",
(spaces + (sizeof spaces - indent * 2)));
sawclose = 0;
}
if (in_rtx == 0)
{
fprintf (outfile, "(nil)");
sawclose = 1;
return;
}
/* print name of expression code */
/*打印表达式的名字,比如(call_insn,再比如(set,再比如(reg:SI */
fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
if (in_rtx->in_struct)
fprintf (outfile, "/s");
if (in_rtx->volatil)
fprintf (outfile, "/v");
if (in_rtx->unchanging)
fprintf (outfile, "/u");
if (in_rtx->integrated)
fprintf (outfile, "/i");
if (GET_MODE (in_rtx) != VOIDmode)
{
/* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
else
fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
}
format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
switch (*format_ptr++)
{
case 'S':
case 's':
if (XSTR (in_rtx, i) == 0)
fprintf (outfile, " \"\"");
else
fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
sawclose = 1;
break;
/* 0 indicates a field for internal use that should not be printed. */
case '0':
break;
case 'e':
indent += 2;
if (!sawclose)
fprintf (outfile, " ");
print_rtx (XEXP (in_rtx, i));
/*这里是递归调用啊,比如call_insn,
DEF_RTL_EXPR(CALL_INSN, "call_insn", "iuueiee")
*/
indent -= 2;
break;
case 'E':
indent += 2;
if (sawclose)
{
fprintf (outfile, "\n%s",
(spaces + (sizeof spaces - indent * 2)));
sawclose = 0;
}
fprintf (outfile, "[ ");
if (NULL != XVEC (in_rtx, i))
{
indent += 2;
if (XVECLEN (in_rtx, i))
sawclose = 1;
for (j = 0; j < XVECLEN (in_rtx, i); j++)
print_rtx (XVECEXP (in_rtx, i, j));
indent -= 2;
}
if (sawclose)
fprintf (outfile, "\n%s",
(spaces + (sizeof spaces - indent * 2)));
fprintf (outfile, "] ");
sawclose = 1;
indent -= 2;
break;
case 'i':
fprintf (outfile, " %d", XINT (in_rtx, i));
sawclose = 0;
break;
/* Print NOTE_INSN names rather than integer codes. */
case 'n':
if (XINT (in_rtx, i) <= 0)
fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
else
fprintf (outfile, " %d", XINT (in_rtx, i));
sawclose = 0;
break;
case 'u':
if (XEXP (in_rtx, i) != NULL)
fprintf(outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
else
fprintf(outfile, " 0");
sawclose = 0;
break;
default:
fprintf (stderr,
"switch format wrong in rtl.print_rtx(). format was: %c.\n",
format_ptr[-1]);
abort ();
}
fprintf (outfile, ")");
sawclose = 1;
}