« 2014年5月 | トップページ | 2014年7月 »

2014年6月

2014/06/29

命令セットアーキテクチャを考える (番外編) 積和演算命令について再考

その4(命令コード)で、

> ・積和演算命令は備えない(4オペランド必要になるので)

としていますが、積和演算命令は科学技術計算や画像処理・信号処理などで多様されるので、やはり実装したほうがいいのかなと考えてみました。

「ぼくのかんがえたさいきょうのめいれいせっと」では、積和演算が必要な場合、特に短精度データ(単精度の間違いではありません)の場合には、SIMDモード命令と水平演算命令を組み合わせることで、比較的高性能(少ない命令数と少ないクロック数)で実現できると考えていました。

例えば、単精度実数による4次元ベクトルA=(a1,a2,a3,a4)とB=(b1,b2,b3,b4)の内積を計算する場合には以下のようにプログラミングできます。

アドレスAから連続する4ワードにa1,a2,a3,a4が格納され、アドレスBから連続する4ワードにb1,b2,b3,b4が格納されており、その内積をアドレスCに格納するとします。

A: dc float"a1","a2","a3","a4" # dcは定数を定義する(define constant)アセンブラ命令
B: dc float"b1","b2","b3","b4" # 同上
C: da float # daは領域確保を定義する(define area)アセンブラ命令

lea R0,=A,R1 # R1にアドレスAを格納する : offset値(=A)は、アセンブラがPC相対アドレスを計算する
lea R0,=B,R2 # R2にアドレスBを格納する : 同上
lea R0,=C,R3 # R3にアドレスCを格納する : 同上

fldm 2 R1,=0,FR2 # FR2,FR3にベクトルAを格納する
fldm 2 R2,=0,FR4 # FR4,FR5にベクトルBを格納する

fadd v sp FR0,FR0,FR6 # FR6,FR7,FR8,FR9に単精度実数0.0×8個を格納する
fmul v sp FR2,FR4,FR6 # FR6,FR7にa1*b1,a2*b2,a3*b3,a4*b4を単精度実数として計算し、格納する
fhadd sp FR6,FR1 # FR1の下位32bitに、FR6,FR7,FR8,FR9に格納されているa1*b1,a2*b2,a3*b3,a4*b4と0.0*0.0×4個の総和を計算して格納する

fstore sp R3,=0,FR1 # FR1の下位32bitの内容をアドレスCに格納する

アドレス計算やload/store、それにSIMDモード命令のパックドデータ数の調整のためのレジスタクリアを除けば、SIMDモード乗算命令と水平加算命令の計2命令で実現できます。積和演算というくらいなのでベクトル演算を除けば乗算と加算命令で実現できるのは当たり前ですが。ただ、ややこしいといえばややこしいので、積和演算命令(SIMDモード付き)ができれば当然そのほうがプログラマ的にも便利でしょう。


積和演算命令を備えない理由として、4オペランド必要になることを挙げていました。
が、上記の内積計算のように、多くの積和計算処理では各要素データの乗算結果の総和をとるような計算が多いので、A×B+C→DでなくてA×B+C→Cでも、多くの場合、Cの元の値を別レジスタに保存しておく必要はなさそうです。ディストネーションオペランドの意味が微妙に違ってきてしまいますが、眼を瞑ることにして、命令コードフォーマットの問題はひとまず解決とします。


ところが、浮動小数点演算命令はすでに16種類あり、命令コードを「綺麗な形式」で浮動小数点積和演算命令を追加することができません。整数演算命令も命令コードのビットパターンに空きがありません。
命令コードが綺麗な形式で定義できないと、前提条件で書いたような「ダンプデータをみてもプログラムが読める」目的からはずれていってしまいますので好ましくありません。

浮動小数点演算命令の場合は、番外編の「本当の汎用レジスタセット」に書いたように、汎用レジスタと浮動小数点レジスタ間の単純データ転送命令(ビットパターンのままの転送命令)を省略することができれば、この問題は解決します。

(修正)命令数を数え直したら、浮動小数点演算命令は全部で15種類でした(その13は修正しました)。ということで、上記のような変更を加えなくても、命令の追加は可能です。また、逆数の近似値命令と平方根の逆数の近似値命令を、即値ビットを使ってモード指定するようにすれば、命令コードをもう一つ空けることもできます。


整数演算命令の命令コードビットパターンは、load/store/分岐命令が7種類、ビット演算命令も7種類なのでここに埋め込むことも可能です。あまり「綺麗な形式」とはいえませんが。できれば、四則演算命令のパターンのところに追加したいのですが、四則演算というくらいなので命令4種類、それぞれに符号付き二進数と符号なし二進数の場合があるので合計8種類になり、空きがありません。
符号付きと符号なしをどこかの空きビットを使ってモード設定できればいいのですが、その空きビットもありません。即値を10bit指定から減らせば可能ですが、分岐命令のoffset範囲が半分に減っちゃうのは結構影響が大きいように思います。

スワップ命令(1)をビット演算命令(7)のグループと一緒にして、水平演算命令(7)のグループに積和演算命令を追加するのが、比較的綺麗そうですね。


ところで、整数の積和演算命令って必要ですかね。
信号処理などのデジタル化データの場合は浮動小数点データではなくて整数の場合も多いと思います。この命令セットではDSPのような用途は想定していませんけど、静止画像処理とか動画像処理とかは、「普通の」PCやワークステーションでも多く利用される用途でしょう。ってことはやはりあったほうがよさそうです。それに、浮動小数点データのみに積和演算命令を追加というのは、綺麗じゃないですよね。

結論はでないまま、今日のところはここまで。

| | コメント (0) | トラックバック (0)

2014/06/28

命令セットアーキテクチャを考える (番外編) 本当の汎用レジスタ

ほとんどのCPUアーキテクチャでは、整数演算/論理演算/ビット操作等用の汎用レジスタと、浮動小数点レジスタは別構成となっています。「ぼくのかんがえたさいきょうのめいれいせっと」シリーズでもそれにならって、汎用レジスタ×64本と浮動小数点レジスタ×64本の構成としました。

汎用レジスタと浮動小数点レジスタを別構成にするというのは、おそらく浮動小数点演算ユニットが電子回路的に複雑でチップ面積をたくさん必要とするとか、処理クロックもたくさん掛かるとかなどで、浮動小数点演算ユニットが使うレジスタも、汎用レジスタとは別回路として演算回路の近くに配置しよう、というような理由じゃないかと想像しています。というか、浮動小数点演算はコプロセッサとして別チップだったという歴史的な背景もあるように思います。

一方で、アプリケーションプログラマからみると、汎用レジスタも浮動小数点レジスタも、演算用にデータを一時的に置いておくところという意味では同じです。別になっていなければならない理由はありません。むしろ、load/store型アーキテクチャでは、浮動小数点レジスタにどのようにデータを詰め込むか、あるいは取り出すかということを、汎用レジスタとは別に考えなければならなくなります。
「ぼくのかんがえたさいきょうのめいれいせっと」アーキテクチャでも、浮動小数点レジスタ用のメモリデータアクセス(load/store)命令と、汎用レジスタ⇔浮動小数点レジスタ間のビットパターン転送命令を追加しました。

