#pragma mc_func ディレクティブは、マシン・インストラクションの短いシーケンスを含んだ関数を定義できるようにします。
ここで、
function C または C++ プログラムにおいて事前定義された関数を指定する必要があります。関数が事前定義されていない場合、コンパイラーはプラグマを関数定義として処理します。 instruction_seq ゼロ個以上の 16 進数字のシーケンスを含んだストリングです。数字の数は、32 ビットの整数倍で構成される必要があります。
mc_func プラグマによって、マシン・インストラクション "inline" の短いシーケンスをプログラムのソース・コード内に埋め込めます。このプラグマは、通常のリンケージ・コードの代わりに、指定された命令を生成するようにコンパイラーに指示します。このプラグマを使用すると、アセンブラーでコーディングした外部関数への呼び出しに関連するパフォーマンス負荷を回避できます。このプラグマの機能は、このコンパイラーおよび他のコンパイラーにある asm キーワードに類似しています。
mc_func プラグマは、関数を定義し、関数の定義が通常行われるプログラム・ソース内にのみ出現しなければなりません。 #pragma mc_func によって定義される関数名は、事前に宣言またはプロトタイプ化される必要があります。
コンパイラーは、他の関数と同様にパラメーターを関数に渡します。例えば、整数型の引き数を取る関数の場合、1 番目のパラメーターは GPR3 に、 2 番目は GPR4 に、というように渡されます。関数によって戻される値は、integer 値の場合は GPR3 に、 float または double 値の場合は FPR1 となります。ご使用のシステムで使用可能な揮発性レジスターのリストについては、 #pragma reg_killed_by を参照してください。
#pragma reg_killed_by を使用して、関数によって使用される特定のレジスター・セットをリストしていない限り、 instruction_seq から生成されるコードは、ご使用のシステムで使用可能な揮発性レジスターをどれでも使用できます。
インライン化オプションは、 #pragma mc_func によって定義された関数に影響を与えません。しかし、#pragma isolated_call を使用して、そのような関数のランタイム・パフォーマンスを改善できます。
次の例では、add_logical と呼ばれる関数を定義するために、#pragma mc_func が使用されています。関数は、マシン・インストラクションから構成されて、いわゆる循環桁上げ を使用して 2 つの int を加算しています。つまり、加算の結果、桁上げが発生する場合、桁上げが合計に加算されます。これは、チェックサム計算において頻繁に使用されます。
例では、 #pragma mc_func によって定義された関数による変更が可能な揮発性レジスターの特定のセットをリストする #pragma reg_killed_by の使用法も示しています。
int add_logical(int, int); #pragma mc_func add_logical {"7c632014" "7c630194"} /* addc r3 <- r3, r4 */ /* addze r3 <- r3, carry bit */ #pragma reg_killed_by add_logical gr3, xer /* only gpr3 and the xer are altered by this function */ main() { int i,j,k; i = 4; k = -4; j = add_logical(i,k); printf("¥n¥nresult = %d¥n¥n",j); }