gcc源代码分析gen_push_operand ()函数和emit_move_insn ()函数

如何生成下面红色的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)
     rtx operand0;
     rtx operand1;
{
  return gen_rtx (SET, VOIDmode, 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 ()函数。

你可能感兴趣的:(gcc,源代码,分析)