本发明的目的,就是要提供一种变换装置,对子程序调用指令和被调用的子程序来说,即使它们存储在不同的文件中,也不会产生流水线停顿,该程序变换装置就是要生成这样的能够调用子程序的可执行程序,本发明的另一个目的,是提供能够执行前述可执行程序的处理器。
为了达到上述目的,下述的程序变换装置以及执行它的可执行程序的处理器便可达到这一目的。
首先,在将程序翻译为机器语言指令序列时,对程序中的各子程序,逐个地检测出它们所需堆栈的长度,与机器语言指令序列同时保存到文件中。
其次,在连接分散在多个文件中的机器语言指令序列时,从机器语言程序中检测出转移到子程序的转移指令,从包含有该转移目标子程序的前述文件中,读出该子程序所需的堆栈的长度,并将该转移指令转换为既包括转移到转移目标,又包括分配所需堆栈长度的堆栈空间而执行的一系列操作为内容的指令序列。
执行这样的可执行目标程序的处理器,并不象通常的那样在子程序的转移指令执行之后,再取出分配堆栈的指令,而是连续取出子程序转移指令和分配堆栈的指令。
此外,利用下述的程序变换装置和执行其可执行目标程序的处理器,便可达到上述目的。
也就是说,首先,在将程序翻译为机器语言指令序列时,对程序中的各子程序,检测出各子程序运行中所要保存的寄存器名,将它们与机器语言指令序列同时保存到文件中。
其次,在连接包含在多个文件之中的机器语言指令序列时,从机器语言指令序列中检测出转移到子程序的转移指令,从包含有该转移目标子程序的前述文件中,读出在该子程序的运行中所要保存的所有寄存器名,并将该转移指令置换为执行下述一系列操作为内容的指令,这些处理就是转移到目标子程序的转移操作,以及保存这些寄存器内容的一系列操作。
执行这样的可执行目标程序的处理器,并不是象传统的那样在完成了向子程序的转移之后,才去取出保存寄存器内容的指令,而是完成一个相当于连续取出子程序转移指令和保存寄存器内容指令的动作。
进而,为了达到上述目的,也可利用下述的程序转换装置和执行该装置的可执行目标程序的处理器来达到。
也就是说,首先,在将源程序翻译为机器语言程序时,对程序中的子程序,逐个检测出它们所需要的堆栈长度和子程序运行中应该保存的寄存器名,将它们与机器语言指令序列一同保存到文件中。
此后,在连接分散在多个文件中的机器语言指令序列的时候,从机器语言指令序列中,检测出转移到子程序的控制转移指令,从包含有该转移目标子程序的前述文件中,读出该子程序所需的堆栈长度以及该子程序的运行中应保存的寄存器名,并将该控制转移指令置换为执行一系列操作为内容的指令,这些操作包括使控制转移到转移目标子程序,分配所需长度堆栈,以及保存寄存器内容的操作。
执行这样的可执行目标程序的处理器,并不象传统的那样等到控制转移到子程序之后,才去取出分配堆栈的指令和保存寄存器内容的指令,而是执行一系列动作,这些动作相当于连续地取出使控制转移到子程序的指令、分配堆栈的指令以及保存寄存器内容的指令。
这样一来,利用这样的程序变换装置和处理器,即便是对那些将子程序调用指令和被调用的子程序放到不同的文件中的源程序来说,都可以避免因执行控制转移指令或取出转移目标指令时所导致的冒险等而引起的流水线停顿的发生,达到高速进行控制转移的效果。
以下,就本发明的实施例,结合图示进行详细说明。
图5是有关本发明的第1实施例的程序变换装置的结构示意方框图。并且,图5中同时地表示出了作为本装置的处理对象的输入文件101,102,输出文件106,107,以及由处理结果生成的可执行文件113。
本装置的结构大体上可分为翻译部103和连接部108。
翻译部103主要是将由高级语言所写的源程序翻译为机器语言指令序列。把包含有源程序的输入文件101,102输入给翻译部103,当结束处理后,翻译部103把106,107作为输出文件进行输出。此处所谓文件,是指作为翻译部103的输入输出单位的程序和机器语言指令序列的集合。翻译部103以文件为单位进行翻译。例如,当只给定一个输入文件A 101时,翻译部103自动地决定出对应于输入文件A 101的名字,并输出结果文件A 106。而翻译部103,则进一步由机器指令生成部104和提取部105组成。
机器指令生成部104,将所供给的源程序进行语法分析等之后,变换为机器语言指令序列。
提取部105,进而由堆栈长度提取部105a和保存寄存器提取部105b组成。堆栈长度提取部105a对存在于源程序中的子程序,计算出为各子程序的运行所必要的堆栈长度,并生成用来定义所算出的堆栈长度的伪指令,放置于该子程序的机器语言指令序列的开始位置。此处,所谓堆栈长度是指子程序在运行中所使用的局部工作区域的大小。所谓伪指令是指为了将此处算出的堆栈大小的信息传递给后述的连接部108的指令,它被连接部所使用。
保存寄存器提取部105b对存在于源程序中的子程序,检出在各子程序运行之前应该保存的寄存器,生成说明所检测出的寄存器的伪指令,放置于该子程序的机器语言指令序列的开头部分。应当保存的寄存器,就是由于子程序运行而将被破坏其值的那些寄存器。所谓伪指令,与堆栈长度提取部105a所生成的伪指令是同一类型的东西,它们是为了将应予保存的寄存器的有关信息传递给连接部而被使用。
连接部108的主要任务是连接机器语言程序指令序列,并生成可在处理器上执行的可执行目标程序。此时,它也对翻译部103所生成的伪指令进行处理。此外,上述的连接作业,由于与通常的LINKER(连接程序)等所进行的处理没有什么不同,因而对进行该处理的构成部分未进行图示。包含着机器语言指令序列的多个文件106、107被送给连接部108,在处理结束之后,连接部108输出可执行文件113。
连接部108进而由转移指令检测部109,文件检索部110,获得部111以及子程序调用指令生成部112构成。
转移指令检测部109从给定的所有输出文件中,检测出控制转移指令,并将被发现的控制转移指令通知文件检索部110。此外,这里所谓控制转移指令,是指转移到子程序的控制转移指令。
文件检索部110对接到通知的控制转移指令,确定出该转移指令所指定的转移目标子程序所属的文件名。并将该文件名和转移目标子程序名一起同时通知获得部111的堆栈大小获得部111a和保存寄存器获得部111b。
堆栈大小获得部111a对放置于转移目标子程序(该子程序所存放的文件由文件检索部110告知)的开始处所放置的伪指令进行解释之后,将该子程序在运行中所必要的堆栈大小通知给子程序调用指令生成部112。
同样地,保存寄存器获得部111b,对转移目标子程序(该子程序所存放的文件由文件检索部110告知)的开始处所放置的伪指令进行解释之后,将该子程序运行过程中所应保存的寄存器的种类通知子程序调用指令生成部112。
子程序调用指令生成部112根据获得部111所通知的堆栈大小和寄存器的种类,生成调用子程序的专用子程序调用指令。这里所谓的专用子程序调用指令,是指处理器对控制转移处理、堆栈的分配以及寄存器的保存这样的三个处理的情况下顺序执行的机器语言指令,而不发生流水线停顿。
最后,连接部108,将转移到子程序的子程序调用指令置换为由子程序调用指令生成部112所生成的该子程序的专用子程序调用指令,同时,将该子程序中所配置的分配堆栈的机器语言指令或保存寄存器的机器语言指令进行删除,生成一个可执行的目标程序,作为可执行文件113,予以输出。
上述连接部108的处理,对由控制转移指令检测部119所检测出的所有控制转移指令循环进行处理。
对于上述结构的装置的操作,用具体程序来加以说明。输入文件A 101中,包含有图6所示的主程序f( )。主程序f( )用两个参数调用子程序g( )。
另一方面,输入文件B 102中,包含有图7所示的子程序g( )。子程序g( )计算出所给的二个参数的和与差。
当将图6中所示的输入文件A 101供给翻译部103后,主程序f( )被翻译为机器语言指令,同时,在该主程序f( )所需要的堆栈大小或应保存的寄存器信息被提取之后,生成图8中所示的输出文件A 106,并予输出。同样地,当图7所示的输入文件B102供给翻译部103后,子程序g( )被翻译为机器语言指令,同时,该子程序g( )所需的堆栈大小或应保存的寄存器的信息被提取之后,生成图9所示的输出文件并被输出。此外,这里所谓的机器语言指令的意义如下所述。
f:表示该函数的标号。
·STACKSIZE S:表示该函数运行过程中所需的堆栈大小为S字节。
·REGLIST r1,r2:表示该函数运行之前应予保存的寄存器是r1和r2。
SP:堆栈指针
#××××:表示立即数××××。
(SP+××××):表示内存中地址为SP+××××的数据。
add src,dst:将dst+src之值传送给dst。
sub src,dst:将dst-src之值传送给dst。
mov src,dst:将src传送给dst。
jsr label:将SP减4,将下一指令的地址(返回地址)传送到(SP)中,控制转移到标号label。
rts:控制转移到(SP)所指的指令,SP的值递增4。
此处,图8所示的输出文件A 106的清单中下半部的42是由机器语言指令生成部104生成的指令,而上半部41是由提取部105生成的伪指令。栈长度提取部105a判断该主程序f( )所需的堆栈大小为8字节,从而生成伪指令·STACKSIZE。这是因为主程序f( )在将2个参数1、2保存到堆栈之中之后才调用子程序g( ),为保存一个参数需要4个字节的缘故。
此外,保存寄存器提取部105b生成的伪指令只有·REGLIST,这是因为进入这个主程序f( )运行之前没有需要保存的寄存器。
同样地,图9所示的输出文件B 107的清单下部的52是由机器语言指令生成部104生成的指令,而清单的上部51是由提取部105所生成的伪指令。堆栈长度提取部105a判断出这一子程序g( )所必要的堆栈大小为16字节,因而生成了伪指令·STACKSIZE 16。这是在子程序g( )的运行过程中,保存两个寄存器的值的区域和存储2个运算结果a、b的区域所需的总长度,共计16个字节之故。
此外,保存寄存器提取部判断进入该子程序g( )的运行之前应予保存的寄存器是r1和r2,因而生成了伪指令·REGLISTr1,r2。
继而,由翻译部103生成的输出文件A 106和输出文件B107被送到连接部108之后,控制转移指令检测部109检出这些文件中所存在的控制转移指令。因为图8中所示的输出文件A106中,使用了转移指令jsr _g,因此该转移指令被转移指令检测部所检出,通知给文件检索部110。文件检索部110根据对所给的文件106、107的检索,从输出文件B 107中得知转移目标的子程序_g已被定义,将其状况通知给堆栈大小获得部111a和保存寄存器获得部111b。
堆栈大小获得部111a和保存寄存器获得部111b从被通知的输出文件B 107的子程序_g的头部的51处所放置的伪指令得知了必要的堆栈大小(16)和应当保存的寄存器(r1,r2),并将该信息通知子程序调用指令生成部112。
子程序调用指令生成部112根据所通知的信息,生成子程序调用指令Call _g,#16,r1,r2。此处,指令Call label,lsz,rn,rm,是将SP减4后,将下一条指令的地址(返回地址)传送到(SP)中,并让控制转移到_label后,在转移冒险的时钟周期分别将寄存器rn,rm保留到(SP-4)、(SP-8)的地址中,并使SP减少lsz,上述一系列的处理是由单一的一条机器指令来完成。也就是说,子程序调用指令Call _g,#16,r1,r2相当于在不会发生转移冒险的情况下执行了下列一系列指令。
jsr _g
mov r1,(SP-4)
mov r2,(SP-8)
add #-16,SP
最后,连接部108用生成的子程序调用指令Call _g,#16,r1,r2置换以子程序_g为转移目标的图8中所示的输出文件的转移指令jsr _g,同时,删除在子程序_g中所配置的保存寄存器的机器语言指令mov r1,(SP-4)和mov r2,(SP-8)和分配堆栈的机器语言指令add #-16,SP之后,生成可执行目标程序,将图10中所示的可执行文件113输出。
从图10中所列的可执行文件113的清单可知,为了从主程序_f调用子程序_g,利用了子程序调用指令Call _g,#16,r1,r2,另一方面,在子程序_g的头部,已删除了保存寄存器的指令和分配堆栈区域的指令。
从上述说明可知,根据本装置,将源程序翻译为机器语言程序时,由翻译部103在各子程序的机器语言指令序列的头部附加上用来表示每一子程序所必需的堆栈长度或有关保存寄存器的信息的伪指令。继而,连接部108在连接各机器语言指令时,即使是存在向其它文件中的子程序转移的转移指令,通过参照各子程序头部所设置的伪指令,就可以在不产生转移冒险的情况下,将向子程序的转移、寄存器的保存以及堆栈的分配等一系列的动作,用一条单一的子程序调用指令来完成。因此,执行上述连接部108所生成的程序的处理器,即使控制转移到由其它文件所定义的子程序中去,也可以不产生转移冒险,能够高速地进行控制转移处理。
其次,对高速进行控制转移处理的第2实施例有关的处理器加以说明。
图11是与本发明的第2实施例有关的处理器的结构示意图。本处理器由下列部分所构成:指令缓冲器701,指令译码器702,执行部件703,寄存器704,栈指针705,程序计数器706,运算电路707,数据缓冲器708,地址缓冲器709和内部总线710等所组成。
数据缓冲器708和地址缓冲器709,分别在外部数据总线711、外部地址总线712和内部总线710之间进行数据的传送。寄存器704用来临时保存进行运算的数据或图中未示出的主存储器的地址。堆栈指针705用来保存指示主存储器中所设定的堆栈区域的地址。程序计数器706用来保存下次应取出的指令在主存储器中的地址。运算电路707是对输入的两个数据逻辑运算的电路。
指令缓冲器701是用来保存所取出指令的先入先出方式(FIFO)的指令缓冲器。指令缓冲器中所放入的指令,顺次被推出缓冲区,通常,将最先进入的指令送到指令译码器702中。
指令译码器702对从指令缓冲器701传送过来的指令逐一进行译码,并将结果通知执行部件703。此外,指令译码器702,具有对所预定的全部指令进行译码的功能,并将各指令所固有的信息传送到执行部件703,特别地,图11中还示出了具有对子程序调用指令进行译码部分,把它作为子程序调用指令译码器702a加以表示。
执行部件703响应从指令译码器702发来的信息,通过利用未示出的内部控制信号,对各构成部701~709进行控制,以及输入和输出外部控制信号(未示出)。此外,执行部件703还具有对指定的所有的指令进行相应控制的功能,特别把执行子程序调用指令的部分作为子程序调用执行部件703a表示在图11中。
指令缓冲器701,指令译码器702以及执行部件703构成了流水线,分别起到流水线的IF阶段、DEC阶段及EX阶段的功能。
下面就按上述方式构成的本处理器的动作进行说明。
首先对本处理器执行通常的控制转移指令jsr时的动作进行说明。图12中表示出了执行包含通常的转移指令jsr的指令序列,以及执行这些指令序列时的流水线流程示意图。
在第1个时钟周期时从指令缓冲区701所取入的控制转移指令jsr_g,在第2个时钟周期时由指令译码器702进行译码,在第3个时钟周期,由执行部件703进行执行。
在第3个时钟周期,执行部件703将程序计数器706更新为转移目标的地址_g。因此,在第4个时钟周期,在地址_g中所放置的指令即mov r1,(SP-4)被取入指令缓冲器701。
执行部件703为了执行指令jsr _g的下一条指令movr1,(SP-4),忽略了这些指令之间的,亦即存在转移冒险的指令(图12中以灰色表示的部分)的执行。因此,执行部件703在执行了指令jsr _g后,在2个时钟周期之后,执行后随的指令movr1,(SP-4)。
上述的动作与传统的处理器执行上述的同样的控制转移指令时的动作没有什么区别。
其次,对本处理器在执行子程序调用指令Call时的动作加以说明。图13中表示出了包含有子程序调用指令Call的指令序列,以及执行这些指令序列时等价的流水线的动作。
子程序调用指令Call _g,#16,r1,r2是一条单一指令,该指令被子程序调用指令译码器702a译码,由子程序调用执行部件703a所执行,这时,本处理器实际上等价于一连串地执行下述四条指令的动作。
也就是首先执行
jsr _g接着在转移冒险的时钟周期,执行
mov r1,(SP-4)
mov r2,(SP-8)
add #-16,SP
从而,图13的流水线的流程图中画出了执行部件703执行子程序调用指令Call _g,#16,r1,r2时的等价流水线流程图。在时钟周期1指令缓冲器701中取入的转移指令jsr _g,在第2个时钟周期由指令译码器702进行译码,在第3个时钟周期由执行部件703执行。
在第3个时钟周期执行了jsr _g的执行部件703,在下一个时钟周期4执行指令mov r1,(SP-4)。
与图12中所示的流水线的流程相比较后便可明白,尽管是进行了完全相同的处理,图13中的流水线的流程不会产生转移冒险。也就是说,在本处理器执行Call _g,#16,r1,r2时,转移冒险被消除,比执行图12中所示的指令序列执行时间可缩短2个时钟周期。
以上,对与本发明有关的程序变换装置和处理器,利用实施例进行了说明,本发明当然绝不只限于这些实施例,也就是说,
(1)在第1实施例中,子程序调用指令生成部112生成了单一的机器语言指令Call _g,#16,r1,r2,但生成的机器语言指令绝不只限于单一的指令,例如,也可以生成
Call _g
mov r1,(SP-4)
mov r2,(SP-8)
add #-16,SP四条机器指令。也就是说,指令Call _g使控制转移到_g的同时,在不发生转移冒险的条件下,后继的3条指令被连续执行,而不发生转移冒险塞。
(2)第一实施例中生成的子程序调用指令,是一条把分配堆栈和保存寄存器的两个操作伴随进行的指令,但绝不只限于这两个处理必须伴随进行的指令。例如,在转移到不必保留寄存器的子程序时,如同Call _g,#16那样,也可以生成只对堆栈进行分配的控制转移指令。
(3)第1实施例中的机器语言指令生成部104也可置换为将程序变换为可重定位的目标程序的通常的编译装置,此外连接部具有的链接功能,也可置换为连接可重定位的目标程序、并作成可执行目标程序的一般性的连接装置。这样一来,对应于第1实施例的程序变换装置,可以实现C语言的编译程序。
(4)在第1实施例中,只由连接部108生成子程序调用指令,但并不限于这样的构成。例如翻译部103进而可配备连接部108所具有的构成部109~112。这样一来,如果是同一文件中的子程序调用指令,就可以由翻译部103来生成子程序调用指令。
(5)在第2实施例中,子程序调用执行部件703a,将单一的子程序调用指令Call _g,#16,r1,r2,分解为一连串的4个指令来执行,毫无疑问,这是由处理器内部所具有但未予图示出来的微程序及布线逻辑等来实现的。
(6)在第2实施例中,避免了控制转移指令jsr所引起的2个时钟周期的流水线停顿,但绝不仅限于这样的流水线停顿。例如,由于存储有子程序_g的ROM的存取时间很长,在图12的流水线流程中产生了3个时钟周期的流水线停顿,按照本实施例可知,与图13中所示的流水线流程相同的结果可被得到。这时,比执行图12中所示的指令序列可以减少3个时钟周期的执行时间。也就是说,按照本实施例,不仅可以避免与执行控制转移指令时伴随产生的流水线停顿,而且也可避免在取出控制转移指令时的冒险而伴随发生的流水线停顿。