图4是编译程序的构成图。如图4所示,编译程序由句法分析装置11,优化装置12,资源分配装置13和代码生成装置14所构成。
句法分析装置11对存储器(未示出)中作为文件存储的源程序,进行词汇分析、语法分析和语意分析,并将源程序变换为中间目标程序。
优化装置12为了减少最终生成的汇编程序的程序长度、以及为了加快处理速度,对中间目标程序进行优化,在该优化过程中,包括着基本分块操作、控制流分析、数据流分析等作业。此处的基本分块操作,就是将作为处理对象的中间目标程序分解为若干基本块。
现在对该分块处理作一简单说明。首先,优化装置12检测中间目标程序的最初的中间指令、无条件或条件转移目标的中间指令、以及紧接着无条件或条件转移目标的中间指令,并把这些检测出的中间指令看作前导。进而,优化装置12,从前导开始,直到碰到下一个前导之前,或者是直到程序的最后,把一系列的中间指令抽出。由这一处理过程所得到的指令序列,就称作基本块,作为下一步处理的单位。
所谓控制流分析,就是对各基本块间的控制流进行分析。
所谓数据流分析,就是对各基本块中的每一变量,分析它在何处定义,在何处被引用。通过参照这些分析结果,就可以得到变量的生存期间的信息。
资源分配装置13,为了使得适应目标机器的处理器指令集,将中间程序中的变量分配到目标机器的处理器中所拥有的寄存器或者存储器。在进行这一资源分配时,对各变量的生存期间怎样进行重迭进行调整,对于这些重迭的变量,给它们分配不同的寄存器。此外,资源分配装置13,对各变量的嵌套层数到底有多少层,或者各变量的使用频度到底有多大等进行调查,根据调查结果,给各变量分配优先级。并且按优先级的顺序来分配寄存器。最后,对没有分配到寄存器的变量,将它们分配到内存中。
代码生成装置14,包括有生成代码改写装置,把中间目标程序内的各中间指令转换为机器指令,从而将中间目标程序变换为目标机器可执行的汇编程序。此处所指源程序和汇编程序,参照图5加以说明。图5是源程序和根据源程序而产生的汇编程序的对应关系示意图。在图5(a)中,main( ),f1( ),f2( ),f3( )分别表示函数。此外,本图中“main( ){ }”中的“f1(1);”表示以参数1来调用函数的指令。另外,在“main( ){ }”中的“f3(2);”表示以参数2来调用函数的指令。
关于源程序和汇编程序的对应关系,参照图5(b)来加以说明。本图中从“mov #1,D0”“jsr_f1”“mov #2,D0”起,直到“rst”的指令为止之间的指令,本图中以符号“}”来与main函数对应。此处的main函数,本图中由“mov #1,D0”-“rst”之间的指令构成。
此外,从指令“mov #1,D1”“add D1,D0”起到“rts”之间的指令,本图中以符号“}”来与函数f1相对应。本图中表示了函数f1是由“mov #1,D1”-“rts”之间的指令构成。
进而,本图中从“mov #3,D1”“mul D0,D1”起至“rts”止的指令,以符号“}”与函数f2相对应。本图中表示出函数f2由“mov#3,D1”-“rts”之间的指令构成。
此外,本图中的源代码与汇编程序码之间相互对应的部分,在它们之间以“{”标记之。也就是说,对图中的函数调用指令“f(1);”,用符号“{”来与“mov #1,D0”“jsr_f1”相对应。这样一来,从源程序中的函数调用指令“f(1)”的代码,生成了“mov #1,D0”也就是将立即值1送入寄存器D0的指令以及“jsr_f1”亦即函数调用指令。
此外,图中的函数调用指令“f3(2)”,用“{”来表示它与“mov#2,D0”“jsr_f3”的对应关系。这也就是说,从源程序中的函数调用指令“f3(2);”生成了“mov #2,D0”也就是将立即数传送给寄存器D0的传送指令以及“jsr_f3”亦即函数调用指令。
进而,图中的乘法指令“b=a*3”,用“{”来与“mov #3,D1”“mul D0,D1”相对应。这意味着从源程序中的乘法命令“b=a*3”,生成了“mov #3,D1”也就是将立即数3送入寄存器D1的指令以及“mul D0,D1”亦即乘法指令。
此外,本图中,寄存器D0、D1全都是16位长的寄存器。进而,也指明了本图中的指令“add D1,D0”“mul D1,D0”“mulD0,D1”“add D0,D1”这样的指令,都是将16位长的运算结果存入16位长的寄存器中。这是因为本编译程序以字长16位的处理器为对象,此外,上述规格基本上是根据运算结果和运算内容是以同一长度进行处理的这一语法规定来执行的。
其次,用图6来说明本实施例的信息处理装置的指令的一部分格式。图6就是表示本实施例中的作为对象的字长16位的处理器的命令格式的示例。今参照本图,对上述处理器的指令格式加以说明。本图中Dn、Dm表示通用计算用寄存器。此外,用MR来表示既用于保存乘、除法运算的高位数据、又用来保存函数调用时的返回地址的返址/运算兼用寄存器。PC表示程序计数器的值。label(label可为任意名字)是标号名,#imm表示立即数。
jsr_f1:
这是函数调用指令。当取出了函数调用指令时,处理器的动作与现存技术所说明的基本上是一样的,但不同的是将函数调用指令的下一条指令的地址,保存到返址/运算兼用寄存器MR中。
rtsf:特殊返回指令
该指令就是实施例中的特殊返回指令。当取出特殊返回指令时处理器的动作与先有技术所说明的动作大体相同,所不同的是将返址/运算兼用寄存器MR中所保存的返回地址,送入程序计数器中。
add Dn,Dm:
该指令是加法指令,当取出此指令时,处理器将Dn和Dm之值相加,并将其和存入寄存器Dm中。
mov Dn,Dm:
这是传送指令,当取出本指令时,处理器将寄存器Dn中的数据传送到寄存器Dm中。
mov # imm,Dm:
本指令是把立即数作为操作数的传送指令,当取出本指令时,处理器将立即数(#imm)送入寄存器Dm中。
mul Dn,Dm:
这是一条乘法指令,当取出此指令时,寄存器Dn和寄存器Dm相乘,积的高位数据存放到返址/运算兼用寄存器MR中,低位数据存放到寄存器Dm中。
图7是生成代码改写装置的示意图。
生成代码改写装置由控制部101、函数检测部102、返址/运算兼用保持状态检测部103和特殊返回指令输出部104组成。
控制部101对函数检出部102,返址/运算兼用保持状态检测部103、特殊返回指令输出部104加以控制,使它们按顺序起动。
函数检测部102检出程序中设有函数调用指令的函数。
返址/运算兼用保持状态检测部103,检测下述指令,包括往运算用寄存器MR存放高位结果数据的乘法指令、除法指令、求余指令或往运算用寄存器MR中传送的传送指令,并对前述函数检测部102所检测出的函数中是否改变过返址/运算兼用寄存器的值加以确认。此外,返址/运算兼用保持状态检测部103之所以能够进行这样的确认,是因为对上述的返址/运算兼用寄存器的状态进行判断,看是否可能将它作为返回地址的保存区。
特殊返回指令输出部104把前述函数检测部102检出的函数末尾的返回指令改写为特殊返回指令。
如上那样构成的生成代码改写装置,将代码生成装置14生成的汇编语言程序进行改写的情形,以图8和图9的程序为例,参照图10的流程图进行说明。
图8表示图5(b)中的汇编语言程序的各指令被存储到相应的存储器上各存储地址的状态。
按图8的状态,函数检测部102首先检测出了表示函数main的起始位置的_main标号(步51)。检出后,顺序检索汇编程序标号_main以后所排列的指令,亦即函数_main中的指令,以判定函数main内部是否存在函数调用指令。由于函数main中存在有函数调用指令“jsr_f1”、“jsr_f3”(步2),因此,检出这些函数调用指令,检索到此处暂停,继之,对函数f1的内部进行检索(步S1,S2)。函数检测部102检索函数f1所在的相对地址0105~0108中的各指令,进一步判定函数f1中是否存在函数调用指令(步S2)。因为在函数f1中存在有对函数f2的函数调用指令“jsr_f2”,因此,检索到此暂停,转去检索下一函数f2(步S1)。函数检测部102,继续检索函数f2内部的相对地址0109~010C内的各指令,以判断是否存在函数调用指令(步S2)。在这情形,因为函数f2中已没有函数调用指令,因此起动返址/运算兼用保持状态检测部103。
返址/运算兼用保持状态检测部103对函数f2内的相对地址0109~010C中的指令进行检索,判断在函数f2内部,返址/运算兼用寄存器的值是否已被改变(步3),也就是判定“mul Dn,Dm”等将返址/运算兼用寄存器用来存放运算结果的这类运算是否存在于函数f2中。由于函数f2中,存在有“mul D0,D1”这样的把运算结果保存到返址/运算兼用寄存器的指令,检索到此暂停,转去检索下一函数f3(步S1)。
函数检测部102顺序检索函数f3内相对地址010d~010f之间的指令,判断该函数f3内是否存在函数调用指令。
在函数f3中,并未发现“jsr”这样的操作码,因为没有函数调用(步S2),就起动返址/运算兼用保持状态检测部103,对函数f3内的指令,即相对地址为010d~010f之间的指令进行检索,确认了在函数f3内并不存在有把返址/运算兼用寄存器用来保存运算结果的指令。因为函数f3中没有这样的指令存在,返址/运算兼用保持状态检测部103便起动特殊返回指令输出部104(步S4),被起动的特殊返回指令输出部104便把函数f3末尾部分的指令(ex16)改写为特殊返回指令rtsf(ex16′)。上述一系列处理的结果,图8中的汇编程序,就变成了图9左半部的状态。
下面利用图示,就本发明的一个实施例中的处理器的内部结构加以说明。
图11是本实施例中的处理器的结构图。如本图所示,处理器由下述部分组成,它们包括指令缓冲器(图中略记为IB)32,选择器34,指令寄存器(图中略记为IR)35,数据寄存器组41,地址寄存器组42,选择器43,堆栈指针44,ALU 51,选择器54和55,返址/运算兼用寄存器(MR)56,移位寄存器(图中略记为SFT)57,选择器58,移位寄存器(图中略记为SFTMD)59,程序计数器61,指令地址缓冲器(图中略记为IAB)66,选择器67,指令缓冲器(图中略记为IFB)73,操作码地址缓冲器(图中略记为OAB)74,存储缓冲器(图中略记为STB)75,加载缓冲器(图中略记为LDB)76等所构成,它们之间通过总线(图中略记为ABUS)、第1数据总线(图中略记为B1BUS),第2数据总线(图中略记为B2BUS),LDBUS,指令总线(图中略记为IBUS)等相互连接,如图中所示。
指令缓冲器(以后略记为IB)32,长度为8位,是一个三段缓冲器,在指令被执行之前,预先从内存中取出,并储存到该指令缓冲器中。例如在该IB 32中,如前所述的“jsr_f1”等函数调用指令、“mul D0,D1”等乘法指令,或多或少地以机器语言的状态存储到该缓冲器中。
选择器34,选择从IB32输入的指令或从IBUS上输入的指令中的某一个。
指令寄存器(以下略记为IR)35,保存从选择器34中所输出的指令。
数据寄存器组41,主要用来保存数据,它的长度为16位,共4个寄存器。
地址寄存器组42,主要用来保存地址,它的长度为16位,共4个寄存器。
选择器43,从ABUS和LDB76之间,选择性地向数据寄存器组41、地址寄存器组42以及堆栈指针44输出。
堆栈指针44,保持有内存RAM78中作为堆栈用的区域的首地址。
ALU 51进行16位长的数据的运算和地址运算。
选择器54、55选择应当输入到ALU中的操作数。
返址/运算兼用寄存器MR 56,是保持乘除运算结果或除法运算结果的高位字节、保存求余运算结果的余数的16位长的寄存器。此外,它也用来保存函数的返回地址。
此外,如果本发明的处理器对C语言编译器编译得到的机器语言程序进行操作,该返址/运算兼用寄存器56的使用频度很低。为什么呢?因为按C语言的一般规定,原则上“16位长的运算结果是16位长,32位长的运算结果是32位长”,运算对象和运算结果按语法规定应有相同的长度,此外,因为上述数据寄存器、地址寄存器、数据总线、地址总线均为16位长,编译程序将乘法的运算结果化为16位,从而生成机器语言程序。又,在本实施例中,以16位长为前提加以说明,当然对其它的长度也是适用的。
移位寄存器(以下略记为SFT)57在接受了ALU 51的输出时,进行移位操作。当移位结束后,SFT 57保存运算结果的高位字节。另外在ALU 51进行除法运算时,SFT 57保存计算结果的商。
选择器58,用来选择ABUS上的数据或者SFTMD 59上的数据。
移位寄存器(从下略记为SFTMD)59,在接受了选择器58的输出时,与ALU 51一起进行移位操作,当移位结束后,SFTMD59保存计算结果低位数据。此外,ALU 51在进行除法运算时,SFT 57保存其计算结果。
程序计数器61,由预取计数缓冲器(图中略记为PFCB,以后,用此略称)62,选择器63,程序计数缓冲器(图中略记为PCB,以后用此略称)64,选择器67构成。
PFC 62是一个16位长的寄存器,它保存有预取指令的地址。
程序计数缓冲器PCB 64,是一个16位长的寄存器,经常保持PFCB 62的一个时钟周期之后的值。
选择器63,用来在PCB 64和PFCB 62之间进行选择数据,并将之输出到ABUS或B1BUS上。
指令地址缓冲器(图中略记为IAB,以后使用这一略称)66,将应当取出的指令的地址发送到地址总线。
指令缓冲器(图中,略记为IFB,今后使用这一略称)73,操作数地址缓冲器(图中记为OAB,以后用此略称)74,存储缓冲器(图中略记为SB,以后用此略称)75,装入缓冲器(图中略记为LB,以后用此略称)76分别是为保存指令、保存操作数地址、保存存储数据或保存装入数据的缓冲器。
RAM 78及ROM 79分别用来保存数据和指令。
ABUS与堆栈指针44,数据寄存器组41、地址寄存器组42、SFTMD 59、选择器63、返址/运算兼用寄存器56、LDB 76、ALU51以及SFT 57的输出端相连接,根据这样的选择关系,可以知道堆栈指针44、数据寄存器组41、地址寄存器组42的值,是通过ABUS而发送给ALU 51的。此外,也可知道返址/运算兼用寄存器56的值,亦即状态返回时的返回地址,也是通过ABUS而传送给ALU 51的。更进一步还可明白,SFT 57和SFTMD 59中所保存的乘积,也是通过这个ABUS和选择器43,而传送给返址/运算兼用寄存器56及数据寄存器组42的。
B1BUS与选择器63、堆栈指针44、地址寄存器组42的输出端相连接,与选择器54的输入端相连接。根据这样的连接关系可知,选择器63对PFCB 62或PCB 64进行选择,并将被选择的值通过B1BUS传送给ALU 51。
B2BUS与IB 32,返址/运算兼用寄存器56,数据寄存器组41,LDB 76的输出端相连接,也与选择器54,选择器55以及LDB 76的输入端相连接。根据这样的连接关系可知,IB 32中保存的指令的一部分,例如jsr@(disp,pc)的disp等,经由这个B2BUS,传送给ALU 51。
参照对上述方式构成的处理器,说明在图6中所示的各指令的执行情况。
首先说明函数调用指令(jsr)执行时的动作。
在图6所示的jsr指令的(1)的动作如下,通过将堆栈指针44的值,传送到ALU 51中,计算SP-2之值并送入SP,从ALU51下方的黑点111,其右边的黑点112起,经由指向ABUS的总线,从ABUS起经由选择器43,传送计算结果到堆栈指针44。
图6中jsr指令的(2)所示的动作如下:
通过OAB 74,将堆栈指针44的值传送到地址总线,根据选择器63对PCB 64进行选择和输出,将PCB 64的值(根据INC65递增之后的下一指令的地址),经由STB 75,保存到存储器78中的由堆栈指针44所指示的位置。换言之,将返回地址压入堆栈。
图6中jsr指令(3)所示动作如下:
选择器63选择PCB 64的值,而PCB的值(下一指令的地址)经由其上的黑点114起,到其右边的黑点115,再经过选择器63,ABUS之后,传送到返址/运算兼用寄存器56中。
图6中jsr指令(4)所示的动作如下:
选择器63选择PFCB 62,PFCB 62(PC)的值,通过选择器63,从B1BUS送入ALU 51中。IB 32中所存储着的程序计数器PC的相对地址(disp)通过B2BUS送入ALU 51中。ALU 51计算出的跳转目的地址(PC+disp)从ALU 51设置到IAB 66和PCB 64中。设定之后,IB 32中的指令全被清除。
图6中rts指令(1)所示的执行动作如下:
DEC 80对返回指令译码之后,将堆栈指针44的值SP经由ALU 51以及通过ALU 51下方的黑色圆点111,以及其右的黑圆点112,从OAB 74,送入地址总线。从而,在RAM 78中的堆栈内所保存的返回地址,经过RAM 78一侧的数据总线、LDB76,从ABUS起,经由ALU 51,选择器67,被传送到PCB 64中。此外,还同时将返回地址传送给IAB 66,并随即将IB 32中的指令全部清除。
图6所示的rts指令(2)中的动作如下:当图6(1)的动作完成之后,接着根据堆栈指针44将其值SP,经由ABUS,传送到ALU51中,并计算SP+2。计算结果经过ALU 51下方的黑色圆点111、它的右边的黑圆点112,并通过从该处指向ABUS的总线,经过ABUS转向右方,再通过其上方的选择器43,被传送到栈指针44中。
图6中的特殊返回指令rtsf的(1)的动作如下:当DEC 80对返回指令(rtsf指令)译码之后,在返址/运算兼用寄存器56中所保存的返回地址,被送到ABUS上,从ABUS起,经选择器67,送入PCB 64的同时,返回地址也被传送到IAB 66中,处理控制转移到返回地址。与此同时,IB 32中的所有指令均被清除。
图6中的rtsf指令(2)的动作如下:在完成了上述(1)的动作之后,栈指针44的值经由ABUS被送到ALU 51中,在ALU 51中计算SP+2,计算的结果经ALU 51下方的黑圆点111,其右边的黑圆点112,通过从该处指向ABUS的总线,经由ABUS向右,再通过其上方的选择器43,传送到栈指针44中。
乘法指令执行时的动作如下:当DEC 80对乘法指令mul译码之后,寄存器Dn(乘数)的值被送到B2BUS上,并到达ALU51中,此外,寄存器Dm(被乘数)的值被送到B1BUS上,然后进入ALU 51中。ALU 51将乘数和被乘数相乘,其积的低位字节经过SFTMD 59移位,而高位字节被保存到SFT 57中。在SFT 57中所保存的乘积的高位字节,经过ALU 51的下方的黑圆点111,其右边的黑圆点112,被送到ABUS上,从而传送给返址/运算兼用寄存器56。而SFT 57中所保存的乘积低位字节,从SFTMD 59经过ABUS,再经过上方的选择器43,被送入寄存器DR之中。
其次,再对函数调用以及从被调用函数的状态返回的过程加以说明。图12中将处理器的处理过程用流程图来表示。图9中表示出了由生成代码改写装置改写之后的程序。本图中左侧的箭头表示了本程序中的执行顺序是怎样改变的。此外,右侧的标有stage1,stage2,stage3等字串的矩形,模拟为堆栈及返址/运算兼用寄存器56,其内的数值“0102”、“0104”,表示执行函数调用时在其内所保存的返回地址。下面,参照这些图,对前述结构的处理器进行函数调用和状态返回时的过程加以说明。
先对程序计数器的设定和指令的取出加以说明。当处理器起动之后,程序首址被置入PCB 64中,同时也设定到IAB 66中。在IAB 66中所设定的程序首地址被送到地址总线上。
程序计数器61内的程序计数器缓冲器PCB 64的值,通过INC 65,将地址每两个字节或者一个字节进行递增。将递增的结果重新去设定PCB 64,同时,设定到IAB 66中。与此同时,将递增之前PCB 64之值被传送到PFCB 62中,这样一来,程序计数器缓冲器PCB 64的值便通过INC 55,就使程序计数器的值不断更新,因而不断读入ROM 79中的机器语言程序。
当程序未开始执行或者在执行函数调用的分枝指令而IB 32为空时,指令的第一个字节从IBUS直接保存到IR 35中。因为地址总线、数据总线都是16位,而IB 32的宽是8位,每当程序计数器PC的值PCB每递增1,则一个字节长的指令便被保存到IB 32中。此外,每当程序计数器PC的值PCB被递增2时,2个字节长的指令便被保存到IB 32中(步t2)。IB 32内所保存的指令之中,其开始的部分被传送到IR 35中。在IR 35中所设置上的指令,进而被传送到DEC 80中,根据这样的传送,在DEC 80中对该指令进行译码。另一方面,在IB 32中保存的指令,以先进先出(FIFO)方式,顺次传送到IR 35之中。
此处,当设有指令的地址被送到地址总线上时,也就是没有指令存在的地址被设定到PCB 64或IAB 66时,或者是读入了表示程序结束的指令时,就认为是程序的结束,从而终止处理(步t1)。
指令“mov #1,D1”的执行过程如下:当程序开始执行后,程序的首地址0100被设定到了PCB 64和IAB 66中。被设定的IAB 66的值0100被送到地址总线上,从而取得了相对地址0100的指令“mov #1,D1”。并且,判断所取出的指令是否是函数调用指令(步t3)。因为相对地址0100的指令“mov #1,D0”是将立即数#1传送到寄存器D0的传送指令而不是函数调用指令,所以,要判断指令“mov #1,D0”是否为特殊返回指令(步t4)。由于“mov #1,D0”不是特殊返回指令,因此执行该指令(步t5)。执行后PCB 64的值增加到0101,将下一条指令,即相对地址0101的函数调用指令“jsr_f1”取出(步t2)。
相对地址0101的函数调用指令的执行过程如下:当取出了“jsr_f1”之后,IB 32中填入“jsr_f1”的3字节长的机器语言代码。这时IB 32的内容为:第一字节存放jsr指令(1字节长)的操作码,第二字节存放转移目标地址(或者PCB 64中的相对地址disp(位移))的低位字节,第三字节存放转移目标地址(或PCB 64中的相对地址(disp:即位移))的高位字节。这样一来,对DEC 80而言,jsr指令的操作码被传送到了DEC 80中。传送后,DEC 80要判断从IB 32传送过来的指令是否为函数调用指令(步t3)。由于相对地址0101的指令“jsr_f1”是一函数调用指令,因而将栈指针44的值传送到ALU 51中,在ALU 51中,根据栈指针44的SP,计算SP-2,其结果再送回栈指针44中。
继而,将栈指针44的值SP,送到地址总线上,使之指向存储器78内的区域。在该指示的区域内把PCB 64中的下一条指令的地址保存起来。因此,返回地址便被压入堆栈(步t6)。
接着,将PCB 64的值(下一条指令的地址)向返址/运算兼用寄存器56传送,保存到返址/运算兼用寄存器56中。作为其结果,堆栈和返址/运算兼用寄存器56中的存储状态如图9的stage1所示。
当DEC 80对IR 35中的1字节长的jsr指令进行译码时,IB 32中保存着jsr指令的2个字节的跳转地址。接着使用保存在此IB 32中的值与指令计数器PC的值来计算跳转地址,并将该地址设定到PCB 64和IAB 66中。这样一来,由于设定了跳转地址,因而便进行了函数调用。设定之后,由于IB 32中函数调用指令之后所列的指令已不起作用,因此将它们清除掉(步t7)。
函数f1及f2内的处理过程如下:当控制转移到函数f1之后,将函数f1中相对地址0105的指令“mov #1,D1”和相对地址0106的“add D0,D1”顺次取出和执行(步t1~t5)。跟随这些指令之后的相对地址0107的指令“jsr_f2”也被取出(步t2),并判断其是否函数调用指令(步t3)。因为该指令为函数调用指令,因而将其指令之后的下一指令的地址,即相对地址0108(PC+1=0107+1=0108)作为返回地址压入堆栈中(步t6),更进一步,将返回地址0108存放到返址/运算兼用寄存器56中。其结果,堆栈及返址/运算兼用寄存器56的存储状态如图9的Stage3所示,也就是说,返回地址被压入堆栈中,而返址/运算兼用寄存器56中保存的值,是用返回地址0108来更新过的值。当保存了返回地址0108之后,计算跳转地址(PC+disp(位移=0002))之值,并将计算结果传送到程序计数器61中(步t7)。
由于这样地将跳转地址(函数f2的首地址0109)传送到PC中,因此控制转移到函数f2。控制转移后,顺次取出相对地址0109,相对地址010a,010b,010c...的指令并予执行(步t1~t5)。取出相对地址0109的指令“mov #3,D1”并执行之后,又取出相对地址010a的指令“mul D0,D1”,将其交给DEC 80。DEC80将其译码为一乘法指令(mul指令),就将寄存器Dn(乘数之值送到B2BUS之上,进入ALU 51中。此外,寄存器Dm(被乘数)之值被送到B1BUS上,进入ALU 51中,ALU 51将乘数和被乘数相乘,将乘积的低位字节在SFTMD 59中移位,高位字节被存储到SFT 57中。保存在SFT 57中的乘积的高位字节,经由ALU51下面的黑圆点111,右边的黑圆点112,送到ABUS上,传送到返址/运算兼用寄存器56中。保存在SFT 57中的乘积的低位字节则从SFTMD 59,经由ABUS,并通过上方的选择器43,传送到寄存器DR之中。这样一来,当执行了乘法指令之后,返址/运算兼用寄存器56变为保存乘积的高位字节的状态。其结果,堆栈及返址/运算兼用寄存器56的存储状态变为如图9的Stage5所示的状态。也就是说,返回地址0108被保存在堆栈中,而返址/运算兼用寄存器56中所保存的值,被乘积结果所改写。
继而取出相对地址010b中的指令“add D0,D1”,执行该指令后,取出相对地址010c的指令(步t1,t2)。
相对地址010c中的rts指令的执行过程如下:这时,堆栈变为stage6的状态,因为取出的相对地址010c中的指令为返回指令“rts”,因而堆栈指针44的值SP经由ALU 51,再经过ALU51下面的黑圆点111,以及其右边的黑圆点112,从OAB 74送到地址总线上。据此,在RAM 78中的堆栈中所保存的返回地址0108,经由RAM 78一侧的数据总线、LDB 76、从ABUS起,经过ALU 51,选择器67,传送并保存到PCB 64中。与此同时,返回地址0108被传送到IAB 66中。在这样的传送之后,因为在IB32中的rts指令之后所列的一连串指令已无作用,因而将它们清除。并且,这样的传送过程,在图9中的stage6中,以箭头←加以表示。
清除完成后,堆栈指针44的值SP,经由ABUS,被传送到ALU 51中,并计算SP+2。计算的结果经过ALU 51下方的黑圆点111,其右边的黑圆点112,通过从该处指向ABUS的总线,经由ABUS,转向右方,再通过其上的选择器43,传送到栈指针44中。这样一来,从函数f2的处理返回,在下一步中,读出相对地址0108中的指令。
从相对地址0108的返回指令“rts”起,到相对地址010e的指令“add D0,D1”止的动作过程如下:因为相对地址0108的指令是返回指令“rts”,因而再次存取堆栈,从堆栈中取出返回地址0102,被取出的返回地址0102被传送到程序计数器61中(步t3,t4,t5)(图9的stage4)。
传送后,取出相对地址0102中的指令并予执行(步t1~t5)。
相对地址0102的指令被执行后,取出相对地址0103的指令。因为相对地址0103的指令是函数调用指令“jsr_f3”,因而下一条指令的地址,也就是相对地址0104被作为返回地址存放到堆栈和返址/运算兼用寄存器56中(stage2),计算转移目标地址(PC+disp),控制向函数_f3转移(步t6、t7)。由于控制的转移,取出相对地址010d的指令“mov #1,D1”,相对地址010e的指令“add D0,D1”,顺次执行之(步t1~t5)。接着取出相对地址010f的指令。
特殊返回指令(rtsf指令)的执行过程如下:DEC 80对相对地址010f的rtsf指令进行译码,返址/运算兼用寄存器56中所保存的返回地址0104被送到ABUS上,从ABUS经由ALU 51,选择器67传送到PCB 64中。与此同时,返回地址0104被传送到IAB 66中。这时的返址/运算兼用寄存器56的状况如图9的stage7所示。也就是说,返址/运算兼用寄存器56中保存的值被改写为0104。由于这样的传送,完成了从子程序到函数main的状态返回。在这样的处理之后,IB 32中的rtsf指令之后所列的一连串指令已没有作用,将它们予以清除。
此后,栈指针44的值SP经由ABUS,传送到ALU 51,由ALU 51计算SP+2之值,计算结果经由ALU 51之下的黑圆点111,右方的黑圆点112,并通过从该处指向ABUS的总线,再经由ABUS转向右方,通过上述的选择器43,传送到栈指针44中。这一状态在图9的Stage7,由箭头←进行表示。也就是利用从返址/运算兼用寄存器56向程序计数器PC传送返回地址,便可知道已完成了状态恢复。
如上所述,按本实施例,即使不设置保存返回地址的专用寄存器,也可以减少为进行状态恢复而对堆栈的存取次数。
此外,在不脱离本实施例的主旨的范围内,也可以变更实施。
本实施例中,运算结果的保存、返回地址的保存均由保存乘法、除法、求余运算结果高位数据的寄存器(返址/运算兼用寄存器)来担当,当然也可以用其它的寄存器来担当。
例如,可由为保存加法、减法、移位运算运算结果高位数据而设的寄存器来担当。
此外,即使没有返址/运算兼用寄存器,也可以用其它使用频度比较低的寄存器。也就是说,也可以用处理器中为保存超过运算器长度的运算的运算结果而设置的寄存器。例如,本实施例中,ALU 51的运算长度为16位,在处理器中超过这一长度的运算,也就是说,在运算长度为16位的ALU中,如果设置有为保存32位长、64位长运算的运算结果的寄存器时,大体来说,这样的寄存器的使用频度较低,因而也可使用。
更进一步,不一定非用保存运算结果高位数据的寄存器,也可以使用保存运算结果的低位数据而设置的寄存器来保存返回地址。
此外,本实施例中,返址/运算兼用寄存器只有一段,把它设置为3段、4段,使其能保存3、4个以上的返回地址也可以。这时,若返址/运算兼用寄存器若为3段,便可保存3个返回地址,如果返址/运算兼用寄存器设为4段,则可保存4个返回地址。为此,生成代码改写装置,可检测出嵌套层数小于返址/运算兼用寄存器的段数的所有函数,并将被测检出的函数中的返回指令改写为特殊返回指令。
这样一来,由于生成代码改写装置进行改写,就可以将多个返回地址保存到返址/运算兼用寄存器中。
更进一步,在本实施例中,由代码生成装置生成汇编程序之后,返回指令被改写为特殊返回指令,例如,可以如以下(a)、(b)所示那样进行变更实施。
(a)最优化装置可利用一个标志,当该标志为ON时,表示可以输出,当为OFF时,表示不能输出,将这样的标志对应于中间目标语言状态的各个函数进行记忆。然后,从中间语言程序状态的程序中,检测出可以输出特殊返回指令的所有函数,对于这些被检出的函数,将表示可以输出特殊返回指令的标志置为ON,而对未检出的函数,该标志位置为OFF。
包括有上述处理的最优化装置的处理结束后,代码生成装置参照这些标志,对于标志为ON的函数,生成一个末尾为一条rtsf指令的子程序,对于标志为OFF的函数,生成末尾为一条rts的指令。
(b)在中间语言状态中,最优化装置检测出中间语言状态的函数中可以输出特殊返回指令的函数,在被检测出的函数末尾可以写入一条表示可以输出特殊返回指令的中间语言指令。
从而,代码生成装置对末尾存在有表示可以输出特殊返回指令的中间语言指令的那些函数,生成一个末尾为rtsf指令的子程序。
对那些末尾不存在用来表示可以输出特殊返回指令的中间语言指令的那些函数,生成一个末尾为rts指令的子程序。