電子回路的なことは無視すると、同一のレジスタを整数演算命令が操作するときは整数データとして、浮動小数点数演算命令が操作するときは浮動小数点数データとして扱うようにできれば、便利になりそうです。

「ぼくのかんがえたさいきょうのめいれいせっと」アーキテクチャは、64本ものレジスタを持っており、最近主流のCPUアーキテクチャはだいたい32本であることを考えると、64本が汎用/浮動小数点レジスタ兼用という「本当の汎用」レジスタにしても、レジスタ本数が少なくて不便ということは少ないと考えられます。

| | コメント (0) | トラックバック (0)

2014/06/22

「はてな」を退会しました

「はてな」から、不正ログインのお詫びとパスワード変更のお願いのメールがきていましたが、「はてな」に登録していたことさえすっかりと忘れてしまっていました。これを機会に、パスワード変更ではなくて、退会手続きを行いました。

きっとこんなような休眠アカウントがあちこちにあるんだろうなぁと思うと、ちょっと気持ち悪いです。

| | コメント (0) | トラックバック (0)

マザボ変更その後(その3)

やはりSETI@homeを動かしているとよくフリーズするような気がします。
もうひとつ、なんとなくですが、フリーズするタイミングはインターネットと通信しているときのような気がします。

ふたつ合わせると、「CPU負荷が高い時に通信処理が入るとフリーズするような気がする」ので、オンボードNICのドライバの品質が悪いんじゃないかと推測しています(邪推かも)。

| | コメント (0) | トラックバック (0)

2014/06/21

命令セットアーキテクチャを考える13 (命令コード)

命令コードフォーマットのうちopcode 6bitの割り当て概略案です。

opcodeの構成(上位3bit)

000 : load/store(4) + 分岐(branch/jump)命令(4)
001 : 整数演算命令(四則演算)(6)
010 : 水平演算(7) + スワップ命令(1)
011 : 論理演算命令(3) + シフト命令(5)
100 : 浮動小数点演算命令(15)
101 : 同上
110 : bit操作命令(7)
111 : special

# loop命令を追加したため、分岐命令の数を3→4に変更しました。(2018/03/21)
# add/subの符号なし命令を削除したため、整数演算命令の数を8→4に変更しました。(2018/03/21)

これで上位3bitを見るだけで、どういった命令かがわかるようになります。

その4で書いた、命令コードフォーマットのちょっと変態なビット割り付けの理由がここでわかります。

最初の前提条件で書いたように、「16進ダンプを見てもプログラムがわかるのが理想」なのですが、いろいろとやって見ても難しかったので、それじゃぁ「8進ダンプならどうか」って考えました。実は、64本というレジスタ本数も6bitで表現できるということが理由です。8bit(256本)にしたらもっと良かったのですが、残念ながら3オペランド命令形式では、レジスタ指定ビットだけで24bit使っちゃうので、命令コードが入りません。

その4で書いた命令コードフォーマットですが、ちょっと変則的に16bit(2バイト)単位に下位から3bitずつ区切ると区切りやすいようなっています。


[命令コードフォーマット]

bit[31:28] : Mode(1+1+2) :vector/PC相対/increment,imm/offset,データ長
bit[27:22] : OPcode(6)
bit[21:16] : Rs(6)
bit[15:6] : imm/offset(10) : imm/offsetとRtはどちらか一方
bit[11:6] : Rt(6)
bit[5:0] : Rd(6)


とりあえず、このシリーズはいったん終了です。

| | コメント (0) | トラックバック (0)

2014/06/20

命令セットアーキテクチャを考える12 (特殊命令)

その他、特殊命令関係です。知識がないため未検討です。多分こんな命令が必要なはず、と想像しています。


[モード遷移命令群]
・supervisor-mode/user-mode切り換えなど

[同期/排他制御用命令群]
・セマフォ、バリア命令など

[暗号化支援]
・暗号化/復号化、キー生成

[仮想化支援]
・よくわかりません

[特殊レジスタアクセス命令]
・よくわかりません

[省電力支援]
・よくわかりません


とりあえず、前提が、アプリケーションプログラマから見た命令セットということで始めましたので、上記のような機能はOSのサービスを呼び出すということでゴニョゴニョ…

| | コメント (0) | トラックバック (0)

2014/06/16

命令セットアーキテクチャを考える11 (分岐命令)

ようやく終わりに近づいてきました。分岐命令です。


[Jump/Branch]:4命令

条件付き分岐はbranch(br)、無条件分岐はjump(jmp)と称する

brl [pc] Rs,=imm,Rd

・CCR0/CCR1の状態がimmで指定される条件に合致する場合に、Rsで指定したアドレスに分岐し、Rdには戻りアドレスとして現在のPCの値が格納される(branch and link)。
・pcモードの場合は、PCの内容とRsの内容を加算したアドレスに分岐する。
・CCR0/CCR1は変化しない。

・imm(10bit)による分岐条件の詳細は以下の通り。
・bit9:CCR0かCCR1を指定(どちらか一方のみ)
・bit8:bit0-bit7が、CCR0/CCR1の各ビットと複数マッチした場合に、その論理積(and)をとるか論理和(or)をとるかを指定
・bit7-bit0:CCR0またはCCR1の対応するビットが"1"である場合に条件成立とする

・ここで、CCR0とCCR1の内容を再掲しておきます。

[CCR0]
bit4: Overflow/Carryover(o) : Overflow
bit3: Underflow/Borrow(u) : Underflow
bit2: positive/plus(p) : Positive
bit1: zero(z) : Zero
bit0: negative/minus(m) : Minus

[CCR1]
bit7: 非正規化数(s) : Subnormal number
bit6: 無限大(i) : Infinite number
bit5: NaN(n) : Not a number
bit4: Overflow : Overflow
bit3: Underflow : Underflow
bit2: positive/plus(p) : Positive
bit1: zero(z) : Zero
bit0: negative/minus(m) : Minus


・戻りアドレスを格納しない(branch and linkではない)branch命令はない。戻りアドレスが不要な場合はRdとしてR0を指定する。


jmpl [pc] Rs,{Rt|=offset},Rd

・Rs及びRtまたはoffsetで指定したアドレスに分岐し、Rdには戻りアドレスとして現在のPCの値が格納される(jump and link)。
・分岐先アドレスの計算は、RsとRtの和、またはRsと(offset値の4倍)の和となる。
・アセンブラ言語ソースプログラムではoffsetの値はそのまま記述し、アセンブラが1/4してoffset領域に設定する。
・pcモードの場合は、さらにPCの内容を加算したアドレスに分岐する。
・CCR0/CCR1は変化しない。

・戻りアドレスを格納しない(jump and linkではない)jump命令はない。戻りアドレスが不要な場合はRdとしてR0を指定する。

# 命令コードに余裕がありましたので、loop命令を追加しました。(2018/03/21)

loop [pc] Rs,{Rt|=offset},Rd

・Rdの内容を1減算し、0でなければRs及びRtまたはoffsetで指定したアドレスに分岐する。
・1減算後のRdの内容が0であれば、なにもしない。
・分岐先アドレスの計算は、RsとRtの和、またはRsと(offset値の4倍)の和となる。
・アセンブラ言語ソースプログラムではoffsetの値はそのまま記述し、アセンブラが1/4してoffset領域に設定する。
・pcモードの場合は、さらにPCの内容を加算したアドレスに分岐する。
・CCR0/CCR1は変化しない。

