Article #247

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

BSVの設計トライアル (14)

posted by sakurai on April 24, 2020 #247

リファクタリング(1)(プッシュとリターンの統合)

前稿でpushRetとcallをまとめるアイデアを記載しましたが、それを実装してみます。まとめたマクロ命令をpushCallと名付けます。

`define _pushRet          rs.upd(sp, ret); sp <= sp + 1
`define popRet            state <= rs.sub(sp-1); sp <= sp - 1
`define pushCall(SUB)     `_pushRet; `_saveNext; state <= State_t {func:SUB, step:S0}
`define _saveNext         ret <= State_t {func:state.func, step:nextStep()}
`define return            state <= ret

非リーフでのコールとリターンが完成したので動作確認を行います。非リーフでのcallをpushCallに、リターンはそのままpopRetとします。リーフではcallは無く、リターンはそのままreturnとします。

ソースコード内のpushRetを削除し、それぞれのcallをL1ルール内において、

             `pushCall(L2);

L2ルール内において、

             `pushCall(L3);

L3ルール内において、

             `pushCall(L4);

のように修正します。動作確認した結果、expectedと一致し正常動作が確認されました。

リファクタリング(2)(リーフと非リーフの共通化)

そもそもリターンレジスタのretがあるためリーフと非リーフの区別がありました。スタック操作はハードウエアであり、性能へのインパクトがほとんど無いことから、リーフ・非リーフで統一したやり方を考えます。それにはretレジスタを廃止します。従って、callとreturnは以下のようにリターンスタックのみで操作します。 retレジスタの削除の他、マクロの修正を次のように行います。

`define return           state <= rs.sub(sp-1); sp <= sp - 1
`define call(SUB)        `_pushNext; state <= State_t {func:SUB, step:S0}
`define _pushNext        rs.upd(sp, State_t {func:state.func, step:nextStep()}); sp <= sp + 1
`define next             state.step <= nextStep()

としました。これにより、サブルーチンコールの場合は常にcall()を用い、リターンの場合は常にreturnを用います。このように修正した結果、正常動作することを確認しました。ただし、returnレジスタを削除したため、rsはL1~L3で使用により3段、従ってspは2bitとなりました。

以上から、内部マクロを除くユーザーに見えるマクロは、call()、return、nextの3種となります。


左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.