その他の命令

特殊目的レジスタ転送命令

汎用レジスタ以外の特殊目的レジスタの内容を読み出したり、設定したりする場合は専用の命令を使って、汎用レジスタを経由して行います。

ニーモニックの意味
mcrf Move Condition Register Field
mcrxr Move to Condition Register from XER
mfcr Move From Condition Register
mfspr Move From Special-Purpose Register
mtcrf Move To Condition Register Fields
mtspr Move To Special-Purpose Register

mfspr/mtspr

特殊目的レジスタ転送命令の中で重要な命令が、mfspr/mtspr です。ユーザモードで使用するレジスタに関しては、拡張ニーモニックが使用できます。

拡張ニーモニック 標準ニーモニック 転送対象レジスタ 説明
mfxer mfspr , rD,1 XER XER から rD
mtxer mfspr , rD,1 XER rD から XER
mflr mfspr , rD,8 LR LR から rD
mtlr mfspr , rD,8 LR rD から LR
mfctr mfspr , rD,9 CTR CTR から rD
mtctr mfspr , rD,9 CTR rD から CTR

標準ニーモニックのオペランドの数値は特殊目的レジスタの種類を指定する番号で、特権モードのみで使用できるレジスタも含めると以下のレジスタがあります。

10進 2進 レジスタ モード
1 00000 00001 XER ユーザ 例外
8 00000 01000 LR ユーザ リンク
9 00000 01001 CTR ユーザ カウント
18 00000 10010 DSISR 特権
19 00000 10011 DAR 特権 データアドレスレジスタ
22 00000 10110 DEC 特権 デクリメントカウンタ
25 00000 11001 SDR1 特権
26 00000 11010 SRR0 特権 例外時のアドレス
27 00000 11011 SRR1 特権 マシン状態の保持
272 01000 10000 SPRG0 特権 OS用レジスタ
273 01000 10001 SPRG1 特権 OS用レジスタ
274 01000 10010 SPRG2 特権 OS用レジスタ
275 01000 10011 SPRG3 特権 OS用レジスタ
282 01000 11010 EAR 特権 外部アクセスレジスタ
287 01000 11111 PVR 特権 プロセッサバージョンレジスタ
528 10000 10000 IBAT0U 特権
529 10000 10001 IBAT0L 特権
530 10000 10010 IBAT1U 特権
531 10000 10011 IBAT1L 特権
532 10000 10100 IBAT2U 特権
533 10000 10101 IBAT2L 特権
534 10000 10110 IBAT3U 特権
535 10000 10111 IBAT3L 特権
536 10000 11000 DBAT0U 特権
537 10000 11001 DBAT0L 特権
538 10000 11010 DBAT1U 特権
539 10000 11011 DBAT1L 特権
540 10000 11100 DBAT2U 特権
541 10000 11101 DBAT2L 特権
542 10000 11110 DBAT3U 特権
543 10000 11111 DBAT3L 特権
1013 11111 10101 DABR 特権

リンクレジスタの保存と復帰

特殊目的レジスタ転送命令の中で最も重要な命令が mflr / mtlr です。PowerPC ではサブルーチンコールを行う場合の戻りアドレスはスタックではなく、LR レジスタに保存されます。サブルーチンの中から、さらにサブルーチンを呼ぶと LR レジスタが上書きされてしまうため外側のサブルーチンは呼び出し元に戻れなくなります。このため通常サブルーチンの最初で LR レジスタを保存し、最後で LR レジスタを復帰する必要があります。このとき mflr で LR レジスタの内容を汎用レジスタに転送し、mtlr で汎用レジスタから LR レジスタ に書き戻します。汎用レジスタに転送された LR レジスタの値はスタックに保存したり、転送した汎用レジスタが使われない場合は、そのまま LR レジスタの復帰に使用されます。

Subroutine:
        mflr    r4                      # lr を r4 に転送
        stwu    r4, -4(r1)              # r4 をスタックに保存
         : 何か処理
        lwz     r4, 0(r1)               # スタックから lr の値をr4に転送
        mtlr    r4                      # r4 から lr に転送
        addi    r1, r1, 4               # スタックを戻す
        blr                             # 呼び出し元へ分岐(return)

条件レジスタ論理演算命令