lea Rs,{Rt|=offset},Rd

・分岐ではないが、おなじようにアドレス計算するということで、ここの括りに入っています。
・PCとRsとRtの和、またはPCとRsと(offset値の4倍)の和を計算し、Rdに格納する。
・アセンブラ言語ソースプログラムではoffsetの値はそのまま記述し、アセンブラが1/4してoffset領域に設定する。


[擬似命令]

nop → jmpl pc R0,R0,R0

・PCの指すアドレス(次の実行番地)にジャンプするのでnop(No Operation)となる。
・そもそも、すべて固定長命令フォーマットであり、かつ遅延スロットもないのでnopは不要なような気もしますが…
・copy R0,R0,R0でも代用可能。但し、condition codeが変化する


opfch → brl Rs,=#3ff,R0 :

・opfch(operation code fetch)命令は、必ず不成立となる条件付き分岐命令に変換される。
・分岐は必ず失敗するが、分岐先アドレスの命令データfetch処理が途中まで進むため、L1命令キャッシュが読み込まれる。

br [r] Rs,=imm → brl [pc] Rs,=imm,R0
jmp [r] Rs,Rt → jmpl [pc] Rs,Rt,R0

・戻りリンク無しの分岐命令はないが、アセンブラ言語ソースプログラムの見やすさのため、リンク無し分岐命令のような擬似命令を用意した。アセンブラがリンクアドレス格納レジスタをR0と設定する。


branch命令の条件コードをimm値として記述するのはややこしいため、アセンブラで以下のような擬似命令を備える。

brleq Rs,Rd → brl Rs,=#102,Rd : z-flg on
brlne Rs,Rd → brl Rs,=#005,Rd : p-flg on or m-flg on
brlge Rs,Rd → brl Rs,=#006,Rd : p-flg on or z-flg on
...
breqf Rs → br Rs,=#302 : z-flg on
brnef Rs → br Rs,=#105 : p-flg on or m-flg on
brgef Rs → br Rs,=#106 : p-flg on or z-flg on
...

| | コメント (0) | トラックバック (0)

2014/06/14

マザボ変更その後(その2)

あまりにもよくフリーズするので、昨夜、マザボのBIOSアップデートを行いました。BIOSアップデート自体はちゃんと終わったのですが、Windowsシステムが起動できなくなってしまいました。ということで、24時を超えた時点からWindowsの再インストールを行っていました。

各種のプログラムインストールやパッチ当てで何度も再起動はしていますが、それ以外ではシステム動作中にフリーズしてしまうようなことにはまだ一度もあっていません。BIOSアップデートで問題解決したということならいいのですが。

ここまで書いてきて、もしかして同様の現象でお困りの方がここにたどり着いたとしても、参考になるかどうかの基本情報がなんにもないことに気づきました。最低限の情報だけ書いておきます。

MB : MSI A88X-G43
CPU: AMD A10-7850
MEM: DDR3-1866 4MB×2
OS : Windows7 professional 32bit

(追記)やっぱりフリーズするのは完全解決にはなっていません。あれから二度フリーズしました。ただ、BIOSアップデート以降は頻度は減っているように思います。

| | コメント (0) | トラックバック (0)

2014/06/13

命令セットアーキテクチャを考える10 (浮動小数点数演算命令)

ようやく、浮動小数点演算命令にたどり着きました。


[浮動小数点数演算命令]:6命令

fadd [v] [sp|dp|qp] FRs,FRt,FRd

・FRsとFRtの内容を浮動小数点数として加算した結果をFRdに格納する。
・単精度モードの場合、FRs及びFRtの下位32ビットを単精度浮動小数点数として計算し、FRdの下位32ビットに格納する。
・倍精度モードの場合、FRs及びFRtの64ビットを倍精度浮動小数点数として計算し、FRdの64ビットに格納する。
・四倍精度モードの場合、FRs及びFRtのそれぞれ連続する二本のレジスタを連結した128ビットを四倍精度浮動小数点数として計算し、FRdの連続する二本のレジスタに格納する。FRs,FRt,FRdはすべて偶数レジスタでなくてはならない。
・計算結果によって、CCR1の内容がセットされる。

・SIMDモードの場合、FRs及びFRtのぞれぞれ連続する四本のレジスタを使って、32bit*8、64bit*4、128bit*2のデータとして演算に使用される。結果は、FRdの連続する四本のレジスタに32bit*8、64bit*4、128bit*2として格納される。
・SIMDモードの場合、CCR1は変化しない。結果の絶対値が最大値を超えた場合には符号付きの最大値が、計算できない場合にはNaNが返る。
・SIMDモードの場合、レジスタ番号はすべて偶数でなくてはならない。(4の倍数でなくてもよい) レジスタ番号としてFR62は指定できない。

fsub [v] [sp|dp|qp] FRs,FRt,FRd

・FRsの内容からFRtの内容を減算するほかはfaddと同様。

fmult [v] [sp|dp|qp] FRs,FRt,FRd

・FRsの内容とFRtの内容を乗算するほかはfaddと同様。

fdiv [v] [sp|dp|qp] FRs,FRt,FRd

・FRsの内容からFRtの内容を除算するほかはfaddと同様。


・正規化数以外(最大値、非正規化数、NaNなど)を含む四則演算結果については別途検討が必要。基本的にはIEEE754に準拠する。


frcp [v] [sp|dp|qp] FRs,FRd

・FRsの逆数(reciprocal)の近似値をFRdに格納する。
・単精度モードの場合、FRs及びFRtの下位32ビットを単精度浮動小数点数として計算し、FRdの下位32ビットに格納する。
・倍精度モードの場合、FRs及びFRtの64ビットを倍精度浮動小数点数として計算し、FRdの64ビットに格納する。
・四倍精度モードの場合、FRs及びFRtのそれぞれ連続する二本のレジスタを連結した128ビットを四倍精度浮動小数点数として計算し、FRdの連続する二本のレジスタに格納する。FRs,FRt,FRdはすべて偶数レジスタでなくてはならない。
・計算結果によって、CCR1の内容がセットされる。FRsの内容がゼロ(正負ともに)の場合は0除算例外が発生する。

・SIMDモードの場合、FRs及びFRtのそれぞれ連続する四本のレジスタを使って、32bit*8、64bit*4、128bit*2のデータとして演算に使用される。結果は、FRdの連続する四本のレジスタに32bit*8、64bit*4、128bit*2として格納される。
・SIMDモードの場合、CCR1は変化しない。0除算例外割り込みも発生しない。(最大値が返る)計算できない場合にはNaNが返る。
・SIMDモードの場合、レジスタ番号はすべて偶数でなくてはならない。(4の倍数でなくてもよい) ただし、FR62は指定できない。

frsqrt [v] [sp|dp|qp] FRs,FRd

・FRsの平方根の逆数(reciprocal of square root)の近似値が格納されるほかはfrcpと同様。
・FRsの内容が負(-0を除く)であった場合には、例外が発生する。FRsの内容がゼロ(±0)の場合にはゼロ除算例外が発生する。


