您好,欢迎访问三七文档
当前位置:首页 > 金融/证券 > 股票报告 > GCC编译器后端移植技术
GCC编译器后端移植技术摘要:从gcc编译器的体系结构出发,提出了gcc前后端分离的结构以适合移植到不同的硬件平台,分析了gcc后端移植的关键技术。重点阐述后端移植所必须的文件,并详细说明这些文件的作用,给出了rtl中间语言的语法结构以及典型指令的rtl指令模板结构。最后通过一个实例对移植到新硬件体系结构的gcc进行测试,结果表明针对特定的硬件体系结构,gcc后端移植技术是可行的,能够产生正确的汇编语言代码。关键词:rtl中间语言;指令模板;机器描述md;后端移植引言近年来,嵌入式计算机系统被广泛应用于军事及空间领域的各种控制及智能系统中。在这些系统中,嵌入式计算机是系统的核心和智能部件。随着集成电路技术的发展,开始设计生产具有自主产权的专用芯片,并越来越多的将其应用于航空航天等相应嵌入式计算机系统中。同时嵌入式计算机应用的不断发展给计算机技术的各个方面提出了新的要求和挑战。嵌入式系统的开发特征对开发工具提出了特殊的要求。它对于代码大小,代码性能,以及可配置性的苛刻要求,使得在桌面以及服务器端开发中表现良好的编译系统往往不能胜任。这需要为其开发专用的高级语言编译器,但是开发一个完全自主化的编译器往往需要很长时间,并不是一个可取的方案,所以把目光转向可变目标编译器[1]。可变目标编译器能够针对不同的目标机器生成代码。编译器中与机器有关的部分被独立成模块,针对不同的目标机器,这些模块可以方便的进行替换。gcc就是是可变目标编译器,作为开源编译器,它源码丰富,文档详尽,是一个支持多种高级语言和多机器平台的系统,高度优化和可移植性能是该编译系统最为突出的2大特点。本文将详细介绍gcc移植相关的技术。1gcc体系结构gcc(gnucompliercollection)是一个成功的支持多种高级语言和多种机器平台的系统。gcc体系结构(如图1所示)可以划分为2部分:与语言相关,目标机器无关的前端和与语言无关,目标机器相关的后端。图1gcc体系结构它是一个典型的语法制导的优化编译器[23],前端通过词法分析,语法分析,语义分析,生成语法树,对语法树简单优化之后,将其转化为中间代码。后端接受前端产生的语法树,将其转换为中间语言的表现形式,在此基础上进行各种优化,然后根据目标机的机器描述生成汇编程序代码[4]。gcc要实现支持多平台编译,必须解决3个根本问题:需要设计一种较好的中间语言,在适当的层次上,向上能支撑多种语言的映射,向下能够适合多平台转换并且适合于各种优化;需要设计一种对目标机恰当的机器描述;在机器描述与编译主体之间需要仔细的设计一种统一接口。将gcc移植到一个新的硬件系统时,上述3个问题的解决是致关重要的。由于gcc前端与语言相关[5],已经很成熟稳定,能够支持当今流行的大部分高级语言,如c/c++,java,fortran,ada等,所以不对前端做过多介绍,着重介绍后端技术。2rtl中间语言rtl(registertransferlanguage)[6]是一种以一种虚拟寄存器(pseudoregister)的方式来叙述计算机行为的语言。rtl有5种对象:表达式,整数,宽整数,字符串和向量。其中最重要的是表达式rtx(rtlexpression)。rtx类似于c的结构体,通常用指针来引用它,指针类型定义名为rtx。每个rtx都具有统一的内部数据结构与外部语法。本文只涉及rtx的外部语法,即rtx表达式的文本形式的语法,其一般形式为:(code:mopn1opn2……),code:rtx操作码。该操作码指明rtx表示的操作类型,如表示一条指令时进行某种说明。此外,code还确定rtx的操作数个数和这些操作数的种类。m:机器模式。表示数据和运行结果的类型,它反映了数据类型与字长两部分信息。数据类型分为整型,浮点型和复型3种。机器字长则分为8位,16位,32位,64位等。这两部分信息组合所构成的机器方式反映了机器能表示的各种数据类型。opn:操作数。各个rtx表达式的操作个数以及操作数的种类是各不相同的,这取决于rtx操作码。以下是一个实际的rtx表达式例子,(insn760(set(mem:si(plus:si(reg:si54virtualstackvars)(const_int12[0xfffffff4]))[0a+0s4a32])(const_int3[0x3]))1(nil))操作码“insn”指出这是一条表示指令的rtx,前3个操作数均为整常数,分别表示本条指令编号,前一条指令编号和后一条指令编号,构成前向链和后向链(如图2所示)。其对应的树结构(如图3所示)。3gcc后端技术gcc后端对于目标机器的支持全部体现在后端描述中,将gcc移植到一个新的硬件系统时,要对新系统的处理器架构要进行详细的描述,使gcc的后端支持新的处理器架构。本节重点介绍后端描述的结构以后端描述的自动处理。图2insn对象的双向链表图3rtx表达式及其对应的树结构3.1gcc后端描述gcc对于后端的描述主要有3个文件[7],一个是c语言宏文件,一个c源文件,一个用rtl表达式写成的机器描述文件md。将gcc移植到一个新的硬件系统时,要对新系统的处理器架构要进行详细的描述,使gcc的后端支持新的处理器架构。具体的描述文件就是上述3个文件:c的宏文件,c文件和机器描述文件md,分别为target.h,target.c和target.md,target是需要移植的目标机器的代号。下面分别介绍3种文件。3.1.1c的宏文件c的宏是用来描述机器和abi的属性。一般分成以下几类:(1)控制gcc驱动程序选项,目标机器的特定命令行选项。这些宏定义告诉编译驱动程序以何种形式的命令行参数运行诸如预处理,编译,汇编,连接等处理步骤,在运行这些处理步骤中可能需要的查询路径名以及是否需要运行某一些特殊的处理步骤等。(2)存储布局:要涉及基本的数据类型的大小,对齐约定;(3)应用二进制编程接口(abi),如何调用函数;(4)目标机器的寄存器使用,包括类型,基本特征,寄存器分配的顺序,用于构造堆栈的寄存器指令等等;(5)寻址模式,描述目标机器不同的寻址模式;(6)汇编文件输出框架格式约定,指定汇编程序的初试数据段,正文段,一般数据段等等的格式要求,定义汇编输出函数的函数名;(7)调试信息输出约定,指定系统支持的调试文件格式。这些参数,其中很多不是参数核集的元素,有缺省的处理方式,但要具体地描述一个特定平台,须对它们作正确而有效的定义。它们是绝大多数平台至少提供的内容,只能描述出平台最基本的功能。3.1.2c源文件target.h中定义的宏都是生成代码,这给调试增加了一定的难度和复杂度,所以在target.c文件中增加一个同名函数(但是为小写字母)。例如,在target.h文件中,定义了这样一个宏:#definepreferred_reload_class(x,class)preferred_reload_class(x,class)为了让其可用,并保证程序的可读性,引入了target_protos.h文件,在target_protos.h中,声明了同名函数:externenumreg_classpreferred_reload_class(rtx,enumreg_class)并且在target.c文件中具体定义了此函数。这是一个约定,在配置的时候,配置程序会做处理。由此,可以调试这个函数,而不必在众多的文件中增加宏定义。3.1.3机器描述md机器描述md中用rtl语言描述的指令模板是核心内容。md文件是目标机指令集的一个形式化的说明文件,它针对gcc中的各种操作模式,描述了指定目标机支持的操作和实现情况,而并非目标指令集的简单汇集。编译系统根据由机器描述md生成的数据结构和函数定义集合,进行中间代码的生成以及中间代码到汇编代码的映射。这些“标准指令”是从各种目标机的指令集中抽象出来的,但同时它又能表达gcc中的各种基本操作。,下面是指令模板的一般结构[8]:(define_patterntype“(optional)patternname”[rtltempalte]“optionalpaternalcondition”“outputtemplate”(optinally:[attributesetting]))简单介绍以下各个参数的含义:(1)patterntype有2种类型,insn是用于定义指令样板的rtx表达式中最核心的一种类型,既可作为生成模板,又可作为匹配模板;expand是模板的扩充定义,仅在操作与标准名称模板相关时使用。(2)patternname指令模板名,一个模板可以为gcc规定的标准指令名,或者开发者任意给定的名字,也可以空字符串,但是模板名必须惟一。(3)rtltempalte一个复杂操作的集合,为一不完全的rtx表达式或向量,称为rtl模板。它表示指令模板的rtl指令体,只规定了rtl指令体中的各种操作以及操作数的位置和操作数必须满足的条件和限制,并未指明具体的操作数。(4)optionalpaternalcondition为一字符串,称为条件。这个字符串或者为空,或者为一个c语言条件表达式。当非空时,它指出此模板有效的条件。(5)outputtemplate为一字符串,称为输出模板。输出模板用来确定与此模板相匹配的rtl指令的汇编输出形式。(6)attributesetting它为一任选的rtx向量,称为指令属性。当此操作数出现时,它给出与这一模板相匹配的指令属性。下面是mips.md中的一条单浮点加法指令模板:(define_insn“addsf3”[(set(match_operand:sf0“register_operand”“=f”)(plus:sf(match_operand:sf1“register_operand”“f”)(match_operand:sf2“register_operand”“f”)))]“target_hard_float”“add.s\t%0,%1,%2”[(set_attr“type”“fadd”)(set_attr“mode”“sf”)])这是一条单浮点加法指令的指令模板[9],分别对应指令模板结构的各个参数的含义。从这个指令模板,可以看出这条指令的模板类型patterntype是insn;模板名patternnames是”addsf3”,这是指令名,从指令名可以看出这是一条单浮点加法指令;这条指令有3个操作数,rtl模板规定了3个操作数的各种操作和位置以及必须满足的条件和限制条件,”set”,”mem”,”plus”分别表示赋值,存储器引用和加法运算,它们的操作数均为rtx表达式;指令模板是否有效的条件是”target_hard_float”;汇编输出模板是”add.s\t%0,%1,%2”,输出的汇编代码形式就如输出模板所示;最后是指令属性,表明这是浮点加法指令,指令的模式为sf,是单浮点模式。3.2gcc后端处理机器描述文件md建立抽象机标准指令、中间语言rtl、目标机汇编模板三者之间的联系,它是一个正文文件,如果编译过程中为构造或匹配rtl去搜寻这样一种文件,将会机器缓慢。为此gcc编译内部设计了专门的函数和数据结构作为编译主体与机器描述之间的接口,编译主体通过这些函数和数据结构获得md的内容。在编译器的构造期间,利用gcc提供的一套独立的,专用的机器描述处理程序,将正文形式的md转换成含有接口所需的数据结构与函数的c源程序。gen*正是完成这一工作的一套转换程序[10],对机器描述文件进行处理(如图4所示),生成一组c文件,或者头文件,生成的这些文件以及手工定义的target.c和target.h结合起来就是gcc的机器相关部分。图4后端处理流程gen*是指一套11个c程序,它们针对不同的编译处理目的分析md,生成相应一套接口程序包含11个c文件insn*.c,或者insn*.h。由gen*生成的这套接口程序分别作用于rtl的优化,机器相关的优化,汇编代码输出等过程。其中,insn*.h含
本文标题:GCC编译器后端移植技术
链接地址:https://www.777doc.com/doc-5084028 .html