その他の命令
特殊目的レジスタ転送命令
汎用レジスタ以外の特殊目的レジスタの内容を読み出したり、設定したりする場合は専用の命令を使って、汎用レジスタを経由して行います。
| ニーモニックの意味 | |
|---|---|
| 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にはない特徴になっています。