[擬似命令]

fcopy [v] [sp|dp|qp] FRs,FRd

・FRsの内容をFRdにコピーする。
・アセンブラが「fadd [v] [sp|dp|qp] FRs,FR0,FRd」に変換する。

fclear [v] [sp|dp|qp] FRd

・FRdの内容をゼロクリアする。
・アセンブラが「fadd [v] [sp|dp|qp] FR0,FR0,FRd」に変換する。


[水平演算命令]:2命令

fhadd [sp|dp|qp] FRs,FRd

・ニーモニックの先頭の"h"はhorizontalを意味する。
・FRsから連続する四本のFRレジスタの内容を、single*8またはdouble*4またはquad*2の浮動小数点データとして、その総和を計算し、FRdに格納する。FRsは偶数レジスタでなければならない。quadモードの場合はFRdも偶数レジスタでなければならない。

fhmult [sp|dp|qp] FRs,FRd

・乗算であることの他はfhaddと同様。


[特殊定数値ロード命令]:1命令

fspcnum [v] [sp|dp|qp] =imm,FRd

・特殊な定数値(special number)をFRdに格納する。特殊な定数値はimmで指定する。
・imm=0:+0.0、imm=1:+1.0、imm=2:e、imm=3:π …
・immは10ビットあるので、ROMの容量に余裕があれば、最大1024個まで定義できる。
・アセンブラソースプログラム上、即値を直接記述しても分かりにくいので、
zero equ 0
one equ 1
e equ 2
pai equ 3

のように定義しておくと、アセンブラソースプログラムを読みやすく理解しやすくできる。

・四倍精度モードの場合、FRdから連続する二本のレジスタに格納される。FRdは偶数レジスタでなければならない。
・SIMDモードの場合は、FRdから連続する四本のレジスタに、32bit×8、64bit×4、128bit×2個の同じ値が格納される。FRdは偶数レジスタでなければならない。(4の倍数である必要はない)
・ロードした値に基づいてCCR1がセットされる。SIMDモードの場合もCCR1がセットされる。


[精度変換命令]:2命令

fup [sp|dp] FRs,FRd

・FRsの浮動小数点数の精度を拡張し(単精度→倍精度、倍精度→四倍精度)、FRdに格納する。
・倍精度→四倍精度の場合、FRdから連続する二本のレジスタに格納される。FRdは偶数レジスタでなければならない。
・変換後の値に基づいてCCR1がセットされる。

fdown [dp|qp] FRs,FRd

・FRsの浮動小数点数の精度を縮小し(倍精度→単精度、四倍精度→倍精度)、FRdに格納する。
・四倍精度→倍精度の場合、FRsから連続する二本のレジスタに格納されたデータを変換する。FRsは偶数レジスタでなければならない。
・変換後の値に基づいてCCR1がセットされる。

・SIMDモードは必要か。レジスタの使い方が他の命令のSIMDモードとはちょっと変則的になるが。


[擬似命令]

fsp2dp FRs,FRd → fup sp FRs,FRd
fdp2qp FRs.FRd → fup dp FRs,FRd
fqp2dp FRs,FRd → fdown qp FRs,FRd
fdp2sp FRs,FRd → fdown dp FRs,FRd


[汎用レジスタ転送命令]:4

gr2fr [1|2|4|8] Rs,FRd

・Rsで指定される汎用レジスタの内容を、FRdで指定される浮動小数点レジスタにビットパターンとしてコピーする。
・CCR1の内容は変化しない。

fr2gr [1|2|4|8] FRs,Rd

・FRsで指定される浮動小数点レジスタの内容を、Rdで指定される汎用レジスタにビットパターンとしてコピーする。
・CCR0の内容は変化しない。

・複数レジスタ指定は、アセンブラが複数命令に展開したほうがいいか?

int2fp [hw|w|dw] Rs,FRd

・Rsの内容を符号付き二進数とみなし、浮動小数点数に変換し、FRdに格納する。
・half-wordモードの場合はRsの下位16ビットを単精度浮動小数点数に、wordモードの場合はRsの下位32bitを倍精度浮動小数点数に、double-wordモードの場合はRsの64bit全体を四倍精度浮動小数点数に変換する。double-wordモードの場合には、FRdは偶数レジスタである必要がある。
・変換結果に応じて、CCR1をセットする。

fp2int [sp|dp|qp] FRs,Rd

・FRsの内容を整数(符号付き二進数)に変換し、Rdに格納する。小数点以下は切り捨てる。
・単精度/倍精度/四倍精度の浮動小数点数を、すべてdouble-wordの整数に変換する。
・変換結果に応じて、CCR0をセットする。

・丸め方法はIEEE 754の仕様を確認しないといけない…

| | コメント (0) | トラックバック (0)

2014/06/12

命令セットアーキテクチャを考える9 (ビット操作命令)

どんどんいきます。次はビット操作命令です。

[ビット操作命令]:6命令

