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

相关文章

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者