PowerPCは32bitモードと64bitモードを持つアーキテクチャなので、同時に32bitアプリケーションと64bitアプリケーションを扱えます。
32bitモードの説明はスタックフレームのページでやったので、ここにあるのは64bitモードの拡張の説明です。
G5は64bit CPUなので、一部の32bitレジスタは64bitに変わっている。64bitになったレジスタは以下の通り。
- 32個の汎用レジスタ
- 整数例外レジスタ、リンクレジスタ、カウンタレジスタといった特殊レジスタ
スタックフレーム
汎用レジスタなどが64bitになったため、一部スタックフレームのサイズも変更される。
連結エリア
連結エリアの構成(64bitモード)
| 呼び出し側引数エリア |
| 呼び出し側連結エリア | TOCレジスタ内容保存先(スタックポインタ+40のアドレス)※Mac OSXでは未使用 |
| 予約領域 |
| 呼び出された側のリンクレジスタ保存先(スタックポインタ+16のアドレス) |
| 呼び出された側の状態レジスタ保存先(スタックポインタ+8のアドレス) |
| 呼び出し側のスタックポインタ |
| 呼び出された側のスタックフレーム |
以上の通り、連結エリアのサイズが48byteになった。
退避エリア
汎用レジスタのサイズが大きくなったため、汎用レジスタを退避する場合、8byteが必要になった。
引数エリア
汎用レジスタのサイズが大きくなったため、最低サイズも32byteから64byteへ変更。
64bitモードと32bitモードとの違いを吸収するため、通常のPowerPC命令の一部への拡張や、命令の追加が加えられている。
32bitモードで整数演算+比較命令を行った場合、32bit整数の時の比較結果となり、64bitモードで整数演算+比較命令を行った場合、64bit整数の時の比較結果となるので注意。
算術演算命令
64bitモードの場合、これらの命令に付加する処理(キャリービットの格納や条件テスト)は、64bitとしての計算結果が反映されるようになった。基本的には、算術命令で32bit整数を扱おうが64bit整数を扱おうが、処理は同じなのだが、乗除算命令はそうはいかないので、新たな命令が追加されたり、振る舞いが変更されたりしている。
- divd(o)(.) rD, rA, rB
- rAとrBとの64bit符号付き除算結果をrDに格納する。
- divw(o)(.) rD, rA, rB
- 32bitモードにもある命令。
rAとrBとの32bit符号付き除算結果をrDに格納する。上32bitの内容は未定義になる。
- divdu(o)(.) rD, rA, rB
- rAとrBとの64bit符号なし除算結果をrDに格納する。
- divwu(o)(.) rD, rA, rB
- 32bitモードにもある命令。
rAとrBとの32bit符号なし除算結果をrDに格納する。上32bitの内容は未定義になる。
- mulhd(.) rD, rA, rB
- rAとrBとの64bit符号付き乗算結果の上64bitをrDに格納する。
- mulhdu(.) rD, rA, rB
- rAとrBとの64bit符号なし乗算結果の上64bitをrDに格納する。
- mulhw(.) rD, rA, rB
- 32bitモードにもある命令。
rAとrBとの、32bitでの符号付き乗算結果の上32bitを、rDの下32bitに格納するという命令となっている。
- mulhwu(.) rD, rA, rB
- 32bitモードにもある命令。
rAとrBとの、32bitでの符号なし乗算結果の上32bitを、rDの下32bitに格納するという命令となっている。
- mulli rD, rA, SIMM
- 32bitモードにもある命令。
rAと16bit符号付き整数との、64bitでの乗算結果の下64bitをrDに格納する、となっている。
- mulld(o)(.) rD, rA, rB
- rAとrBとの64bit乗算結果の下64bitをrDに格納する。
- mullw rD, rA, rB
- 32bitモードにもある命令。
rAとrBとの、32bitでの乗算結果をrDに格納する、となっている。
論理演算命令
64bitモードの場合、これらの命令に付加する処理(キャリービットの格納や条件テスト)は、64bitとしての計算結果が反映されるようになった。既存の命令のほとんどは、命令実行サイズが64bitになった以外変わりはないが、シフトとマスクを実行する命令は大量に追加された。
なお、32bit用の論理演算命令(slw, srw, rlwinm, rlwnm, rlwimiといった命令)は、64bit演算において、上32bitを0クリアする。
- clrldi(.) rA, rS, n
- rSの下からnバイト目までを取り出してrAに格納する。rldicl rA, rS, 0, nで実現。
- clrrdi(.) rA, rS, n
- rSの下からnバイト目までを0にしてrAに格納する。rldicr rA, rS, 0, 63 - nで実現。
- cntlzd(.) rA, rS
- rSの一番上のbitから下に、0の続く数をrAに格納する。値の範囲は0 ~ 64
- cntlzw(.) rA, rS
- 32bitモードにもある命令。
rSの下から31bit目から下に、0の続く数をrAに格納する。ゆえに、値の範囲は0 ~ 32
- extsw(.) rA, rS
- rSの下32bitを符号拡張した値をrAに格納する。
- rldcl(.) rA, rS, rB, MB
- MBは6bitの値(0 ~ 63)。
rSの値をrBの下位6bitの値ぶんだけ左回転シフト後、上からMB bit目までの値を0クリア(MB bit目はクリアしない)し、rAに格納する。
- rldcr(.) rA, rS, rB, ME
- MEは6bitの値(0 ~ 63)。rldclとは逆で、左回転シフト後、下bitから63 - ME bit目までの値を0クリア(ME bit目はクリアしない)し、rAに格納する。
- rldic(.) rA, rS, SH, MB
- SH、MBは6bitの値(0 ~ 63)。
SHの値分だけ左回転シフト後、上からMB bit目から、上から63 - SH目までを残し、他を0クリアして、rAに格納する。63 - SH > MBの場合、マスク範囲はループする。
- rldicl(.) rA, rS, SH, MB
- rldclのrBの代わりに即値を利用する命令。簡略ニーモニックsrdi clrldi
- rldicr(.) rA, rS, SH, MB
- rldcrのrBの代わりに即値を利用する命令。簡略ニーモニックsldi clrrdi
- rldimi(.) rA, rS, SH, MB
- rSの値をSHの値ぶんだけ左回転シフト後、上bitからMB bit目から、上bitから63 - SH bit目までをrAに挿入する。63 - SH > MBの場合、マスク範囲はループする。
- sld(.) rA, rS, rB
- rSの値をrBの値ぶんだけ64bit左シフトしてrAに格納する。
slwは32bit整数用だが、この命令は64bit整数用である。
- sldi(.) rA, rS, u6
- rSの値を即値u6の値ぶんだけ64bit左シフトしてrAに格納する。rldicl rA, rS, n, 63 - nで実現。
- srad(.) rA, rS, rB
- rSの値をrBの値ぶんだけ64bit右算術シフトしてrAに格納する。
srawは32bit整数用だが、この命令は64bit整数用である。
- srd(.) rA, rS, rB
- rSの値をrBの値ぶんだけ64bit右論理シフトしてrAに格納する。
srwは32bit整数用だが、この命令は64bit整数用である。
- srdi(.) rA, rS, u6
- rSの値を即値u6の値ぶんだけ64bit右論理シフトしてrAに格納する。rldicl rA, rS, 64 - n, nで実現。
浮動小数演算命令
通常PowerPC命令は変わらず、整数と浮動小数との変換命令が増えたのみである。
- fcfid(.) fD, fB
- fBの値を64bit符号付き整数値として64bit倍精度浮動小数に変換し、fDに格納する。
- fctid(.) fD, fB
- fBの値を64bit符号付き整数に変換してfDに格納する。小数の丸め方は、FPSCR[RN]で指定された方法。
- fctidz(.) fD, fB
- fBの値を64bit符号付き整数値に変換し、fDに格納する。小数は切り捨て。
データ転送命令
汎用レジスタが64bitに拡張されたため、32bitデータの符号付きロードと、64bitデータのロード/ストア命令が追加された。今までの4byteロード命令は、符号なしロード命令となる。
また、32bitモードでは、汎用レジスタの上32bitは無視され、下32bitだけでメモリにアクセスされる。
64bitモードでは、lmwやstmwは下32bitしか格納しないので、使うと危険。なぜかlwau(符号あり4byteロード+更新)は存在しないようだ…
- lwa rD, d(rA)
- rAの値(r0の場合は0)と16bit符号付き整数との和をメモリアドレス位置として、rDに4byte符号付き整数をロードする。4の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- lwaux rD, rA, rB
- rAの値とrBとの和をメモリアドレス位置として、rDに4byte符号付き整数をロードする。さらに、rAにはこの命令で読み込んだメモリアドレスが格納される。4の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- lwax rD, rA, rB
- rAの値(r0の場合は0)とrBとの和をメモリアドレス位置として、rDに4byte符号付き整数をロードする。4の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- ld rD, d(rA)
- rAの値(r0の場合は0)と16bit符号付き整数×8との和をメモリアドレス位置として、rDに8byte整数をロードする。8の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- ldu rD, d(rA)
- rAの値と16bit符号付き整数×8との和をメモリアドレス位置として、rDに8byte整数をロードする。さらに、rAにはこの命令で読み込んだメモリアドレスが格納される。8の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- ldux rD, rA, rB
- rAの値とrBとの和をメモリアドレス位置として、rDに8byte整数をロードする。さらに、rAにはこの命令で読み込んだメモリアドレスが格納される。8の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- ldx rD, rA, rB
- rAの値(r0の場合は0)とrBとの和をメモリアドレス位置として、rDに8byte符号付き整数をロードする。8の倍数のアドレスから読み込む方がメモリアクセス効率がいい。
- std rS, d(rA)
- rSの8byteを、rA(r0の時は0)と16bit符号付き即値d×8との和のアドレスのメモリに格納する。メモリアドレスが8の倍数であるほうが効率がいい。
- stdu rS, d(rA)
- rSの8byteを、rAと16bit符号付き即値d×8との和のアドレスのメモリに格納する。さらに、rAにはこの命令で書き出したメモリアドレスが格納される。メモリアドレスが8の倍数であるほうが効率がいい。
- stdux rS, rA, rB
- rSの8byteを、rAとrBとの和のアドレスのメモリに格納する。さらに、rAにはこの命令で書き出したメモリアドレスが格納される。メモリアドレスが8の倍数であるほうが効率がいい。
- stdx rS, rA, rB
- rSの8byte全てを、rA(r0の時は0)とrBとの和のアドレスのメモリに格納する。メモリアドレスが8の倍数であるほうが効率がいい。
条件比較命令
PowerPCの汎用レジスタ比較命令には、全て'L'というフラグが存在する。通常のPowerPCでは、これらには必ず0を入れなければならなかった。G5では、Lに1を入れた場合、比較命令を64bit整数同士の比較とみなし、Lに0を入れた場合、比較命令を32bit整数同士の比較とみなす。
つまり、普通のPowerPCの比較命令の簡略ニーモニック(cmpw, cmpwi, cmplw, cmplwi)を使った場合、上32bitを無視し、下32bitのみで、32bit整数として比較を行う。これにともない、新しく簡略ニーモニックが追加された。
- cmpd (crD,) rS, rB
- rSとrBとの64bitでの算術比較結果をcrD(なければcr0)に格納する。
この命令は、cmp crD, 1, rS, rBで実現されている。
- cmpdi (crD,) rS, SIMM
- rSと16bit符号付き整数との64bitでの算術比較結果をcrD(なければcr0)に格納する。
この命令は、cmpi crD, 1, rS, SIMMで実現されている。
- cmpld (crD,) rS, rB
- rSとrBとの64bitでの論理比較結果をcrD(なければcr0)に格納する。
この命令は、cmpl crD, 1, rS, rBで実現されている。
- cmpldi (crD,) rS, UIMM
- rSと16bit符号なし整数との64bitでの論理比較結果をcrD(なければcr0)に格納する。
この命令は、cmpli crD, 1, rS, UIMMで実現されている。
分岐命令
基本的に、分岐命令には変更はなく普通に使えるが、G5においては分岐ヒントが、『分岐を期待』(++)『分岐なしを期待』(--)『弱く分岐を期待』(+)『弱く分岐なしを期待』(-)に増えている。
トラップ命令
そもそもPowerPCのトラップ命令の説明を確認してないので、変更点があまりわからないが、64bitトラップ命令が追加されたようだ。