Expr.c:文件中的emit_call_insn()函数调用了gen_call()函数

来源:互联网 发布:php htnl模板引擎 编辑:程序博客网 时间:2024/05/06 15:58

 genoutput由i386.md生成Insn-output.c


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,
    0,
    0,
    0,
    gen_jump,
    gen_tablejump,
    gen_call,
    gen_call_value,
    gen_nop,
  };



static void
emit_call_1 (funexp, funtype, stack_size, next_arg_reg, valreg, old_inhibit_defer_pop, use_insns)
     rtx funexp;
     tree funtype;
     int stack_size;
     rtx next_arg_reg;
     rtx valreg;
     int old_inhibit_defer_pop;
     rtx use_insns;
{
  rtx stack_size_rtx = gen_rtx (CONST_INT, VOIDmode, stack_size);
  rtx call_insn;

  if (valreg)
    emit_call_insn (gen_call_value (valreg,
                    gen_rtx (MEM, FUNCTION_MODE, funexp),
                    stack_size_rtx, next_arg_reg));
  else
    emit_call_insn (gen_call (gen_rtx(MEM, FUNCTION_MODE, funexp),
                  stack_size_rtx, next_arg_reg));  //终于我们知道了哪里调用了gen_call()函数,第二又调用了gen_rtx()函数

  /* Find the CALL insn we just emitted and write the USE insns before it.  */
  for (call_insn = get_last_insn();
       call_insn && GET_CODE (call_insn) != CALL_INSN;
       call_insn = PREV_INSN (call_insn))
    ;

  if (! call_insn)
    abort ();

  /* Put the USE insns before the CALL.  */
  emit_insn_before (use_insns, call_insn);

  inhibit_defer_pop = old_inhibit_defer_pop;

  /* If returning from the subroutine does not automatically pop the args,
     we need an instruction to pop them sooner or later.
     Perhaps do it now; perhaps just record how much space to pop later.  */

  if (! RETURN_POPS_ARGS (funtype)
      && stack_size != 0)
    {
      if (flag_defer_pop && inhibit_defer_pop == 0)
    pending_stack_adjust += stack_size;
      else
    adjust_stack (stack_size_rtx);
    }
}



emit_call_1()函数被expand_call()函数调用

/* Generate all the code for a function call
   and return an rtx for its value.
   Store the value in TARGET (specified as an rtx) if convenient.
   If the value is stored in TARGET then TARGET is returned.
   If IGNORE is nonzero, then we ignore the value of the function call.  */

static rtx
expand_call (exp, target, ignore)
     tree exp;
     rtx target;
     int ignore;
{

...


  /* Generate the actual call instruction.  */
  /* This also has the effect of turning off any pop-inhibition
     done in expand_call.  */
  if (args_size.constant < 0)
    args_size.constant = 0;
  emit_call_1 (funexp, funtype, args_size.constant,
           FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
           valreg, old_inhibit_defer_pop, use_insns);


expand_call()函数被expand_expr()函数调用

rtx
expand_expr (exp, target, tmode, modifier)
     register tree exp;
     rtx target;
     enum machine_mode tmode;
     enum expand_modifier modifier;
{

...


    case CALL_EXPR:
      /* Check for a built-in function.  */
      if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == FUNCTION_DECL
      && (DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
          != NOT_BUILT_IN))
    return expand_builtin (exp, target, subtarget, tmode, ignore);
      /* If this call was expanded already by preexpand_calls,
     just return the result we got.  */
      if (CALL_EXPR_RTL (exp) != 0)
    return CALL_EXPR_RTL (exp);
      return expand_call (exp, target, ignore);



expand_expr()函数被expand_expr_stmt()函数调用stmt.c文件中。


stmt:
      compstmt    {}
    | expr ';'
        { emit_line_note (input_filename, lineno);
          /* Do default conversion if safe and possibly important,
             in case within ({...}).  */
          if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
               && lvalue_p ($1))
              || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
            $1 = default_conversion ($1);
          expand_expr_stmt ($1);
          clear_momentary (); }


1 0
原创粉丝点击