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

2024-01-02 22:58

本文主要是介绍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源代码分析gen_push_operand ()函数和emit_move_insn ()函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/563885

相关文章

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)