デュアルコア インテル® Itanium® プロセッサー 9000 系の組み込み関数

デュアルコア インテル® Itanium® プロセッサー 9000 系のプロセッサーでは、次の表の組み込み関数をサポートします。

これらの組み込み関数は、それぞれ IA-64 命令を生成します。組み込み関数名の前半は戻り型を示し、後半はその組み込み関数により生成される命令を示します。例えば、組み込み関数 _int64_cmp8xchg の戻り型は _int64 で、生成される IA-64 命令は cmp8xchg です。

これらの組み込み関数のいくつかの例がこのトピックの最後にあります。

組み込み関数により生成される命令についての詳細は、インテル® Itanium® プロセッサー Web サイト (http://developer.intel.com/products/processor/itanium/index.htm) のドキュメントを参照してください。

Note icon

以前のバージョンの Itanium® プロセッサーでこれらの組み込み関数を呼び出すと、不正な命令違反が発生します。

組み込み関数名

演算子

__cmp8xchg16

比較/交換

__ld16

ロード

__fc_i

キャッシュのフラッシュ

__hint

パフォーマンス・ヒントの提供

__st16

ストア

 

__int64 __cmp8xchg16(const int <sem>, const int <ldhint>, void *<addr>, __int64 <xchg_lo>)

16 バイトの 比較/交換 IA-64 命令を生成します。

指定のメモリーアドレスから読み取られた 64 ビット値を返します。

次の表は、この組み込み関数の引数について説明しています。

sem

ldhint

addr

xchg_lo

セマフォー・コンプリーターを指定するリテラル値 (0==.acq または 1==.rel)

ロード・ヒント・コンプリーターを指定するリテラル値 (0==.none、1==.nt1、または 2==.nta)

読み取る値のアドレス

交換する値の最下位 8 バイト

次の表は、この組み込み関数の暗黙の引数について説明しています。

xchg_hi

cmpnd

交換する値の最上位 8 バイト。__setReg 組み込み関数を使用して、AR[CSD] レジスターに <xchg_hi> 値を設定します。[__setReg (_IA64_REG_AR_CSD, <xchg_hi>);]

64 ビットの比較値。__setReg 組み込み関数を使用して、AR[CCV] レジスターに <cmpnd> 値を設定します。[__setReg (_IA64_REG_AR_CCV,<cmpnd>);]

例:

__int64 foo_cmp8xchg16(__int64 xchg_lo, __int64 xchg_hi, __int64 cmpnd, void* addr)

 

{

 __int64 old_value;

 

 /**/

  // set the highest bits of the exchange value and the comperand value

  // respectively in CSD and CCV. Then, call the exchange intrinsic

  //

 

  __setReg(_IA64_REG_AR_CSD, xchg_hi);

  __setReg(_IA64_REG_AR_CCV, cmpnd);

  old_value  = __cmp8xchg16(__semtype_acq, __ldhint_none, addr, xchg_lo);

  /**/

  return old_value;

}

 

__int64 __ld16(const int <ldtype>, const int <ldhint>, void *<addr>)

指定されたアドレスから 16 バイトをロードする IA-64 命令を生成します。

<addr> からロードされた下位 8 バイトを返します。上位 8 バイトは AR[CSD] レジスターにロードされます。

AR[CSD] レジスターにロードされる上位 8 バイトは暗黙的に返されます。__getReg 組み込み関数を使用して、ユーザー変数に値をコピーすることができます。 [foo = __getReg(_IA64_REG_AR_CSD);]

次の表は、この組み込み関数の引数について説明しています。

ldtype

ldhint

addr

ロードタイプを指定するリテラル値 (0==none または 1==.acq)

ヒント・コンプリーターを指定するリテラル値 (0==none、1==.nt1、または 2== .nta)

ロードするアドレス

例:

void foo_ld16(__int64* lo, __int64* hi, void* addr)

{

     /**/

 

     // The following two calls load the 16-byte value at the given address

     // into two (2) 64-bit integers

     // The higher 8 bytes are returned implicitly in the CSD register;

     // The call to __getReg moves that value into a user variable (hi).

     // The instruction generated is a plain ld16

     //    ld16 Ra,ar.csd=[Rb]

 

     *lo = __ld16(__ldtype_none, __ldhint_none, addr);

     *hi = __getReg(_IA64_REG_AR_CSD);

 

      /**/

 

}

 

void __fc_i(void *<addr>)

指定されたアドレスに関連するキャッシュラインをフラッシュし、命令キャッシュとデータキャッシュの一貫性を保つ IA-64 命令を生成します。

次の表は、この組み込み関数の引数について説明しています。

cache_line

フラッシュするキャッシュラインに関連するアドレス

 

void __hint(const int <hint_value>)

実行中のプログラムのパフォーマンス・ヒントを提供する IA-64 命令を生成します。

次の表は、この組み込み関数の引数について説明しています。

hint_value

ヒントを指定するリテラル値。現在、0 のみ有効です。__hint(0) は、IA-64 の hint@pause 命令を生成します。

 

void __st16(const int <sttype>, const int <sthint>, void *<addr>, __int64 <src_lo>)

指定されたアドレスに 16 バイトをストアする IA-64 命令を生成します。

次の表は、この組み込み関数の引数について説明しています。

sttype

sthint

addr

src_lo

ストア・タイプ・コンプリーターを指定するリテラル値 (0==.none または 1==.rel)

ストア・ヒント・コンプリーターを指定するリテラル値 (0==.none または 1==.nta)

16 バイト値をストアするアドレス

ストアする 16 バイト値の下位 8 バイト

次の表は、この組み込み関数の暗黙の引数について説明しています。

src_hi

ストアする 16 バイト値の上位 8 バイト。setReg 組み込み関数を使用して、AR[CSD] レジスターに <src_hi> 値を設定します。[__setReg(_IA64_REG_AR_CSD, <src_hi>); ]

例:

void foo_st16(__int64 lo, __int64 hi, void* addr)

 

{

 

 /**/

 

  // first set the highest 64-bits into CSD register. Then call

  // __st16 with the lowest 64-bits as argument

 //

 

 __setReg(_IA64_REG_AR_CSD, hi);

  __st16(__sttype_none, __sthint_none, addr, lo);

 

 /**/

 

}

複数の組み込み関数の併用例

次の例では、上記の組み込み関数を一緒に使用して対応する命令を生成する方法を示します。いずれの場合も、__setReg (または __getReg) 組み込み関数を使用して暗黙の引数 (それぞれの暗黙の戻り値の取得) を設定します。

// file foo.c

//

 

#include <ia64intrin.h>

 

void foo_ld16(__int64* lo, __int64* hi, void* addr)

{

     /**/

 

     // The following two calls load the 16-byte value at the given address

     // into two (2) 64-bit integers

     // The higher 8 bytes are returned implicitly in the CSD register;

     // The call to __getReg moves that value into a user variable (hi).

     // The instruction generated is a plain ld16

     //    ld16 Ra,ar.csd=[Rb]

 

     *lo = __ld16(__ldtype_none, __ldhint_none, addr);

     *hi = __getReg(_IA64_REG_AR_CSD);

 

      /**/

 

}

void foo_ld16_acq(__int64* lo, __int64* hi, void* addr)

 

{

 

 /**/

 

  // This is the same as the previous example, except that it uses the

 // __ldtype_acq completer to generate the acquire_from of the ld16:

  // ld16.acq Ra,ar.csd=[Rb]

  //

 

  *lo = __ld16(__ldtype_acq, __ldhint_none, addr);

  *hi = __getReg(_IA64_REG_AR_CSD);

 

  /**/

 

}

void foo_st16(__int64 lo, __int64 hi, void* addr)

 

{

 

 /**/

 

  // first set the highest 64-bits into CSD register. Then call

  // __st16 with the lowest 64-bits as argument

 //

 

 __setReg(_IA64_REG_AR_CSD, hi);

  __st16(__sttype_none, __sthint_none, addr, lo);

 

 /**/

 

}

__int64 foo_cmp8xchg16(__int64 xchg_lo, __int64 xchg_hi, __int64 cmpnd, void* addr)

 

{

 __int64 old_value;

 

 /**/

  // set the highest bits of the exchange value and the comperand value

  // respectively in CSD and CCV. Then, call the exchange intrinsic

  //

 

  __setReg(_IA64_REG_AR_CSD, xchg_hi);

  __setReg(_IA64_REG_AR_CCV, cmpnd);

  old_value  = __cmp8xchg16(__semtype_acq, __ldhint_none, addr, xchg_lo);

  /**/

  return old_value;

}

 

// end foo.c