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

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

python中的高阶函数示例详解

《python中的高阶函数示例详解》在Python中,高阶函数是指接受函数作为参数或返回函数作为结果的函数,下面:本文主要介绍python中高阶函数的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录1.定义2.map函数3.filter函数4.reduce函数5.sorted函数6.自定义高阶函数

Python中的sort方法、sorted函数与lambda表达式及用法详解

《Python中的sort方法、sorted函数与lambda表达式及用法详解》文章对比了Python中list.sort()与sorted()函数的区别,指出sort()原地排序返回None,sor... 目录1. sort()方法1.1 sort()方法1.2 基本语法和参数A. reverse参数B.

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe