如何生成下面红色的3个指令?
和gen_push_operand ()函数和emit_move_insn ()函数有关,他们都在expand_call()函数中被调用。
expand_call ()函数调用了store_one_arg ()函数,
store_one_arg ()函数调用了emit_push_insn()函数,
emit_push_insn ()函数调用了 emit_move_insn ()函数。emit_push_insn ()函数中具体的位置:
rtx addr;
#ifdef PUSH_ROUNDING
if (args_addr == 0)
addr = gen_push_operand ();
else
#endif
if (GET_CODE (args_so_far) == CONST_INT)
addr
= memory_address (mode,
plus_constant (args_addr, INTVAL (args_so_far)));
else
addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
args_so_far));
emit_move_insn (gen_rtx (MEM, mode, addr), x);
}
(mem:BLK (symbol_ref:SI ("*LC0")))
(pre_dec:SI (reg:SI 7))
(mem:SI (pre_dec:SI (reg:SI 7)))
(set (mem:SI (pre_dec:SI (reg:SI 7)))
(symbol_ref:SI ("*LC0")))
经过添加fprintf之后
end addr_expr
gen_push_operand
(pre_dec:SI (reg:SI 7))
end gen_push_operand
before emit_move_insn
(mem:SI (pre_dec:SI (reg:SI 7)))
before return emit_insn icode= 14
(set (mem:SI (pre_dec:SI (reg:SI 7)))
(symbol_ref:SI ("*LC0")))
emit_insn
after emit_move_insn
before prepare_call_address
emit_move_insn()函数也在expr.c文件中
/* Generate code to copy Y into X.
Both Y and X must have the same mode, except that
Y can be a constant with VOIDmode.
This mode cannot be BLKmode; use emit_block_move for that.
Return the last instruction emitted. */
rtx
emit_move_insn (x, y)
rtx x, y;
{
enum machine_mode mode = GET_MODE (x);
x = protect_from_queue (x, 1);
y = protect_from_queue (y, 0);
if (mode == BLKmode)
abort ();
if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
int icode = (int) mov_optab->handlers[(int) mode].insn_code;
if (! (*insn_operand_predicate[icode][1]) (y, mode)
&& (CONSTANT_P (y) || GET_CODE (y) == CONST_DOUBLE))
{
y = force_const_mem (mode, y);
if (! memory_address_p (mode, XEXP (y, 0)))
y = gen_rtx (MEM, mode, memory_address (mode, XEXP (y, 0)));
}
return emit_insn (GEN_FCN (icode) (x, y));
}
...
else
abort ();
}
expr.h文件中有GEN_FCN(CODE)的定义
#define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)])
这里的CODE等于14
insn_output.c文件中有insn_gen_function[]函数数组的定义
rtx (*const insn_gen_function[]) () =
{
gen_tstsi,
gen_tsthi,
gen_tstqi,
gen_tstsf,
gen_tstdf,
gen_cmpsi,
gen_cmphi,
gen_cmpqi,
gen_cmpdf,
gen_cmpsf,
0,
0,
0,
0,
gen_movsi,
gen_movsi()函数定义在insn-emit.c文件中
rtx
gen_movsi (operand0, operand1)}
很好的解释了(set (mem:SI (pre_dec:SI (reg:SI 7)))
(symbol_ref:SI ("*LC0")))
第三条指令的生成。
expand_call ()函数调用了store_one_arg ()函数,
store_one_arg ()函数调用了emit_push_insn()函数,
emit_push_insn ()函数调用了emit_move_insn ()函数。