GCC后端指令生成分析(1)

本文深入探讨GCC编译器后端的指令生成和汇编代码的生成过程,涉及RTL指令的创建、汇编代码的形成、机器描述文件分析以及常量和指令的生成。通过示例详细解释了如何从源代码到汇编代码的转化,揭示了GCC内部的工作机制。
摘要由CSDN通过智能技术生成

主要研究GCC指令生成阶段的各个步骤,重点在编译器代码与机器描述之间的接口函数和数据结构。以一小段代码片段为示例,逐步追溯直至汇编代码生成的整个过程。

引言

机器描述文件是形如*.md的文件,其核心部分是两类定义:“define_insn”和“define_expand”。

md文件中define_insn模版示意图
图1 md文件中define_insn模版示意图

define_insn主要分为以下几个部分。

  1. 名字,对应图1中的“addqi3_cc”。
  2. 样式(pattern),对应于图1中的“[(set (reg:CC… … match_dup 2)))]”。规定了RTL指令体中的各种操作以及操作数的位置和操作数必须满足的条件。
  3. 条件,对应于图1中的“ix86_binary_operator_ok (PLUS, QImode, operands)”,指出此样板有效的前提条件。
  4. 输出模板(output template),对应于图1中的“add{b}\t{%2, %0 | %0, %2}”。确定与此样式相匹配的RTL指令的汇编输出形式。可分为三种:单汇编模板、多汇编模板和C代码。前两种给出的就是机器的汇编指令,第三种不能直接给出指令,C代码被编译器吸收并且动态产生汇编模板。
  5. 指令属性,对应于图1中的“[(set attr … … )])”。给出与该样式所匹配的指令的属性。在编译器的编译过程中,编译器主体与机器描述文件相交互,最终生成汇编代码,完成编译器的使命。

下文中将逐步介绍x86架构下(i386.md文件)后端执行的流程,主要分为三个部分:RTL指令的生成及汇编代码的生成;md文件的分析;编译器后端辅助工具的分析。

RTL及汇编代码的生成

相关文件

GCC编译器从源代码转换到汇编代码的过程,主要经历了三个阶段的中间表示:GIMPLE→RTL→ASM。GIMPLE是比较高层次的语法树;RTL代表指令的rtx表达式;ASM是汇编码。
前端调用后端的函数接口主要是expand_*系列函数集,这一系列函数的作用是完成从tree到rtl的转换。这些函数按照功能分类在以下一些文件中被实现:stmt.c, calls.c, expr.c, explow.c, expmed.c, function.c, optabs.c, integrate.c。

  1. stmt.c中的expand_*函数的作用是将前端的语句级别上的语法树转换为等义的rtl。因此stmt.c中的这些expand_*函数是被前端parser最先调用的。换句话说,这些函数是“GCC后端”的第1功能层(顶层)。它们会调用exp*.c的一些expand_*函数来真正完成对“表达式”的求值(也即表达式的tree→rtx,并返回rtx),以及调用emit-rtl.c中gen_rtx和gen_reg_rtx等功能函数。
  2. calls.c也是语句级别上的,它将函数调用语句的tree转换为rtl。
  3. function.c将函数一级的tree转换为rtl。
  4. expr.c, explow.c, expmed.c完成对表达式的tree到rtx的转换。这些文件中的expand_*函数基本可以归纳为第2功能层。它这里会将一步引用insn_emit.c文件中的gen_*等功能函数以及optabs.c文件中的expand_*函数。
  5. optabs.c文件中的expand_*函数,作用是将基本的一元操作和二元操作转换为rtx。它属于 expand_*函数集中的第3功能层。它这里接着往下就会引用与平台相关的一些函数模块(从 md 自动生成的一些程序文件,如 insn-output.c、insn-emit.c以及其它 insn-*系列文件)。

常量的生成

rtx包含不同的类型,主要有常量、指令等。指令rtx的生成,需要从md文件中读取信息来实现;而常量的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值