条件レジスタは4つのビットからなる8組 (cr0-cr7) の条件を保持することができます。 8組のうちの任意の2組のビット間で論理演算を行うことができます。比較命令(cmp)や条件分岐命令ではデフォルトではcr0が指定されたことになりますが、使用する条件を cr0 から cr7 を指定することが可能です。

ニーモニックの意味
crand Condition Register AND
crandc Condition Register AND with Complement
creqv Condition Register EQuiValent
crnand Condition Register NAND
crnor Condition Register NOR
cror Condition Register OR
crorc Condition Register OR with Complement
crxor Condition Register XOR

次のコードは r10 に格納されている文字が「0」から「9」の範囲かどうかをチェックするものです。「0」との比較結果を cr2 に格納し、「9」との比較を cr3 に格納して、cror でサマリーオーバフロービットに結果を入れます。複数の比較を条件レジスタ論理演算命令で一度に処理することで分岐命令を減らすことができます。

IsNum:  cmpwi   cr2, r10, '0'           # r10 < '0'  cr2[lt]=1
        cmpwi   cr3, r10, '9'           # r10 > '9'  cr3[gt]=1
        cror    3, 8, 13                # cr0[so] = cr2[lt] | cr3[gt]
        blr

条件レジスタ論理演算命令で条件レジスタの任意のビットをセット/リセットすることができます。同じ値を「XOR」すると結果は 0 になるため、次のように適当なビット(以下の例ではcr2[lt])を「XOR」して cr0[so] をクリアします。

        crxor   3, 8, 8                 # cr0[so]=0

同様に同じ値を「EQV」すると結果は 1 になるため、適当なビット(以下の例ではcr2[lt])を「EQV」して cr0[so] をセットします。

        creqv   3, 8, 8                 # cr0[so]=1

その他の命令

符号拡張

ニーモニックの意味
extsb[.] EXTend Sign Byte
extsh[.] EXTend Sign Halfword

8bitの値を32ビットに符号拡張する。ビット24(下位の8ビット目)を上位の3バイトにコピーします。 16bitの値を32ビットに符号拡張する。ビット16(下位の8ビット目)を上位の2バイトにコピーします。

上位ビットの0の計数

ニーモニックの意味
cntlzw[.] CouNT Leading Zeros Word

最上位ビット(ビット0)から連続する 0 の数を数えます。

システムコール

ニーモニックの意味
sc System Call

システムコールを呼び出します。Linux では以下に示すようにレジスタに値を設定して実行します。

レジスタ
r0 システムコール番号
r3 システムコールの第1引数
r4 システムコールの第2引数
r5 システムコールの第3引数
r6 システムコールの第4引数
r7 システムコールの第5引数

        .text
        .align 2
        .global _start
_start:
        lis     r4, msg@ha         # msg のアドレス上位
        addi    r4, r4, msg@l      # msg のアドレス下位
        li      r3, 1              # 標準出力のファイルディスクリプタ
        li      r5, 13             # 出力文字数
        li      r0, 4              # write のシステムコール番号
        sc                         # システムコール
        li      r3, 0              # 終了コード
        li      r0, 1              # プロセス終了のシステムコール
        sc                         # システムコール
msg:
        .asciz "Hello, World\n"

アセンブル、リンクして実行すると:

$ as -mregnames -o hello hello.s
$ ld -o hello hello.o
$ ./hello
Hello, World

その他の命令

ユーザモードで実行できますが、使うことはないと思いますので、以下の命令の解説は省略します。

ニーモニックの意味
tw Trap Word
twi Trap Word Immediate
sync SYNChronize

まとめ

以上で PowerPC の命令を一通り見てきました。 PowerPC の命令は、読み書きの対象となるメモリアドレスの指定方法(アドレッシングモード)が単純である一方、ネイティブなニーモニックが複雑(人間向きでない)です。読みやすくするためアセンブラに拡張ニーモニックが用意されているため、複雑な命令に関しては拡張ニーモニックを使うことが多くなると思います。


条件比較命令で変化する条件レジスタが 8 セットあり、比較命令でフラグを設定する条件レジスタを指定することができ、各セット間の論理演算が可能な点と分岐命令の分岐条件に条件レジスタの 8セットのうちの1つを指定できる部分は他のCPUにはない特徴になっています。