(57)【要約】【課題】リーフ関数の実行時にスタックへのアクセス回数を減らすことができるプロセッサを提供すること。【解決手段】本発明は、汎用レジスタと、リーフ関数用レジスタと、リーフ関数呼び出し命令が入力されると、スタックポインタをリーフ関数用レジスタにコピーするスタックポインタ退避手段と、プログラムカウンタの次のアドレスを、リーフ関数用レジスタに記憶するプログラムカウンタ退避手段と、使用するレジスタを汎用レジスタからリーフ関数用レジスタに切り替え、リーフ関数戻り命令が入力されると、使用するレジスタをリーフ関数用レジスタから汎用レジスタに切り替えるレジスタ切り替え手段と、リーフ関数戻り命令が入力されると、リーフ関数用レジスタにおけるプログラムカウンタに対応する領域に記憶されたアドレスを、プログラムカウンタにコピーするプログラムカウンタ復帰手段とを有するプロセッサを提供する。【選択図】図１
2007219938.tif 000002
【特許請求の範囲】
【請求項１】
メモリに記憶され、各々前記メモリ内のアドレスに対応する複数の命令からなるプログラムを実行するプロセッサであって、
入力された命令に従って演算処理を行う演算部と、
前記プロセッサが実行すべき命令のアドレスを記憶するプログラムカウンタと、前記プロセッサと異なる装置に設けられた記憶領域であるスタックのアドレスを記憶するスタックポインタと、前記演算処理に必要な情報とを記憶する汎用レジスタと、
少なくとも前記プログラムカウンタおよび前記スタックポインタに対応する記憶領域を有するリーフ関数用レジスタと、
リーフ関数呼び出し命令が入力されると、前記スタックポインタの記憶内容を前記リーフ関数用レジスタの対応する領域にコピーするスタックポインタ退避手段と、
リーフ関数呼び出し命令が入力されると、前記プログラムカウンタに記憶されたアドレスの次のアドレスを、前記リーフ関数用レジスタの対応する領域に記憶するプログラムカウンタ退避手段と、
リーフ関数呼び出し命令が入力されると、前記演算部が演算処理に使用するレジスタのうちプログラムカウンタおよびスタックポインタを、前記汎用レジスタから前記リーフ関数用レジスタに切り替え、リーフ関数戻り命令が入力されると、前記演算部が演算処理に使用するレジスタのうちプログラムカウンタおよびスタックポインタを、前記リーフ関数用レジスタから前記汎用レジスタに切り替えるレジスタ切り替え手段と、
リーフ関数戻り命令が入力されると、前記リーフ関数用レジスタにおける前記プログラムカウンタに対応する領域に記憶されたアドレスを、前記プログラムカウンタにコピーするプログラムカウンタ復帰手段と
を有するプロセッサ。
【請求項２】
前記リーフ関数用レジスタが、前記汎用レジスタと同一の大きさおよび数の記憶領域を有し、
前記レジスタ切り替え手段が、リーフ関数呼び出し命令が入力されると、前記演算部が演算処理に使用するレジスタを前記汎用レジスタから前記リーフ関数用レジスタに切り替え、リーフ関数戻り命令が入力されると、前記演算部が演算処理に使用するレジスタを前記リーフ関数用レジスタから前記汎用レジスタに切り替え、
前記プロセッサが、リーフ関数戻り命令が入力されると、前記リーフ関数用レジスタに記憶されたリーフ関数の戻り値を、前記汎用レジスタの対応する記憶領域にコピーする戻り値復帰手段をさらに有する
ことを特徴とする請求項１に記載のプロセッサ。
【請求項３】
前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示すフラグを記憶するフラグレジスタと、
前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であるか判断する呼び出し命令判断手段と、
前記呼び出し命令判断手段が、前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であると判断した場合、かつ、前記フラグレジスタに記憶されたフラグが前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示す場合、フェッチされた命令をリーフ関数呼び出し命令からリーフ関数以外の関数呼び出し命令に置換する命令置換手段と、
前記呼び出し命令判断手段が、前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であると判断した場合、かつ、前記フラグレジスタに記憶されたフラグが前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していないことを示す場合、前記フラグレジスタの内容を、前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示すものに書き換えるフラグセット手段と、
前記プロセッサによりフェッチされた命令がリーフ関数戻り命令である場合、前記フラグレジスタの内容を、前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していないことを示すものに書き換えるフラグクリア手段と
をさらに有する請求項１に記載のプロセッサ。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プロセッサの動作を高速化する技術に関する。
【背景技術】
【０００２】
ＣＰＵ（Central Processing Unit）などのプロセッサがプログラムを実行しているとき、ｃａｌｌ命令などで別の関数を呼び出して実行することがある。呼び出された関数の実行が完了した後、元の処理に戻るには、関数を呼び出す前に実行していた処理の続きの処理を特定するアドレスを記憶しておく必要がある。このため、ＲＡＭ（Random Access Memory）内にスタックと呼ばれる記憶領域が確保される。ＣＰＵは、スタックに、処理中のデータや戻りアドレスなどを一時的に記憶する。スタックはＣＰＵの外部に設けられるため、ＣＰＵ内部に設けられたレジスタと比較するとアクセス速度は遅い。このように、スタックへのアクセスは、ＣＰＵの高速化を阻害する要因となる。
【０００３】
以上の観点から、スタックへのアクセスを減らし、ＣＰＵの処理速度を向上させる種々の技術が開発されている。特に、いわゆる組み込み機器においては、処理速度を高速化するため、関数呼び出しの少ないプログラムを開発するという手法がとられている。また、例えば特許文献１は、複数のレジスタを有するプロセッサを開示している。
【特許文献１】特開平７−２１０３９８号公報
【発明の開示】
【発明が解決しようとする課題】
【０００４】
プログラムの中でも、ネストが最も深い位置にある、いわゆるリーフ関数と呼ばれる関数は、呼び出される回数が多い場合が多い。しかし、リーフ関数を呼び出す回数の少ないプログラムを開発することは困難である。そこで、リーフ関数の実行時にスタックへのアクセス回数を減らすことにより、ＣＰＵの処理速度を向上させることができると考えられる。しかし、特許文献１は、リーフ関数と他の関数を区別することができなかった。
【０００５】
本発明は上述の事情に鑑みてなされたものであり、リーフ関数の実行時にスタックへのアクセス回数を減らすことができるプロセッサを提供する。
【課題を解決するための手段】
【０００６】
上述の課題を解決するため、本発明は、メモリに記憶され、各々前記メモリ内のアドレスに対応する複数の命令からなるプログラムを実行するプロセッサであって、入力された命令に従って演算処理を行う演算部と、前記プロセッサが実行すべき命令のアドレスを記憶するプログラムカウンタと、前記プロセッサと異なる装置に設けられた記憶領域であるスタックのアドレスを記憶するスタックポインタと、前記演算処理に必要な情報とを記憶する汎用レジスタと、少なくとも前記プログラムカウンタおよび前記スタックポインタに対応する記憶領域を有するリーフ関数用レジスタと、リーフ関数呼び出し命令が入力されると、前記スタックポインタの記憶内容を前記リーフ関数用レジスタの対応する領域にコピーするスタックポインタ退避手段と、リーフ関数呼び出し命令が入力されると、前記プログラムカウンタに記憶されたアドレスの次のアドレスを、前記リーフ関数用レジスタの対応する領域に記憶するプログラムカウンタ退避手段と、リーフ関数呼び出し命令が入力されると、前記演算部が演算処理に使用するレジスタのうちプログラムカウンタおよびスタックポインタを、前記汎用レジスタから前記リーフ関数用レジスタに切り替え、リーフ関数戻り命令が入力されると、前記演算部が演算処理に使用するレジスタのうちプログラムカウンタおよびスタックポインタを、前記リーフ関数用レジスタから前記汎用レジスタに切り替えるレジスタ切り替え手段と、リーフ関数戻り命令が入力されると、前記リーフ関数用レジスタにおける前記プログラムカウンタに対応する領域に記憶されたアドレスを、前記プログラムカウンタにコピーするプログラムカウンタ復帰手段とを有するプロセッサを提供する。
このプロセッサによれば、リーフ関数を呼び出すときに、戻りアドレスはスタックではなくリーフ関数用レジスタに記憶される。また、リーフ関数から元の処理に戻るときには、戻りアドレスはリーフ関数用レジスタから読み出される。したがって、プロセッサと異なる装置に設けられたスタックへのアクセス頻度を低減することができる。また、このプロセッサによれば、その処理内容が同じである場合、通常関数（非リーフ関数）とリーフ関数との差は、関数呼び出し命令および関数からの戻り命令が異なるだけである。すなわち、このプロセッサによれば、コンパイラの設計が容易になる。
【０００７】
好ましい態様において、このプロセッサは、前記リーフ関数用レジスタが、前記汎用レジスタと同一の大きさおよび数の記憶領域を有し、前記レジスタ切り替え手段が、リーフ関数呼び出し命令が入力されると、前記演算部が演算処理に使用するレジスタを前記汎用レジスタから前記リーフ関数用レジスタに切り替え、リーフ関数戻り命令が入力されると、前記演算部が演算処理に使用するレジスタを前記リーフ関数用レジスタから前記汎用レジスタに切り替え、前記プロセッサが、リーフ関数戻り命令が入力されると、前記リーフ関数用レジスタに記憶されたリーフ関数の戻り値を、前記汎用レジスタの対応する記憶領域にコピーする戻り値復帰手段をさらに有してもよい。
【０００８】
別の好ましい態様において、このプロセッサは、前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示すフラグを記憶するフラグレジスタと、前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であるか判断する呼び出し命令判断手段と、前記呼び出し命令判断手段が、前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であると判断した場合、かつ、前記フラグレジスタに記憶されたフラグが前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示す場合、フェッチされた命令をリーフ関数呼び出し命令からリーフ関数以外の関数呼び出し命令に置換する命令置換手段と、前記呼び出し命令判断手段が、前記プロセッサによりフェッチされた命令がリーフ関数呼び出し命令であると判断した場合、かつ、前記フラグレジスタに記憶されたフラグが前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していないことを示す場合、前記フラグレジスタの内容を、前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していることを示すものに書き換えるフラグセット手段と、前記プロセッサによりフェッチされた命令がリーフ関数戻り命令である場合、前記フラグレジスタの内容を、前記プロセッサがリーフ関数呼び出し命令とリーフ関数戻り命令の間の命令を実行していないことを示すものに書き換えるフラグクリア手段とをさらに有してもよい。
この態様のプロセッサによれば、割り込み処理などにより、リーフ関数の実行中にさらにリーフ関数呼び出し命令がフェッチされた場合には、リーフ関数呼び出し命令はリーフ関数以外の関数呼び出し命令に置換される。したがって、割り込み処理においてリーフ関数用レジスタが使用されることはなく、２重にリーフ関数が呼び出されることによってリーフ関数用レジスタの内容が破壊されてしまうことを回避することができる。
【発明を実施するための最良の形態】
【０００９】
以下、図面を参照して本発明の一実施形態について説明する。
＜１．第１実施形態＞
図１は、本発明の第１実施形態に係るコンピュータシステム１の構成を示す図である。ＣＰＵ１００は、本実施形態に係るプロセッサである。ＲＯＭ（Read Only Memory）３００は、プログラムを記憶したメモリである。ＣＰＵ１００は、ＲＯＭ３００に記憶されたプログラムを読み出して実行する。ＲＯＭ３００は、複数の記憶領域を有する。各記憶領域にはアドレスが割り当てられている。プログラムは、複数の命令から構成される。各命令は、ＲＯＭ３００において一の記憶領域に記憶されている。すなわち、各命令とアドレスは対応する。ＲＡＭ２００は、ＣＰＵ１００がプログラムを実行する際の作業領域として機能するメモリである。ＣＰＵ１００、ＲＡＭ２００、およびＲＯＭ３００は、バス９００を介して接続されている。
【００１０】
ＣＰＵ１００は、さらに以下の構成を有している。演算ユニット１１０は、入力された命令に従って演算を行う。汎用レジスタ１３０は、プログラムカウンタと、スタックポインタと、演算処理に必要な情報とを記憶する記憶領域を有するレジスタである。プログラムカウンタは、ＣＰＵ１００が実行すべき命令のアドレスを記憶する。スタックポインタは、ＣＰＵ１００と異なる装置であるＲＡＭ２００内に設けられた記憶領域であるスタックのアドレスを記憶する。スタックは、ＣＰＵ１００がサブルーチンや関数を呼び出す際に、処理中のデータや戻りアドレスなどを一時的に記憶する記憶領域である。リーフ関数用レジスタ１４０は、ＣＰＵ１００がリーフ関数を実行する際に用いるレジスタである。リーフ関数とは、プログラムにおいて、ネストが最も深い位置にある関数をいう。リーフ関数用レジスタ１４０は、汎用レジスタ１３０と対応する記憶領域を有する。レジスタ切り替えユニット１２０は、実行する命令に応じて使用するレジスタを切り替える。具体的には、レジスタ切り替えユニット１２０は、リーフ関数呼び出し命令が入力されると、演算ユニット１１０が演算処理に使用するレジスタを汎用レジスタ１３０からリーフ関数用レジスタ１４０に切り替える。また、レジスタ切り替えユニット１２０は、リーフ関数戻り命令が入力されると、演算ユニット１１０が演算処理に使用するレジスタをリーフ関数用レジスタ１４０から汎用レジスタ１３０に切り替える。
【００１１】
＜１−１．従来技術の説明＞
本発明の実施形態の説明に先立ち、従来技術について説明する。
図２は、従来技術に係るコンピュータシステム２の構成を示す図である。コンピュータシステム２は、コンピュータシステム１のＣＰＵ１００に代わりＣＰＵ４００を有する。それ以外の構成はコンピュータシステム１と同一である。ＣＰＵ４００は、入力された命令に従って演算を行う演算ユニット４１０と、演算処理に用いられる汎用レジスタ４３０とを有する。
【００１２】
図３は、従来技術に係るレジスタの使用例を示す図である。図３の左側に示されているのは、汎用レジスタ４３０の使用例である。汎用レジスタ４３０は、ｒ０〜ｒ９までの１０個のレジスタと、プログラムカウンタＰＣおよびスタックポインタＳＰの合計１２個のレジスタを有している。レジスタｒ０〜ｒ３は保護レジスタである。レジスタｒ４およびｒ５は、関数の戻り値を記憶するレジスタである。レジスタｒ６〜ｒ９は、関数の引数を記憶するレジスタである。図３の右側に示されているのは、ＲＡＭ２００内のスタックである。スタックの左側に記載されている記号はスタックのアドレスである。
【００１３】
図４は、実行対象となるプログラムの例を示す図である。図４の左側のカラムはＣソースコードで、右側のカラムはアセンブラコードで記述されたプログラムを示している。説明の便宜上、プログラム中の必要箇所に、（１）〜（４）の記号を付している。図４に示されるプログラムにおいては、（３）におけるａｄｄ関数がリーフ関数である。以下、このプログラムを実行するときのスタック操作について説明する。
【００１４】
図５、図６、図７、および図８は、従来技術に係るスタック操作の例を示す図である。図５、図６、図７、および図８は、それぞれ、図４に示されるプログラムの（１）〜（４）の処理に対応している。
【００１５】
図５は、ｍａｉｎ関数の実行前のレジスタおよびスタックの状態を示す図である。図５は、図４のプログラムの（１）の位置に対応している。レジスタｒ０〜ｒ３は保護レジスタであるので、変更禁止である。レジスタｒ４〜ｒ９は、初期値を記憶している。ＣＰＵ４００は、ｍａｉｎ関数の戻りアドレス（ここでは「０ｘｃ００１５８」）をスタックに記憶する。スタックポインタＳＰは、ｍａｉｎ関数の戻りアドレスが記憶されたスタックのアドレス（「０ｘ１ｆｆｃ」）を記憶する。
【００１６】
図６は、リーフ関数（ここではａｄｄ関数）の引数を記憶した後、リーフ関数を呼び出す前のレジスタおよびスタックの状態を示す図である。図６は、図４のプログラムの（２）の位置に対応している。レジスタｒ６、ｒ７、ｒ８、およびｒ９は、引数として１、１０、１００、および１０００を記憶している。図４に示されるプログラムにおいて、ａｄｄ関数の引数は５個存在するが、引数を記憶するレジスタは４個しかない。したがって、ＣＰＵ４００は、第５引数「１００００」をスタックに記憶する。スタックポインタＳＰは、第５引数が記憶されたスタックのアドレス（「０ｘ１ｆｆ８」）を記憶する。
【００１７】
図７は、リーフ関数を呼び出した後のレジスタおよびスタックの状態を示す図である。図７は、図４のプログラムの（３）の位置に対応している。ＣＰＵ４００は、ａｄｄ関数の戻りアドレスをスタックに記憶する。スタックポインタＳＰは、ａｄｄ関数の戻りアドレスが記憶されたスタックのアドレス（「０ｘ１ｆｆ４」）を記憶する。ＣＰＵ４００の演算ユニット４１０は、汎用レジスタ４３０を用いて演算を行う。
【００１８】
図８は、リーフ関数からｍａｉｎ関数に戻ったときのレジスタおよびスタックの状態を示す図である。図８は、図４のプログラムの（４）の位置に対応している。レジスタｒ４は、ａｄｄ関数の戻り値（演算結果）「１１１１１」を記憶する。ＣＰＵ４００は、スタックからａｄｄ関数の戻りアドレスを消去する。スタックポインタＳＰは、第５引数が記憶されたスタックのアドレス（「０ｘ１ｆｆ８」）を記憶する。
【００１９】
図９は、従来技術に係るｃａｌｌ命令とｒｅｔ命令の動作例を示す図である。以上で説明したように、リーフ関数を呼び出す際、ＣＰＵ４００は、戻りアドレス（ＰＣ＋２）をスタックに記憶する必要があった。また、リーフ関数から元の処理に戻る際、ＣＰＵ４００は、スタックに記憶された戻りアドレスをプログラムカウンタＰＣに記憶する必要があった。このように、従来技術においては、ＣＰＵ４００は、リーフ関数の呼び出し時とリーフ関数からの戻り時の少なくとも２回、スタックにアクセスする必要があった。
【００２０】
＜１−２．本実施形態の動作＞
以上のように、従来技術に係るＣＰＵ４００は、処理中のデータや戻りアドレスなどを必要に応じてスタックに記憶する。しかし、スタックはＣＰＵ４００とは別個の装置であるＲＡＭ２００内に設けられている。したがって、スタックへのアクセス速度は、ＣＰＵ４００内部に設けられたレジスタと比較すると遅い。そのため、スタックへのアクセスは、ＣＰＵの高速化を阻む要因となっていた。特に、リーフ関数は呼び出される頻度が高い場合が多い。したがって、リーフ関数の実行中におけるスタックへのアクセス頻度を低下させることができれば、ＣＰＵの処理速度が向上することが期待される。そこで、本実施形態に係るＣＰＵ１００は、汎用レジスタ１３０とは別に、リーフ関数の実行時に用いられるリーフ関数用レジスタ１４０を有している。
【００２１】
図１０は、第１実施形態に係るレジスタの使用例を示す図である。汎用レジスタ１３０のレジスタ割り当ては、従来技術と同一である。リーフ関数用レジスタ１４０は、レジスタｒｒ０〜ｒｒ９の１０個のレジスタと、戻り番地格納用のレジスタｒＰＣと、スタックポインタ格納用のレジスタｒＳＰとを有する。レジスタｒｒ０〜ｒｒ９は、リーフ関数において任意に使用可能である。本実施形態において、リーフ関数の呼び出しにはｃａｌｌｒ命令が、リーフ関数から元の処理に戻るときにはｒｅｔｒ命令が使用される。
【００２２】
図１１は、本発明の第１実施形態に係るｃａｌｌｒ命令、ｒｅｔｒ命令の動作例を示す図である。図１１の左側のカラムは、ｃａｌｌｒ命令の動作例を、右側のカラムはｒｅｔｒ命令の動作例を示している。ｃａｌｌｒ命令を実行すると、ＣＰＵ１００は、レジスタｒ０〜ｒ９の内容を、レジスタｒｒ０〜ｒｒ９にコピーする。また、ＣＰＵ１００は、スタックポインタＳＰの内容を、レジスタｒＳＰにコピーする。さらに、ＣＰＵ１００は、レジスタｒＰＣに、プログラムカウンタＰＣに記憶されたアドレス（ｍａｉｎ関数のアドレス）の次のアドレスを記憶させる。本実施形態において、ＣＰＵ１００は、ｒＰＣ＝ＰＣ＋２としてレジスタｒＰＣの内容を決定する。
【００２３】
図１１の右側のカラムは、ｒｅｔｒ命令の動作例を示している。レジスタｒ０〜ｒ３、レジスタｒ６〜ｒ９、およびレジスタＳＰの値は変更されない。ＣＰＵ１００は、レジスタｒｒ４およびｒｒ５の内容を、レジスタｒ４およびｒ５にコピーする。また、ＣＰＵ１００は、レジスタｒＰＣの内容をプログラムカウンタＰＣにコピーする。このように、本実施形態によれば、リーフ関数の呼び出し時およびリーフ関数からの戻り時に、スタックへのアクセスが発生しない。
【００２４】
図１２、図１３、図１４、および図１５は、第１実施形態に係るスタック操作の例を示す図である。従来技術に係るスタック操作の説明と同様に、図１２、図１３、図１４、および図１５は、それぞれ、図４に示されるプログラムの（１）〜（４）の処理に対応している。なお、ＣＰＵ１００に対しては、ａｄｄ関数（リーフ関数）を呼び出す命令はｃａｌｌに代わり「ｃａｌｌｒ」が用いられる。リーフ関数から戻るときには、ｒｅｔ命令に代わり、「ｒｅｔｒ」が用いられる。
【００２５】
図１２は、ｍａｉｎ関数の実行前のレジスタおよびスタックの状態を示す図である。図１２は、図４のプログラムの（１）の位置に対応している。レジスタｒ０〜ｒ３は保護レジスタであるので、変更禁止である。レジスタｒ４〜ｒ９は、初期値を記憶している。ＣＰＵ１００は、ｍａｉｎ関数の戻りアドレス（ここでは「０ｘｃ００１５８」）をスタックに記憶する。スタックポインタＳＰは、ｍａｉｎ関数の戻りアドレスが記憶されたスタックのアドレス（「０ｘ１ｆｆｃ」）を記憶する。
【００２６】
図１３は、リーフ関数（ここではａｄｄ関数）の引数を記憶した後、リーフ関数を呼び出す前のレジスタおよびスタックの状態を示す図である。図１３は、図４のプログラムの（２）の位置に対応している。レジスタｒ６、ｒ７、ｒ８、およびｒ９は、引数として１、１０、１００、および１０００を記憶している。図４に示されるプログラムにおいて、ａｄｄ関数の引数は５個存在するが、引数を記憶するレジスタは４個しかない。したがって、ＣＰＵ１００は、第５引数「１００００」をスタックに記憶する。スタックポインタＳＰは、第５引数が記憶されたスタックのアドレス（「０ｘ１ｆｆ８」）を記憶する。ここで、リーフ関数呼び出し命令（ｃａｌｌｒ）が入力されると、ＣＰＵ１００は、戻りアドレス（ＰＣ＋２）を、リーフ関数用レジスタ１４０内のレジスタｒＰＣに記憶する。さらに、ＣＰＵ１００は、汎用レジスタ１３０内のレジスタｒ０〜ｒ９およびスタックポインタＳＰの内容を、リーフ関数用レジスタ１４０内のレジスタｒｒ０〜ｒｒ９およびレジスタｒＳＰにコピーする。このように、ＣＰＵ１００は、リーフ関数を呼び出すときにスタック（ＲＡＭ２００）にアクセスする必要がない。次に、レジスタ切り替えユニット１２０は、演算ユニット１１０が使用するレジスタを汎用レジスタ１３０からリーフ関数用レジスタ１４０に切り替える。例えば、汎用レジスタ１３０を用いる場合、レジスタｒ０とレジスタｒ２の値を足した値をレジスタｒ０に格納する命令は、「ａｄｄ  ｒ０，ｒ２」として実行される。一方、リーフ関数用レジスタ１４０を用いる場合、この命令は、「ａｄｄ  ｒｒ０，ｒｒ２」として実行される。このように、レジスタ切り替えユニット１２０は、ＣＰＵ１００がリーフ関数を実行中であるか、すなわち、ｃａｌｌｒ命令とｒｅｔｒ命令の間の命令を実行中であるか判断し、ＣＰＵ１００がリーフ関数を実行中である場合には、汎用レジスタ１３０内のレジスタを用いる命令を、リーフ関数用レジスタ１４０内の対応するレジスタを用いるように切り替える機能を有する。
【００２７】
図１４は、リーフ関数を呼び出した後のレジスタおよびスタックの状態を示す図である。図１４は、図４のプログラムの（３）の位置に対応している。リーフ関数の実行時において、ＣＰＵ１００は、リーフ関数用レジスタ１４０内のレジスタｒｒ０〜ｒｒ５をワークとして利用することができる。ここで、リーフ関数戻り命令（ｒｅｔｒ）が入力されると、ＣＰＵ１００は、リーフ関数用レジスタ１４０内のレジスタｒｒ４およびｒｒ５の内容を、汎用レジスタ１３０内のレジスタｒ４およびｒ５にコピーする。また、ＣＰＵ１００は、リーフ関数用レジスタ１４０内のレジスタｒＰＣに記憶されたアドレスを、汎用レジスタ１３０内のプログラムカウンタＰＣにコピーする。このように、ＣＰＵ１００は、リーフ関数から元の処理に戻るときにスタック（ＲＡＭ２００）にアクセスする必要がない。次に、レジスタ切り替えユニット１２０は、演算ユニット１１０が使用するレジスタをリーフ関数用レジスタ１４０から汎用レジスタ１３０に切り替える。
【００２８】
図１５は、リーフ関数からｍａｉｎ関数に戻ったときのレジスタおよびスタックの状態を示す図である。図１５は、図４のプログラムの（４）の位置に対応している。ａｄｄ関数（リーフ関数）を実行すると、レジスタｒｒ４は戻り値（演算結果）「１１１１１」を記憶する。先に説明したように、レジスタｒｒ４の内容はレジスタｒ４にコピーされる。ＣＰＵ１００は、汎用レジスタ１３０を用いて引き続き処理を行う。プログラムカウンタＰＣには、リーフ関数を呼び出す前の処理に続く処理に対応するアドレスが記憶されている。こうして、ＣＰＵ１００は、ｍａｉｎ関数の次の命令を実行する。
【００２９】
以上で説明したように、本実施形態によれば、ＣＰＵ１００は、戻りアドレスをスタックに記憶することなく、また、戻りアドレスをスタックから読み出すことなく、リーフ関数を実行することができる。すなわち、ＲＡＭ２００へのアクセス回数は削減される。これにより、ＣＰＵ１００は、従来技術に係るＣＰＵと比較して高速にプログラムを実行することができる。また、本実施形態によれば、その処理内容が同じである場合、通常関数（非リーフ関数）とリーフ関数との差は、関数呼び出し命令（ｃａｌｌ命令とｃａｌｌｒ命令）および関数からの戻り命令（ｒｅｔ命令およびｒｅｔｒ命令）が異なるだけである。すなわち、本実施形態によれば、コンパイラ（ここではＣコンパイラ）の設計が容易になる。
【００３０】
＜２．第２実施形態＞
続いて、本発明の第２実施形態について説明する。以下では、第１実施形態との差異点を中心に説明する。また、第１実施形態と共通する構成要素には、共通する参照符号を用いる。第２実施形態が第１実施形態と異なっている点は次のとおりである。第１実施形態において、リーフ関数用レジスタ１４０は、汎用レジスタ１３０の全体と対応する記憶領域を有している。これにた対し第２実施形態において、リーフ関数用レジスタ１４０は、プログラムカウンタＰＣおよびスタックポインタＳＰに対応するレジスタｒＰＣおよびｒＳＰのみを有し、レジスタｒ０〜ｒ９に対応するレジスタを有していない。
【００３１】
図１６は、第２実施形態に係るレジスタの使用例を示す図である。汎用レジスタ１３０におけるレジスタの割り当ては、第１実施形態と同一である。リーフ関数用レジスタ１４０は、レジスタｒＰＣおよびｒＳＰを有する。レジスタｒＰＣは、リーフ関数から元の処理に戻るときの戻りアドレスを記憶する。
【００３２】
図１７は、本発明の第２実施形態に係るｃａｌｌｒ命令、ｒｅｔｒ命令の動作例を示す図である。ｃａｌｌｒ命令を実行すると、ＣＰＵ１００は、スタックポインタＳＰの内容をレジスタｒＳＰにコピーする。また、ＣＰＵ１００は、プログラムカウンタＰＣに記憶されたアドレスの次のアドレス（本実施形態においてはＰＣ＋２）を、レジスタｒＰＣに記憶させる。プログラムカウンタＰＣは、元の関数のアドレスを記憶している。ｒｅｔｒ命令を実行すると、ＣＰＵ１００は、レジスタｒＰＣに記憶されたアドレスを、プログラムカウンタＰＣにコピーする。一方、リーフ関数以外の関数の呼び出し命令（ｃａｌｌ）および戻り命令（ｒｅｔ）に対しては、ＣＰＵ１００は次のように動作する。ｃａｌｌ命令を実行すると、ＣＰＵ１００は、スタックポインタＳＰに記憶されたアドレスを、ひとつ前のアドレス（本実施形態においてはＳＰ＝ＳＰ−４）に更新する。さらに、ＣＰＵ１００は、更新されたスタックポインタＳＰに記憶されたアドレスに対応するスタックに、プログラムカウンタＰＣに記憶されたアドレスの次のアドレス（本実施形態においてはＰＣ＋２）を記憶させる。ｒｅｔ命令を実行すると、ＣＰＵ１００は、スタックポインタＳＰに記憶されたアドレスに対応するスタックに記憶されたアドレスを、プログラムカウンタＰＣにコピーする。
【００３３】
図１８、図１９、図２０、および図２１は、第２実施形態に係るスタック操作の例を示す図である。第１実施形態に係るスタック操作の説明と同様に、図１８、図１９、図２０、および図２１は、それぞれ、図４に示されるプログラムの（１）〜（４）の処理に対応している。
【００３４】
図１８は、ｍａｉｎ関数の実行前のレジスタおよびスタックの状態を示す図である。図１８は、図４のプログラムの（１）の位置に対応している。レジスタｒ０〜ｒ３は保護レジスタであるので、変更禁止である。レジスタｒ４〜ｒ９は、初期値を記憶している。ＣＰＵ１００は、ｍａｉｎ関数の戻りアドレス（ここでは「０ｘｃ００１５８」）をスタックに記憶する。スタックポインタＳＰは、ｍａｉｎ関数の戻りアドレスが記憶されたスタックのアドレス（「０ｘ１ｆｆｃ」）を記憶する。
【００３５】
図１９は、リーフ関数（ここではａｄｄ関数）の引数を記憶した後、リーフ関数を呼び出す前のレジスタおよびスタックの状態を示す図である。図１９は、図４のプログラムの（２）の位置に対応している。レジスタｒ６、ｒ７、ｒ８、およびｒ９は、引数として１、１０、１００、および１０００を記憶している。図４に示されるプログラムにおいて、ａｄｄ関数の引数は５個存在するが、引数を記憶するレジスタは４個しかない。したがって、ＣＰＵ１００は、第５引数「１００００」をスタックに記憶する。スタックポインタＳＰは、第５引数が記憶されたスタックのアドレス（「０ｘ１ｆｆ８」）を記憶する。ここで、リーフ関数呼び出し命令（ｃａｌｌｒ）が入力されると、ＣＰＵ１００は、戻りアドレス（ＰＣ＋２）を、リーフ関数用レジスタ１４０内のレジスタｒＰＣに記憶する。さらに、ＣＰＵ１００は、汎用レジスタ１３０内のスタックポインタＳＰの内容を、リーフ関数用レジスタ１４０内のレジスタｒＳＰにコピーする。このように、ＣＰＵ１００は、リーフ関数を呼び出すときにスタック（ＲＡＭ２００）にアクセスする必要がない。次に、レジスタ切り替えユニット１２０は、演算ユニット１１０が使用するレジスタの一部を汎用レジスタ１３０からリーフ関数用レジスタ１４０に切り替える。すなわち、演算ユニット１１０は、汎用レジスタ１３０内のプログラムカウンタＰＣおよびスタックポインタＳＰに代わり、リーフ関数用レジスタ１４０内のレジスタｒＰＣおよびｒＳＰを使用する。
【００３６】
図２０は、リーフ関数を呼び出した後のレジスタおよびスタックの状態を示す図である。図２０は、図４のプログラムの（３）の位置に対応している。リーフ関数の実行時において、ＣＰＵ１００は、汎用レジスタ１３０内のレジスタｒ０〜ｒ９と、リーフ関数用レジスタ１４０内のレジスタｒＰＣおよびｒＳＰを利用して演算を行う。ここで、リーフ関数戻り命令（ｒｅｔｒ）が入力されると、ＣＰＵ１００は、リーフ関数用レジスタ１４０内のレジスタｒＰＣに記憶されたアドレスを、汎用レジスタ１３０内のプログラムカウンタＰＣにコピーする。このように、ＣＰＵ１００は、リーフ関数から元の処理に戻るときにスタック（ＲＡＭ２００）にアクセスする必要がない。次に、レジスタ切り替えユニット１２０は、演算ユニット１１０が使用するレジスタをすべてリーフ関数用レジスタ１４０から汎用レジスタ１３０に切り替える。
【００３７】
図２１は、リーフ関数からｍａｉｎ関数に戻ったときのレジスタおよびスタックの状態を示す図である。図２１は、図４のプログラムの（４）の位置に対応している。ａｄｄ関数（リーフ関数）を実行すると、レジスタｒ４は戻り値（演算結果）「１１１１１」を記憶する。ＣＰＵ１００は、ｍａｉｎ関数の次の命令を実行する。
【００３８】
以上で説明したように、本実施形態によれば、ＣＰＵ１００は、戻りアドレスをスタックに記憶することなく、また、戻りアドレスをスタックから読み出すことなく、リーフ関数を実行することができる。すなわち、ＲＡＭ２００へのアクセス回数は削減される。これにより、ＣＰＵ１００は、従来技術に係るＣＰＵと比較して高速にプログラムを実行することができる。また、第２実施形態においては、リーフ関数用レジスタ１４０は、プログラムカウンタおよびスタックポインタに対応する記憶領域のみ有する。これにより、第１実施形態と比較してプロセッサのコストを低減することができる。
【００３９】
＜３．第３実施形態＞
続いて、本発明の第３実施形態について説明する。以下では、第１および第２実施形態と共通する構成要素には、共通する参照符号を用いて説明を行う。また、第１および第２実施形態と共通する事項については説明を省略する。第３実施形態の概要は次のとおりである。ＣＰＵ１００が、いわゆる割り込みハンドラを呼び出す機能を有している場合、次のような問題が起こる可能性がある。すなわち、ＣＰＵ１００がリーフ関数を実行しているときに割り込みが発生し、割り込みハンドラが割り込み処理の中でリーフ関数を実行する場合がある。このとき、割り込み処理においてもリーフ関数を第１および第２実施形態で説明したリーフ関数呼び出し命令（ｃａｌｌｒ）でリーフ関数を呼び出すと、リーフ関数用レジスタ１４０の内容が破壊されてしまうおそれがある。本実施形態は、この問題を回避する技術を提供するものである。
【００４０】
図２２は、第３実施形態に係るコンピュータシステム３の構成を示す図である。コンピュータシステム３がコンピュータシステム１と異なっている点は、ＣＰＵ１００が、ｃａｌｌｒ命令ネストフラグレジスタ１５０を有する点である。ｃａｌｌｒ命令ネストフラグレジスタ１５０は、ＣＰＵ１００がリーフ関数を実行中であること、すなわち、ＣＰＵ１００が、ｃａｌｌｒ命令とｒｅｔｒ命令の間の命令を実行中であることを示すフラグを記憶するレジスタである。本実施形態において、ＣＰＵ１００がリーフ関数を実行中である場合、そこから再度リーフ関数呼び出し命令（ｃａｌｌｒ）を実行することは回避される。
【００４１】
図２３は、コンピュータシステム３の動作を示すフローチャートである。ステップＳ１００において、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグレジスタ１５０を初期化する。ｃａｌｌｒ命令ネストフラグレジスタ１５０は、例えば、その値が「０」のときはＣＰＵ１００がリーフ関数を実行中でないことを、また、その値が「１」のときはＣＰＵ１００がリーフ関数を実行中であることを示す。ここで、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグレジスタ１５０の値を「０」に初期化する。
【００４２】
次に、ステップＳ１１０において、ＣＰＵ１００は、命令をフェッチしたか判断する。何らかの命令をフェッチした場合（ステップＳ１１０：ＹＥＳ）、ステップＳ１２０において、ＣＰＵ１００は、フェッチした命令がリーフ関数呼び出し命令（ｃａｌｌｒ命令）であるか判断する。フェッチした命令がｃａｌｌｒ命令である場合（ステップＳ１２０：ＹＥＳ）、ＣＰＵ１００は、処理をステップＳ１３０に移行する。フェッチした命令がｃａｌｌｒ命令でない場合（ステップＳ１２０：ＮＯ）、ＣＰＵ１００は、処理をステップＳ１６０に移行する。
【００４３】
ステップＳ１３０において、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグがセットされているか判断する。すなわち、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグレジスタ１５０の値が「１」であるか判断する。ｃａｌｌｒ命令ネストフラグレジスタ１５０の値が「０」であった場合（ステップＳ１３０：ＮＯ）、ステップＳ１４０において、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグをセットする。すなわち、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグレジスタ１５０の値を「１」に書き換える。ｃａｌｌｒ命令ネストフラグレジスタ１５０の値を「１」に書き換えると、ＣＰＵ１００は、処理をステップＳ１８０に移行する。
【００４４】
ｃａｌｌｒ命令ネストフラグレジスタ１５０の値が「１」であった場合（ステップＳ１３０：ＹＥＳ）、ステップＳ１５０において、ＣＰＵ１００は、フェッチした命令をｃａｌｌｒからｃａｌｌに置換する。フェッチした命令をｃａｌｌｒからｃａｌｌに置換すると、ＣＰＵ１００は、処理をステップＳ１８０に移行する。
【００４５】
ステップＳ１６０において、ＣＰＵ１００は、フェッチした命令がリーフ関数戻り命令（ｒｅｔｒ命令）であるか判断する。フェッチした命令がｒｅｔｒ命令であった場合（ステップＳ１６０：ＹＥＳ）、ＣＰＵ１００は、ステップＳ１７０において、ｃａｌｌｒネストフラグをクリアする。すなわち、ＣＰＵ１００は、ｃａｌｌｒ命令ネストフラグレジスタ１５０の値を「０」にする。ｃａｌｌｒネストフラグをクリアすると、ＣＰＵ１００は、処理をステップＳ１８０に移行する。また、フェッチした命令がｒｅｔｒ命令でない場合（ステップＳ１６０：ＮＯ）も、ＣＰＵ１００は、処理をステップＳ１８０に移行する。
【００４６】
ステップＳ１８０において、ＣＰＵ１００は命令を実行する。ここで、ＣＰＵ１００がリーフ関数を実行しているとき（ｃａｌｌｒ命令とｒｅｔｒ命令の間の命令を実行しているとき）にｃａｌｌｒ命令が入力された場合、ｃａｌｌｒ命令はｃａｌｌ命令に置換される。すなわち、リーフ関数呼び出し命令はリーフ関数以外の関数呼び出し命令に置換される。したがって、割り込みハンドラがリーフ関数を実行してもリーフ関数用レジスタ１４０の内容が破壊されることがない。
【００４７】
例えば、ｍａｉｎ関数からリーフ関数が呼び出された場合を考える。このとき、ｃａｌｌｒ命令ネストフラグレジスタ１５０は「０」を記憶している。したがって、ステップＳ１４０においてｃａｌｌｒ命令ネストフラグレジスタ１５０の値は「１」に書き換えられる。次に、ステップＳ１８０において、ＣＰＵ１００はｃａｌｌｒ命令を実行する。このときの処理は第１および第２実施形態で説明したとおりである。すなわち、演算ユニット１１０は、リーフ関数用レジスタ１４０を用いて演算処理を行う。
【００４８】
次に、この状態において割り込み処理ハンドラによりリーフ関数が呼び出された場合を考える。このとき、ｃａｌｌｒ命令ネストフラグレジスタ１５０は「１」を記憶している。したがって、ステップＳ１５０において、ｃａｌｌｒ命令はｃａｌｌ命令に置換される。次に、ステップＳ１８０において、ＣＰＵ１００はｃａｌｌ命令を実行する。このとき、ＣＰＵ１００が実行するのはリーフ関数呼び出し命令ではなく、リーフ関数以外の関数呼び出し命令である。したがって、戻りアドレスなどはスタックに記憶され、リーフ関数用レジスタ１４０の内容は破壊されない。
【００４９】
次に、この状態で割り込み処理が完了したあと元のリーフ関数の処理に戻り、リーフ関数戻り命令が入力された場合を考える。この場合、ステップＳ１７０において、ｃａｌｌｒ命令ネストフラグレジスタ１５０の値は「０」に書き換えられる。次に、ステップＳ１８０において、ＣＰＵ１００はｒｅｔｒ命令を実行する。すなわち、リーフ関数から元のｍａｉｎ関数の処理に戻る。
【００５０】
なお、本実施形態は、上述の第１実施形態および第２実施形態のどちらに対して適用してもよい。
【図面の簡単な説明】
【００５１】
【図１】第１実施形態に係るコンピュータシステム１の構成を示す図である。
【図２】従来技術に係るコンピュータシステム２の構成を示す図である。
【図３】従来技術に係るレジスタの使用例を示す図である。
【図４】実行対象となるプログラムの例を示す図である。
【図５】従来技術に係るスタック操作の例を示す図である。
【図６】従来技術に係るスタック操作の例を示す図である。
【図７】従来技術に係るスタック操作の例を示す図である。
【図８】従来技術に係るスタック操作の例を示す図である。
【図９】従来技術に係るｃａｌｌ命令とｒｅｔ命令の動作例を示す図である。
【図１０】第１実施形態に係るレジスタの使用例を示す図である。
【図１１】第１実施形態に係るｃａｌｌｒ命令、ｒｅｔｒ命令の動作例を示す。
【図１２】第１実施形態に係るスタック操作の例を示す図である。
【図１３】第１実施形態に係るスタック操作の例を示す図である。
【図１４】第１実施形態に係るスタック操作の例を示す図である。
【図１５】第１実施形態に係るスタック操作の例を示す図である。
【図１６】第２実施形態に係るレジスタの使用例を示す図である。
【図１７】第２実施形態に係るｃａｌｌｒ命令、ｒｅｔｒ命令の動作例を示す。
【図１８】第２実施形態に係るスタック操作の例を示す図である。
【図１９】第２実施形態に係るスタック操作の例を示す図である。
【図２０】第２実施形態に係るスタック操作の例を示す図である。
【図２１】第２実施形態に係るスタック操作の例を示す図である。
【図２２】第３実施形態に係るコンピュータシステム３の構成を示す図である。
【図２３】コンピュータシステム３の動作を示すフローチャートである。
【符号の説明】
【００５２】
１・２・３…コンピュータシステム、１００…ＣＰＵ、１１０…演算ユニット、１２０…レジスタ切り替えユニット、１３０…汎用レジスタ、１４０…リーフ関数用レジスタ、１５０…ｃａｌｌｒ命令ネストフラグレジスタ、２００…ＲＡＭ、３００…ＲＯＭ、４００…ＣＰＵ、４１０…演算ユニット、４３０…汎用レジスタ、９００…バス
【図１】
2007219938.tif 000003
【図２】
2007219938.tif 000004
【図３】
2007219938.tif 000005
【図４】
2007219938.tif 000006
【図５】
2007219938.tif 000007
【図６】
2007219938.tif 000008
【図７】
2007219938.tif 000009
【図８】
2007219938.tif 000010
【図９】
2007219938.tif 000011
【図１０】
2007219938.tif 000012
【図１１】
2007219938.tif 000013
【図１２】
2007219938.tif 000014
【図１３】
2007219938.tif 000015
【図１４】
2007219938.tif 000016
【図１５】
2007219938.tif 000017
【図１６】
2007219938.tif 000018
【図１７】
2007219938.tif 000019
【図１８】
2007219938.tif 000020
【図１９】
2007219938.tif 000021
【図２０】
2007219938.tif 000022
【図２１】
2007219938.tif 000023
【図２２】
2007219938.tif 000024
【図２３】
2007219938.tif 000025