有了print_rtx()函数和gen_rtx()函数以及insn结构和rtx结构
【主要是fmt格式化字符串和GET_RTX_LENGTH】的定义。
对于rtx或者说insn我们已经能游刃有余了!
/* Allocate an rtx of code CODE. The CODE is stored in the rtx;
all the rest is initialized to zero. */rtx
rtx_alloc (code)
RTX_CODE code;
{
rtx rt;
register int nelts = GET_RTX_LENGTH (code);
register int length = sizeof (struct rtx_def)
+ (nelts - 1) * sizeof (rtunion);
rt = (rtx) obstack_alloc (rtl_obstack, length);
* (int *) rt = 0;
PUT_CODE (rt, code);
return rt;
}
非常简单的函数,最主要的是得到code对应的长度比如我们的call_insn的长度为7
那么除了分配一个rtx_def结构的长度外,还要分配指定长度的空间以便存放其他的rtx的地址!
当然每个空间是四个字节。当然这四个字节不是一定是指针,比如对于我们研究的call_insn来说
第一个空间是表示此insn的编号,而第二个第三个空间表示前一个insn和后一个insn。
前一个insn的编号INSN_UID (XEXP (in_rtx, i))
#define INSN_UID(INSN) ((INSN)->fld[0].rtint) 在rtl.h头 文件里。
typedef union rtunion_def
{
int rtint;
char *rtstr;
struct rtx_def *rtx;
struct rtvec_def *rtvec;
enum machine_mode rttype;
} rtunion;
/* Emit an insn of given code and pattern
at a specified place within the doubly-linked list. */
/* Make an instruction with body PATTERN
and output it before the instruction BEFORE. */
rtx
emit_insn_before (pattern, before)
register rtx pattern, before;
{
register rtx insn;
if (GET_CODE (pattern) == SEQUENCE)
{
register int i;
/* For an empty sequence, emit nothing. */
if (XVEC (pattern, 0))
for (i = 0; i < XVECLEN (pattern, 0); i++)
add_insn_after (XVECEXP (pattern, 0, i), PREV_INSN (before));
return PREV_INSN (before);
}
insn = make_insn_raw (pattern, 0);
PREV_INSN (insn) = PREV_INSN (before);
NEXT_INSN (insn) = before;
/*全局变量before,如果我们新建了一个insn则把before指向的地址赋给我们,
然后我们的下一个insn的地址是before*/
if (PREV_INSN (insn))
NEXT_INSN (PREV_INSN (insn)) = insn;
else
first_insn = insn;
PREV_INSN (before) = insn;
return insn;
}
/* Make an instruction with body PATTERN and code CALL_INSN
and output it before the instruction BEFORE. */
rtx
emit_call_insn_before (pattern, before)
register rtx pattern, before;
{
rtx insn = emit_insn_before (pattern, before);
PUT_CODE (insn, CALL_INSN);
return insn;
}