1.2 言語仕様
1.2.16 組み込み関数
(標準)Cに同等のものがない、S1C88特有の関数を使用したい場合、これらの作業を実行するアセンブラ ルーチンを記述する他ありません。しかし、c88では、これをCで扱う方法が提供されています。c88には、
さまざまなビルトイン関数があり、組み込み関数として実装されています。
プログラマから見ると、組み込み関数は通常のC関数と同じに見えますが、コードジェネレータがこれを解 釈するという点で異なります。このような特性のため、生成されるコードは効率的になります。組み込み 関数呼び出し時にインラインアセンブラコードを生成するとき、一部の宣言済みの関数が使用できます。
このような関数を使用すると、呼び出される関数を実行する前に、パラメータの受け渡しとコンテキスト の保存で通常発生するオーバーヘッドを回避することができます。
すべての組み込み関数の名前には、最初にアンダースコアが付いています。これは、一般的に定義済みの仕 様の場合、Cの名前の最初にアンダースコアを付けるということが、ANSI仕様で定義されているためです。
アセンブラの記述(プラグマasm/endasm)と比較した場合の組み込み関数の利点には、次のようなものがあり ます。
● c88によって生成されたアセンブラの記述コードを置換するとき、ホストコンパイラがシミュレーショ
ンルーチンまたはスタブ関数を使用できます。
● Cレベルの変数にアクセスすることができます。
● コンパイラが、もっとも効率的にC変数にアクセスできるコードを生成します。
● _nop()を除き、組み込みコードが最適化されます。
次の組み込み関数が実装されています。
関数 _bcd() _halt() _int() _jrsf() _nop() _pack() _rlc() _rrc() _slp() _swap() _ubcd() _unpack() _upck()
説 明 式評価で"D"フラグをセット HALT命令
ソフトウェア割り込み
条件が真であれば相対位置にジャンプ 最適化されないNOP命令
整数を文字値にパック 左にローテート 右にローテート SLP命令
上位ニブルと下位ニブルをスワップ 式評価で"U"フラグと"D"フラグをセット 式評価で"U"フラグをセット
文字を整数値にアンパック
組み込み関数のプロトタイプは、c88.hにあります。以下、実装されている組み込み関数の詳細を示して います。
_bcd
void _bcd();
引数式を評価するとき、"D"フラグがセットされます。つまり、加算/減算命令および否定命令が二進化 十進数として実行されます。ただし、式評価を通じて"D"フラグがリセットされないとき、たとえば式 が浮動小数点を使用する場合などに問題が起こる可能性もあります。
引数は任意の型の式にすることができます(char/int/long)。そのため、引数リストは、古いスタイ ル(K&Rスタイル)の関数定義として(引数の型を定義しないで)実装されます。
戻り値 なし
_halt
void _halt ( vold );
HALT命令を生成します。
戻り値 なし _halt();
...Code...
HALT
_int
void _int ( ICE vector );
実行ソフトウェア割り込み命令(INT)を挿入します。引数はICE型の値で、ジャンプ先の割り込みベクタ アドレスを決定します。ICEは、オペランドが、任意の型の整数式でなく、整数定数式でなければなら ないことを示します。
戻り値 なし
_jrsf
char _jrsf( ICE number );
̲lab命令、JRS Fnumberを使用します。この命令は、if()条件テストで使用するのに適しています。number の値は、0から3の定数値でなければなりません。ICEは、オペランドが、任意の型の整数式でなく、整 数定数式でなければならないことを示します。コードジェネレータは、Fnumberとこの命令の変異体で あるNFnumberのいずれかを選択します。
戻り値 結果 if ( _jrsf(2) ) {
...
} ...Code...
JRS NF2, _l0001 _L0001:
_nop
void _nop( void );
NOP命令を生成します。
戻り値 なし _nop();
...Code...
NOP
_pack
char _pack( int operand );
PACK命令を使用して、整数operandを文字値にパックします。
戻り値 文字値
_rlc
char _rlc( char operand );
RLC命令を使用して、バイトoperandを左にローテートします。命令は結果にのみ影響し、operandには影 響を与えません。
戻り値 結果 char c;
int i;
/* rotate left */
c= _rlc( c ) ;
_rrc
char _rrc( char operand );
RRC命令を使用して、バイトoperandを右にローテートします。命令は結果にのみ影響し、operandには 影響を与えません。
戻り値 結果 char C;
int i;
/* rotate right */
c = _rrc( c );
_slp
void _slp( void );
SLP命令を生成します。
戻り値 なし _slp();
...Code...
SLP
_swap
char _swap ( char operand );
SWAP命令を使用して、文字operandの上位ニブルと下位ニブルをスワップします。
戻り値 結果
_ubcd
void _ubcd();
引数式を評価するとき、"U"フラグと"D"フラグがセットされます。つまり、計算時にバイトの下位ニブ ルのみが使用され、同時に加算/減算命令および否定命令がBCD演算として実行されます。ただし、式 評価を通じて"D"フラグがリセットされないとき、たとえば式が浮動小数点を使用する場合などに問題 が起こる可能性もあります。
戻り値 なし
_unpack
void _unpack();
引数式を評価するとき、"U"フラグがセットされます。つまり、計算時にバイトの下位ニブルのみが使 用されます。引数は任意の型の式にすることができます(char/int/long)。そのため、引数リスト は、古いスタイルの関数定義として実装されます。
戻り値 なし
_upck
int _upck( char operand );
UPACK命令を使用して、文字operandを整数値にアンパックします。
戻り値 整数値