条件実行

ADSP-2191の面白い特徴のひとつとして、条件実行を挙げることができます。条件実行とは読んでその名のとおり、ある条件が満たされたときだけ実行される命令です。

大抵のプロセッサは条件分岐命令を持っています。たとえば、x86のJEQ、68000のBEQは演算結果が0のときに分岐します。変わったところではマイクロプロセッサではないものの、私のHP製電卓は条件が満たされると次の命令を実行しないという命令を持っています。次の命令を分岐命令にしておくと、反転条件の分岐命令を組めるわけです。

ADSP-2191は条件分岐だけでなく条件演算命令を持っています。たとえば2191の条件分岐は

IF EQ JUMP FOO;

のようになっています。前の演算結果が0であれば分岐する命令です。そして条件演算のほうは

IF EQ AR = AX0 + AY0;

のように条件節の後ろに演算命令を書くことで表記します。ちょっとしたコードでも条件分岐を多用するとすぐにストールまみれになってしまいますが、条件実行をうまく使うとストールを防ぐこともできます。

条件コード

実行条件の指定は条件コードで行います。条件コードには以下のようなものがあります。

コード 条件
EQ 等しい。あるいは0。
NE 等しくない。あるいは0でない。
GE 大きいか等しい。あるいは正か0。
LT 小さい。あるいは負。
GT 大きい。あるいは正。
LE 小さいか等しい。あるいは負か0.
AC 桁上げがおきた。
NOT AC 桁上げがおきなかった。
AV あふれがおきた。
NOT AV あふれがおきなかった。
MV MRレジスタであふれがおきた。
NOT MV MRレジスタであふれがおきなかった。
SWCOND ソフトウェア条件が成立した。
NOT SWCOND ソフトウェア条件が成立しなかった。
NOT CE カウンターが0になっていない。
TRUE

前半は比較的理解しやすいものですが、後半首をひねるようなものが顔を出します。SWCONDってなんでしょう?これは少ないビットフィールドで多くの条件を指定できるようアーキテクトが用意した機能です。

SWCOND

SWCONDはソフトウェア条件と呼ばれます。あまりいい名前ではありませんが、あえて言えばレジスタ間接条件です。ADSP-2191はCCODEという名前のレジスタを持っており、ここに拡張条件をセットすることができます。プログラマがSWCOND条件を参照した場合、ADSP-2191はCCODEレジスタの拡張条件が成立するかどうかを調べて、成立すればSWCOND評価結果を真、成立しなければ偽とします。

この機能によって命令の条件フィールドが許すより多くの種類の条件を使用することができます。実際には煩雑に現れる条件をここに指定するのはオーバーヘッドが大きすぎますので、やや特殊なものが用意されています。

ADSP-2191はCCODE用の条件として次のようなものを用意しています。

コード 条件
cond_PF0 PF0ピンがHである
cond_PF1 PF1ピンがHである
cond_PF2 PF2ピンがHである
cond_PF3 PF3ピンがHである
cond_PF4 PF4ピンがHである
cond_PF5 PF5ピンがHである
cond_PF6 PF6ピンがHである
cond_PF7 PF7ピンがHである
cond_PF8 PF8ピンがHである
cond_PF9 PF9ピンがHである
cond_PF10 PF10ピンがHである
cond_PF11 PF11ピンがHである
cond_PF12 PF12ピンがHである
cond_PF13 PF13ピンがHである
cond_AS 飽和が起きた
cond_SV SRレジスタであふれがおきた

組み込み用ということで、プログラマブルファンクションピンを監視する条件が多く用意されています。

PFピン監視の極性

SWCONDでPFピンを監視できるのは結構ですが、PFピンはFSPRレジスタで入力極性を切り替えることができます。SWCONDによる監視はこの影響を受けるのでしょうか。HRにはこの記述がないようなので下のようなコードで実験してみたところ、FSPRの値によって条件の真偽が影響を受けました。

SWCONDはFSPRの影響を受けます。

#include "def2191.h"
.section/pm program;
.global _main;
_main:
        iopg=General_Purpose_IO;
        ax0=0x01;           // PF0 out, others in;
        io(DIR)=ax0;
#if 1
        ax0=0x0010;         // set PF4 negative logic
#else
        ax0=0x0000;         // set PF4 positive logic
#endif
        io(FSPR)=ax0;
        ax1=1;
        ccode=cond_PF4; // check PF4 (SW3)
looptop:
        if swcond jump clear;
        io(FLAGS)=ax1;      // set PF0
        jump looptop;
clear:
        io(FLAGC)=ax1;      // clear PF0
        jump looptop;
2191空挺団 | プログラム | EZ-KIT | こぼれ話 | アーキテクチャー | 命令 | レジスタ | DSP掲示板 | FAQ |