setbit [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・Rsの内容を、Rtまたはimmで示されるビット位置を"1"にセットし、Rdに格納する。
・セットする元の値によってCCR0を設定(正/零)する。(結果ではなくて、元の値によってCCR0がセットされることに注意)
・byteモード/half-wordモード/wordモードモードの場合、Rsの下位8ビット/16ビット/32ビットのうちの指定ビットのみがセットされ、残りの上位ビットは変更されない。
・byteモード/half-wordモード/wordモード/double-wordモードの場合、Rtまたはimmの下位3ビット/4ビット/5ビット/6ビットのみが有効であり、符号無し二進数とみなされる。

・SIMDモードの場合、Rsレジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとしてそれぞれセットされる。
・SIMDモードの場合、Rtまたはimmの下位ビットが用いられ、すべてのパックドデータに対して同じビット位置がセットされる。
・CCRは変更されない。

clrbit [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・"0"にクリア(clear)するほかはsetbitと同様。

revbit [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・もとのビットを反転(reverse)する("0"→"1"、"1"→"0")ほかはsetbitと同様。


[擬似命令]

tstbit [b|hw|w|dw] Rs,{Rt|=imm}

・指定位置のビット状態をテストする。結果はCCR0にセットされる。(正/零)
・アセンブラが「setbit [b|hw|w|dw]Rs,{Rt|=imm},R0」に翻訳する。Rdにゼロレジスタを指定しているため、CCR0以外はなにも変更されない。


[ビットカウント命令]:4命令

ctzero [v] [b|hw|w|dw] Rs,Rd

・Rs内の"0"ビットの数をカウントし(count zero bits)、Rdに格納する。
・byteモード/half-wordモード/wordモード/double-wordモードでは、Rsの下位8ビット/16ビット/32ビット/64ビット内の"0"ビットの数のみをカウントし、Rdの下位8ビット/16ビット/32ビット/64ビットに格納する。Rdの余った上位ビットは変化しない。
・"0"ビットのカウント数によって、CCR0をセットする。(正/零)

・SIMDモードの場合、Rsレジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとしてそれぞれゼロビットの個数がカウントされ、Rdの対応する領域に格納される。
・CCRは変更されない。

ctbit [v] [b|hw|w|dw] Rs,Rd

・Rs内の"1"ビットを数える(count bits)ほかはctzeroと同様。
・反転してから"0"ビットを数えても同じ結果が得られるので不要とも言えるが…

ctlzero [v] [b|hw|w|dw] Rs,Rd

・上位ビットからの連続した"0"ビットを数える(count leading zero bits) ほかはctzeroと同様。

cttzero [v] [b|hw|w|dw] Rs,Rd

・下位ビットからの連続した"0"ビットを数える(count trailing zero bits)ほかはctzeroと同様。

| | コメント (0) | トラックバック (0)

命令セットアーキテクチャを考える8 (シフト/ローテート/バイトスワップ命令)

続いて、シフト/ローテート/バイトスワップ命令の定義です。


[シフト命令]:4命令

sll [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・Rsの内容を、Rtまたはimmで示されるビット数分、論理左シフト(shift left logical)し、Rdに格納する。
・CCR0は変化しない。
・byteモード/half-wordモード/wordモードモードの場合、Rsの下位8ビット/16ビット/32ビットがシフトされ、残りの上位ビットは変更されない。
・byteモード/half-wordモード/wordモード/double-wordモードの場合、Rtの下位3ビット/4ビット/5ビット/6ビットのみが有効であり、符号無し二進数とみなされる。
・immモードの場合、同様に下位ビットが符号無し二進数とみなされる。

・SIMDモードの場合、Rsレジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとしてシフト演算に使用される。
・SIMDモードの場合、Rtまたはimmの下位ビットが用いられ、すべてのパックドデータに対して同じビット数だけシフトされる。

srl [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・論理右シフト(shift right logical)となることを除いて、sll命令と同様。

sla [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・算術左シフト(shift left arithmetic)となることを除いて、sll命令と同様。

sra [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・算術右シフト(shift right arithmetic)となることを除いて、sll命令と同様。


[ローテート命令]:1命令

rot [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・Rsの内容をRtまたはimmで示されるビット数分だけ左ローテートし、Rdに格納する。(右ローテート命令はないが、ローテート量を大きく指定することにより同じ結果が得られる)
・CCR0は変化しない。
・byteモード/half-wordモード/wordモードモードの場合、Rsの下位8ビット/16ビット/32ビットがシフトされ、残りの上位ビットは変更されない。
・byteモード/half-wordモード/wordモード/double-wordモードの場合、Rtまたはimmの下位3ビット/4ビット/5ビット/6ビットのみが有効であり、符号無し二進数とみなされる。

・SIMDモードの場合、Rsレジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとしてそれぞれローテートされる。
・SIMDモードの場合、Rtまたはimmの下位ビットが用いられ、すべてのパックドデータに対して同じビット数だけローテートされる。


[バイトスワップ命令]:1命令

boswap [hw|w|dw] Rs,Rd

・Rsの内容を2byte/4byte/8byte単位でbyte order swappingしてRdに格納する。
・Rsの内容が16進表記で0123456789ABCDEFであった場合、Rdの内容は以下のようになる。
hwモード :23016745AB89EFCD
w モード :67452301EFCDAB89
dwモード :EFCDAB8967452301

| | コメント (0) | トラックバック (0)

命令セットアーキテクチャを考える7 (論理演算命令)

続いて、論理演算命令を定義します。

[論理演算命令]:6命令

and [b|hw|w|dw] Rs,{Rt|=imm},Rd

・RsとRtの内容をビット単位に論理積をとり、Rdに格納する。
・byteモードの場合は下位8bit、half-wordモードの場合は下位16bit、wordモードの場合は下位32bitのみが演算に使用され、Rdの下位ビットに格納される。使用されない上位ビットは変更されない。
・演算結果を符号なし付き二進数とみなし、CCR0のcondition code bitがセットされる。(正/零/負など)
・Immidiateモードの場合、Rtの代わりにimm(10bit)を指定する。immは、符号なし付き2進数として扱われ、必要に応じて拡張が行われる。

・SIMDモードの場合、レジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとして演算に使用される。
・SIMDモードには、double-word指定はできない。(エラーにはならないが、64bitデータが一つしかないので普通のand命令と同じになる)
・SIMDモードの場合、condition code bitは変化しない。
・SIMDモードで即値指定の場合、第三オペランドは8bit/16bit/32bitに符号拡張されたものが必要回数繰り返しされたものと見なされる。

or [b|hw|w|dw] Rs,{Rt|=imm},Rd

・RsとRtの内容をビット単位に論理和をとり、Rdに格納する。
・その他はand命令と同様である。

xor [b|hw|w|dw] Rs,{Rt|=imm},Rd

・RsとRtの内容をビット単位に排他的論理和をとり、Rdに格納する。
・その他はand命令と同様である。


hand [b|hw|w] Rs,Rd

・ニーモニックの先頭の "h"は、horizontalを意味する。
・byteモードの場合、Rsのレジスタ内容を8bit×8個の論理積を計算し、Rdの下位8bitに格納する。
・同様に、half-wordモードの場合、16bitデータ×4個、wordモードの場合、32bitデータ×2個の論理積を計算する。
・演算結果を符号なし二進数とみなし、CCR0のcondition code bitがセットされる。(正/零など)

hor [b|hw|w] Rs,Rd

・論理和であることを除いて、handと同様。

hxor [b|hw|w] Rs,Rd

・排他的論理和であることを除いて、handと同様。


[擬似命令]

*not [b|hw|w|dw] Rs,Rd xor Rs,R0,Rdxor Rs,=-1,Rd

ゼロレジスタ即値-1(all bit on)との排他的論理和をとることで、論理反転を求める。


# notの擬似命令を間違えていたので、修正しました。即値の符号付き拡張が必要になったので、即値の扱いを符号付き2進数に改めました。それにともない、CCRの設定のための演算結果によるRdの内容の解釈も符号付き2進数に改めました。

| | コメント (0) | トラックバック (0)

2014/06/11

命令セットアーキテクチャを考える6 (整数演算命令)

続いて、整数演算系の命令を定義します。

[整数演算系命令]:12命令


add [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・RsとRtの内容を符号付き二進数として加算し、結果をRdに格納する。
・byteモードの場合は下位8bit、half-wordモードの場合は下位16bit、wordモードの場合は下位32bitのみが演算に使用され、Rdの下位ビットに格納される。使用されない上位ビットは変更されない。
・演算結果により、CCR0のcondition code bitがセットされる。(正/負/零、オーバーフローなど)
・Immidiateモードの場合、Rtの代わりにimm(10bit)を指定する。immは、符号付き2進数として扱われ、必要に応じて符号拡張が行われる。

・SIMDモードの場合、レジスタ内のデータを8bit*8、16bit*4、32bit*2のデータとして演算に使用される。
・SIMDモードには、double-word指定はできない。(エラーにはならないが、64bitデータが一つしかないので普通の加算命令と同じになる)
・condition code bitは変化しない。加算結果が最大値を超えた場合には最大値が、最小値(負数で絶対値が最大のもの)を超えた場合は最小値がセットされる(飽和演算)。
・即値指定の場合、第三オペランドは8bit/16bit/32bitに符号拡張されたものが必要回数繰り返しされたものと見なされる。

sub [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・Rsの内容からRtの内容を減算した結果が、Rdに格納される。
・それ以外は加算命令と同様である。

mult [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・byteモードの場合はRs及びRt(またはimmの符号拡張された値)の下位8bit、half-wordモードの場合は下位16bit、wordモードの場合は下位32bitのみが演算に使用され、Rdの下位ビット16bit、32bit及び64bitに格納こされる。
・double-wordモードの場合、RdとRsの乗算結果、Rd及び連続する汎用レジスタに格納される。Rdは偶数レジスタでなければならない。

・SIMDモードの場合、演算結果は、Rd及び連続する汎用レジスタの下位ビットから格納される。Rdは偶数レジスタでなければならない。

div [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・byteモードの場合は被除数をRs、除数をRt(またはimmの符号拡張された値)とし、byteモードの場合は下位8bit、half-wordモードの場合は下位16bit、wordモードの場合は下位32bit、double-wordモードの場合は64bitすべて演算に使用され、除算結果をRdの下位8bit、16bit、32bit及び64bitに格納し、剰余をRdに連続するレジスタの下位8bit、16bit、32bit及び64bitに格納する。
・Rdは偶数レジスタでなければならない。

・SIMDモードの場合、演算結果は、Rd及び連続する汎用レジスタに格納される。Rdは偶数レジスタでなければならない。
・SIMDモードの場合、0除算割り込みも発生しない。(除算結果として被除数の符号の付いた最大値が返り、剰余として0が返る)

addl [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd
subl [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd
multu [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd
divu [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd

・末尾に"l""u"が付く命令は、logicalunsignedの意味で、符号なし二進数としての演算を行う。
・immも符号なし二進数とみなし、必要に応じて拡張される
・それ以外は符号付き二進数演算命令と同様である。

# 加算と減算は、符号付きも符号なしも計算後のビットパターンは同じなので、別命令とすることをやめた。(2018/03/21)


hadd [b|hw|w] Rs,Rd

・ニーモニックの先頭の "h"は、horizontalを意味する。
・SIMD命令で利用されるパックデータの合計を計算する。
・byteモードの場合、Rsのレジスタ内容を8bit×8個を加算し、Rdの下位8bitに格納する。
・同様に、half-wordモードの場合、16bitデータ×4個、wordモードの場合、32bitデータ×2個を加算する。
・演算結果により、CCR0がセットされる。

haddu [b|hw|w] Rs,Rd

・上記と同様で、符号なし二進数として加算する。

hmult [b|hw|w] Rs,Rd

・haddと同様に乗算。
・演算結果は、Byteモードの場合は下位16bitに、half-wordモードの場合は下位32bitに、wordモードの場合は64bitに格納する。

hmultu [b|hw|w] Rs,Rd

・同様に、符号無し二進数として乗算する。


[擬似命令]

copy [b|hw|w|dw] Rs,Rd → add [b|hw|w|dw] Rs,R0,Rd

・レジスタ間のデータ複写(転送)命令は、Rsとゼロレジスタの加算結果(減算結果でもいいけど)Rdに格納する命令で代用する。

clear [b|hw|w|dw] Rd : add [b|hw|w|dw] R0,R0,Rd

・レジスタ内容のゼロクリアは、ゼロレジスタ同士の加算結果をRdに格納する命令で代用する。

comp [b|hw|w|dw] Rs,{Rt|=imm} → sub [b|hw|w|dw] Rs,Rt,R0
ucomp [b|hw|w|dw] Rs,{Rt|=imm} → usub [b|hw|w|dw] Rs,Rt,R0

・レジスタ同士または(及び即値)との比較は、減算命令により代用する。減算結果の格納先をゼロレジスタに指定する。

| | コメント (0) | トラックバック (0)

命令セットアーキテクチャを考える5 (load/store系命令)

いよいよ命令の定義です。いくつかに分けて定義していきます。
まずはload/store系の命令から。


[Load/Store系命令]:4命令

load [b|hw|w|dw] Rs[+],{Rt|=offset},Rd

・RsとRtから計算したアドレスからbyte/half-word(2byte)/word(4byte)/double-word(8byte)のデータを読み込み、Rdの下位ビットに格納する。余った上位ビットは変更されない。
・condition code registerの内容は変化しない。

・offset付き命令の場合、Rtの代わりにoffset(10bit)を指定できる。offsetは符号付き2進数として扱われ、必要に応じて符号拡張が行われる。
・load/store/branch/jump命令におけるアドレス計算の場合では、offsetは4倍して計算される。byte/half/word/doubleによらず常に4倍される。
・アセンブラ言語ソースプログラムではアドレスオフセット値をそのまま記述する。アセンブラがoffset値を1/4する。

・increment modeの場合、load命令実行後にRsの値が1/2/4/8(byte/half-word/word/double-word)、fload命令実行後にRsの値が4/8/16(single/double/quad)増加する。Rt/offsetの値は変化しない。
・なお、decrement modeはない。

・アドレス計算後は、1/2/4/4バイト境界に合っている必要がある。合っていない場合の処理は、rounding mode registerの内容に従う。(double-wordの場合も4バイト境界で良い)

fload [sp|dp|qp] Rs[+],{Rt|=offset},FRd

・RsとRtから計算したアドレスから単精度(4byte)/倍精度(8byte)/4倍精度(16byte)のデータを読み込み、FRdの下位ビットに格納する。余った上位ビットは変更されない。
・4倍精度の場合、連続したふたつのFRに格納される。FRdのレジスタ番号は偶数でなくてはならない。

・increment modeの場合、fload命令実行後にRsの値が4/8/16(単精度/倍精度/4倍精度)増加する。Rt/offsetの値は変化しない。

・上記以外はload命令と同様である。

store [b|hw|w|dw] [-]Rs,{Rt|=offset},Rd

・Rdの下位ビットからbyte(1byte)/half-word(2byte)/word(4byte)/double-word(8byte)のデータを、RsとRtから計算したアドレスに格納する。
・decrement modeの場合、store命令ではRsの値から1/2/4/8(byte/half-word/word/double-word)、fstore命令ではRsの値から4/8/16(single/double/quad)減じてアドレス計算する。
・Rdがデータのコピー元であることに注意。

・上記以外はload命令と同様である。

fstore [sp|dp|qp] [-]Rs,{Rt|=offset},FRd

・FRdの下位ビットから単精度(4byte)/倍精度(8byte)のデータを、RsとRtから計算したアドレスに格納する。
・4倍精度モードの場合、連続したふたつのFRからデータを取り出して、メモリに格納する。FRdは偶数レジスタでなくてはならない。
・Rdがデータのコピー元であることに注意。


[擬似命令]

以下の擬似命令はアセンブラ言語プログラムに記述できるが、対応する個々のハードウェア命令は存在せず、アセンブラが別の命令語に置き換える。

dtfch Rs,Rt → load Rs,Rt,R0

・dtfch(data fetch)命令は、Rdとしてゼロレジスタを指定しているため実際にはデータを読み込まないので即時に完了するが、Rs,Rtで示されるアドレスを含むキャッシュラインをL1キャッシュに(もしなければ)読み込む処理が実行される(突き放し実行)。
・あらかじめメモリ上のデータをキャッシュに読み込みたい時に使用する。L1キャッシュの構成が命令キャッシュとデータキャッシュに分かれている場合、データキャッシュしかプリフェッチできない。
・命令キャッシュのプリフェッチには別の擬似命令を利用する。(別の記事に書く予定)

loadm [2|4|8|16] Rs[+],{Rt|=offset},Rd
storem [2|4|8|16] [-]Rs,{Rt|=offset},Rd
fldm [2|4|8|16] Rs[+],{Rt|=offset},FRd
fstm [2|4|8|16] [-]Rs,{Rt|=offset},FRd

・load/store/fload/fstore命令でロードまたはストアするレジスタ本数を指定する。(レジスタ内容は64bitすべてを使う)
・loadm/storem/fldm/fstm命令は、アセンブラで複数命令に展開される
・展開された命令中で、increment付きload/store命令を使用する。(終了時には元の値に戻っている)そのため、Rdから連続で指定されるレジスタ群が、Rs,Rtと重複する場合には予期しない結果となるため注意する必要がある。

push [w|dw] Rs,Rd → store [w|dw] [-]Rs,Rd

pop [w|dw] Rs,,Rd → load [w|dw] Rs[+],R0,Rd

# loadはincrementモード、storeはdecrementモードに変更した。
# あわせて、疑似命令としてpush/pop命令を追加した。(2018/04/17)

# push/pop疑似命令から、アドレス境界例外発生を防止するため、byte/half wordモードを削除した。(2018/04/21)
# decrementモードの記述方法をレジスタ記号の前にマイナス記号を付けるように変更した。(2018/04/21)

| | コメント (0) | トラックバック (0)

2014/06/10

命令セットアーキテクチャを考える4 (命令コード)

だいぶん本題に近づいてきました。

[命令体系の基本構想]

・命令フォーマットは3オペランドフォーマット
 ・第1オペランドはレジスタ指定、ソース
 ・第2オペランドはレジスタまたは即値(10bit)、ソース
 ・第3オペランドはレジスタ指定、ディストネーション

・基本命令数は少ない(50命令程度)が、モード(データ長/SIMD/即値等)でバリエーションを持たせられるようにする
 ←ニーモニックコードが読みやすいはず

・多くのレジスタ本数とマルチデータ操作モードでベクトル演算に代える
 ・専用のベクトル演算命令/ベクトルレジスタは備えない

・積和演算命令は備えない(4オペランド必要になるので)

・条件付き命令は備えない(条件付き分岐のみ)

[アセンブラ命令ニーモニック]

opcode [v] [b|hw|w|dw] Rs,{Rt|=imm},Rd : integer/bit演算系
opcode [v] [sp|dp|qp] Rs,{Rt|=imm},Rd : floting演算系
opcode [1|2|4|8|16] Rs[+],{Rt|=offset},Rd : load系
opcode [1|2|4|8|16] [-]Rs,{Rt|=offset},Rd : store系
opcode [pc] Rs,{Rt|=imm|=offset},Rd : branch/jump系


[v]
・SIMD命令の場合に指定(vector)
・省略するとscalar命令(単一データ処理)となる

[b|hw|w|dw]
・整数データのデータ長を指定(byte/half-word/word/double-word)
・省略するとwordとなる

[sp|dp|qp]
・浮動小数点データのデータ長を指定(single-precision/double-precision/quad-precision)
・省略するとsingle-precision

[1|2|4|8|16]
・レジスタ本数を指定(1/2/4/8 か 2/4/8/16 のどちらか)
・擬似命令でのみ指定可能

[pc]
・branch/jump系命令時、PC相対モード指定
・pcが指定されると、アドレス計算にPCの値が加算される

Rs[+] / [-]Rs
・ソースレジスタを指定(R0~R63,FR0~FR63)
・store系命令ではディストネーション
・load/store系命令では、+がつくとincrementモード、-がつくとdecrementモード
・decrementモードではアドレス計算前に減算される
・decrementモードはない

Rt
・ソースレジスタを指定(tはsの次という意味)
・increment/decrementはしない

=imm
・即値を指定(即値は第二オペランドでのみ(Rtの代わりに)可能)
・10進数はそのまま(-512~+511または0~1023)
・16進数は#000~#3ff
・2進数は%0000000000~%1111111111
・<<,>>で算術シフト/論理シフトも指定可能(算術シフトか論理シフトかは、命令によって異なる)

=offset
・load/store系命令で扱うアドレスのオフセット値を指定(第二オペランドでのみ(Rtの代わりに)可能)
・オフセット値は4の倍数である必要がある(4の倍数でない場合は、アセンブラエラーとなる)
・命令コードフォーマット中のimm領域に1/4した値がセットされる
・符号付き10進数(-2048~+2044)
・16進数は#000~#ffc
・<<,>>で算術シフトも指定可能

Rd
・ディストネーションレジスタを指定
・store系命令ではソース


ソースオペランドとディストネーションオペランドをどの順番で書くかということについては、いろいろと流儀があると思います。3オペランド形式だと、例えば加算命令の場合、
add R1,R2,R3 が、
R1 ← R2 + R3 の演算を指示するのか、それとも
R1 + R2 → R3 の演算を指示するのか、が代表的な書き方だと思います。

いま定義している命令セットアーキテクチャでは後者の方式をとりました。理由は、データの流れに沿っているような感じがするのと、日本語で「R1の内容とR2の内容を足してR3に格納する」という説明に合っていると思うからです。


[命令コードフォーマット]

bit[31:28] : Mode(1+1+2) :vector/PC相対/increment,imm/offset,データ長
bit[27:22] : OPcode(6)
bit[21:16] : Rs(6)
bit[15:6] : imm/offset(10) : imm/offsetとRtはどちらか一方
bit[11:6] : Rt(6)
bit[5:0] : Rd(6)

| | コメント (0) | トラックバック (0)

命令セットアーキテクチャを考える3 (特殊レジスタ)

# シリーズものになる予定なのに、タイトルが馬鹿っぽいので変更しました。

命令そのものに入る前に、どうしても必要になる特殊レジスタを定義しておきます。


[Condition Code Register(Read Only)]
・命令の実行結果によってセットされる。
・命令によっては変化しない(load/store/branch命令など)
・整数演算・論理演算・ビット演算結果用(CCR0)と浮動小数点演算結果用(CCR1)の2セットのCCRを持つ
・条件付き分岐命令で参照される
・コンディションコードをリセットする命令はないので、どうしても変更したい場合は、適切な命令(R0+R0→R0とか)を実行する

[CCR0]
bit5: Carry/Borrow(c) : Carry
bit4: Overflow(o) : Overflow
bit3: Underflow(u) : Underflow
bit2: positive/plus(p) : Positive
bit1: zero(z) : Zero
bit0: negative/minus(m) : Minus

# carry/borrowフラグとoverflowフラグを分離した。(2018/03/21)

[CCR1]
bit7: 非正規化数(s) : Subnormal number
bit6: 無限大(i) : Infinite number
bit5: NaN(n) : Not a number
bit4: Overflow : Overflow
bit3: Underflow : Underflow
bit2: positive/plus(p) : Positive
bit1: zero(z) : Zero
bit0: negative/minus(m) : Minus

[Rounding Mode Register(Read/Write)]
・浮動小数点演算の丸め処理のモードを指定する
・特権モードでのみ設定可能、ユーザプログラムからは読み取りのみ可能。

bit5: flash to zero(fz) : 非正規化数を0に丸める
bit4: zero(zr) : 0方向丸め
bit3: negative infinite(in) : -無限大方向丸め
bit2: positive infinite(ip) : +無限大方向丸め
bit1: zero neiborhood(nz) : 最近接丸め(0方向)
bit0: even neiborhood(ne) : 最近接丸め(偶数方向)

・bit0~bit4はいずれか一つのみ設定(排他的)。bit5はbit0~4と独立に設定可能。

[Exception Interruption Inhibit Mode Register(Read/Write)]
・例外割り込み禁止フラグ
・特権モードでのみ設定可能、ユーザプログラムからは読み取りのみ可能。

bit3: fp invalid operation : 演算結果はNaN
bit2: floating zero divide : 演算結果は無限大
bit1: integer zero divide : 演算結果は無限大
bit0: address boundary : 0方向に境界整列する

[Exception code register(Read Only)]
・例外発生フラグ

76543210
bit5: invalid operation excep(iv) : 無効な演算例外(負値の二乗根の逆数など)
bit4: zero divide exception(zd) : 0除算例外(0の平方根の逆数も含む)
bit3: mem protect exception(mp) : 記憶保護例外
bit2: boundary exception(bd) : アドレス境界例外
bit1: address exception(ad) : アドレス例外(実装メモリがないなど)
bit0: operation exception(op) : 命令例外

| | コメント (0) | トラックバック (0)

2014/06/09

命令セットアーキテクチャを考える2 (レジスタ)

レジスタ構成について、先の記事の最後の部分の再掲載から。

・64bit汎用レジスタ×64本、64bit(倍精度)浮動小数点レジスタ×64本
・R0はゼロレジスタ、FR0はゼロレジスタ
・連続する複数本のレジスタを使用する命令で、ゼロレジスタを指定された場合、ゼロレジスタが仮想的に拡張される(R1…,FR1…が使用されるわけではない)

レジスタ本数が64本と多いのは、後で説明するSIMD演算用にも使うため。SIMD演算用の特別なレジスタは持たない。

[General Register 64bit*64]

R0 Zero register(always zero)
R1

R63

・R0はゼロレジスタであり、読み込んだ際にはオールゼロビットが読み出され、書き込みは無視される。(命令は正常終了する)
・連続する複数本のレジスタを使用する命令で、ゼロレジスタを指定された場合、ゼロレジスタが仮想的に拡張される(R1…が使用されるわけではない)。
・byteモードの場合は下位8ビット、half wordモードの場合は下位16bit、wordモードの場合は下位32ビットのみが演算に用いられる。残りの上位ビットは変化しない。
・レジスタの上位ビットのみを参照したり変更するようなハードウェア命令はない。そのような処理が必要な場合は、シフト命令と組み合わせて実現する必要がある。
・SIMDモード命令の場合、8ビット*8、16ビット*4、32ビット×2として使用する。doble wordのSIMDモード命令はない。内部的にはエラーとはならないが、通常のdouble-wordの演算(64bit×1)と同じ演算結果が得られる。

[Floating point number Register 64bit*64]

FR0 Zero register(always zero)
FR1

FR63

・FR0はゼロレジスタであり、読み込んだ際にはプラスゼロ(オールビットゼロ)が読み出され、書き込みは無視される。(命令は正常終了する)
・連続する複数本のレジスタを使用する命令で、ゼロレジスタを指定された場合、ゼロレジスタが仮想的に拡張される(FR1…が使用されるわけではない)。
・単精度モードの場合は下位32ビットのみ演算に用いられる。残りの上位ビットは変化しない。
・連続する二つのレジスタを連結して四倍精度実数データを格納できる。
・SIMDモード命令の場合、連続する四本のレジスタを使って、単精度(32bit)*8、倍精度(64bit)*4、(四倍精度)128bit*2のデータとして演算に使用される。

・浮動小数点レジスタと汎用レジスタとのデータのコピー/変換命令を備える。

| | コメント (0) | トラックバック (0)

命令セットアーキテクチャを考える1 (想定条件)

命令セットを考える前提というか想定条件を明らかにしましょう。
想定そのものが最近のトレンドとは違っているというか、ありえないだろそれ、に近いようなものなので、あくまでも「ぼくのかんがえたさいきょうのめいれいせっと」です。

[前提条件、想定]

・PC/WS/サーバ用途の汎用CPU
 ・組み込み用/スパコンシステム用/GPGPUなどは想定しない

アセンブラでアプリケーションを作成するプログラマ向け
 ・ニーモニックコードが読みやすいこと
  →VLIW形式や遅延スロットは採用しない
  ・16進ダンプを見て理解できるくらいが理想
  ・固定長命令フォーマット
  ・ビッグエンディアンを採用

・マルチプロセッサ構成や仮想化支援機能などはよく分からない‥
  あくまでもアプリケーションプログラマから見える範囲

[基本的な構想]

・64bitアドレッシング

・整数データ形式は、符号付き二進数と2の補数、または符号無し二進数
・実数データ形式は、IEEE754の二進浮動小数点形式(単精度、二倍精度、四倍精度)

・32bit固定長RISC風命令セット
・load/store以外はレジスタ操作のみ

・64bit汎用レジスタ×64本、64bit(倍精度)浮動小数点レジスタ×64本
・R0はゼロレジスタ、FR0はゼロレジスタ

・連続する複数本のレジスタを使用する命令で、ゼロレジスタを指定された場合、ゼロレジスタが仮想的に拡張される(R1…,FR1…が使用されるわけではない)

・ダンプデータの見やすさという理由からビッグエンディアンを採用する。リトルエンディアンを採用するシステムとのデータ交換を容易にするために、バイトスワップ命令を備える。

| | コメント (0) | トラックバック (0)

2014/06/08

新しいマザボ その後

なんとか普通に使うソフトのインストール・設定まで完了しました。

ただ、使っている途中でフリーズしてしまうことが良くあり、状況からseti@home(BOINC)を始めとする負荷の高いソフトを動かしているときにフリーズするような気がします。今はseti@home(BOINC)の稼働設定をあまり負荷が高くならないようにしています。

メモリを今どき風に8GBにしたのですが、OSがWindows7の32bit版なので半分も使っていません。64bit版にすればいいのでしょうけど、Windows8はいまいちなじめないような気がしますし、いまさらWindows7の64bit版を買うのもバカバカしいような気がしてしまっています。

| | コメント (0) | トラックバック (0)

2014/06/07

マザボ変更

今まで使っていたPCが起動時に失敗するようなことが何度かあったので、マザーボード、CPU、メモリを入れ換えました。たぶん5年ぶりくらいのパーツ交換になります。

ハード的にはすんなりと立ち上がったのですが、Windows7のシステムが立ち上がらず、止むなくWindows7の再インストールをすることになってしまいました。とりあえず、こうやってブログを書くところまではたどり着きました。これからいろいろとアプリをインストールしたり、環境設定をしていきます。昔ほどの体力・気力がないので、そこそこの状態になるまでは2~3週間くらいかかっちゃうんじゃないでしょうか。

| | コメント (0) | トラックバック (0)

« 2014年5月 | トップページ | 2014年7月 »