MC6800のプログラミングテクニック(14) 多バイト整数の2の補数
MC6800のプログラミングテクニック(1) 16bit数値の2の補数の計算と
MC6800のプログラミングテクニック(7) 分岐条件の生成(2)の記事を書いてから、ずーっと考えていたことがある。多バイトの2の補数はもっと簡単に作れないか?
1バイトの2の補数はNEG命令1つでできる。2バイトだとNEGA/NEGB/SBCA #0の4バイト。
negb ; 2 1
nega ; 2 1 negb ; 2 1 sbca #0 ; 2 2
ところが多バイトだと、定義通りに反転して+1するコードが使われていることが多い。なんとかならないか。
4バイト整数の2の補数
例えば、0,x – 3,x の32bit整数の補数を素直に計算すると、以下のコードになる。44-73cycle, 23bytes。最初の反転と+1とretに40cyc。あとは分岐と+1ごとに11cyc。
定義通り反転して+1している。桁上がりの検出が必要なので、bne/incを繰り返している。
com 0,x ; 7 2 com 1,x ; 7 2 com 2,x ; 7 2 com 3,x ; 7 2 inc 3,x ; 7 2 bne ret ; 4 2 inc 2,x ; 7 2 bne ret ; 4 2 inc 1,x ; 7 2 bne ret ; 4 2 inc 0,x ; 7 2 ret: rts ; 5 1
普通に書くとcom 3,x / inc 3,x になるが、そこを negに変更すると少し減らせる。37-66cycle, 21bytes。
メモリ操作命令では、キャリーを使った加減算ができないので、分岐命令を使うしかない。INC with Carry のような命令があったら良かったのだが、未定義命令にも無さそう。
分岐に応じて37,48,59,66cycleかかる。遅くなるのは、$xx000000,$xxxx0000,$xxxxxx00のように下位桁が$00の場合。
com 0,x ; 7 2 com 1,x ; 7 2 com 2,x ; 7 2 neg 3,x ; 7 2 bne ret ; 4 2 inc 2,x ; 7 2 bne ret ; 4 2 inc 1,x ; 7 2 bne ret ; 4 2 inc 0,x ; 7 2 ret: rts ; 5 1
2,x の部分をAccBに置き換えてみる。45,45,56,63cycle, 22bytes。最初の桁で分岐が発生する場合は8cyc遅くなる。それ以外は3サイクル速い。バイト数は1バイト増える。微妙。
AccAも使ってみるパターンも考えたが、速くならないのでボツ。
com 0,x ; 7 2 com 1,x ; 7 2 ldaa 2,x ; 5 2 coma ; 2 1 neg 3,x ; 7 2 sbca #0 ; 2 2 staa 2,x ; 6 2 bne ret ; 4 2 inc 1,x ; 7 2 bne ret ; 4 2 inc 0,x ; 7 2 ret: rts ; 5 1
2の補数のもう一つの定義は、0から引くこと。57cyc, 24bytes. AccAも壊して良いなら、もう1バイト減らせる。
所要時間は57cycで一定。インデックスアクセスではなく ダイレクトページが対象なら、49cycleになる。バイト数は同じ。
clrb ; 2 1 subb 3,x ; 5 2 stab 3,x ; 6 2 ldab #0 ; 2 2 sbcb 2,x ; 5 2 stab 2,x ; 6 2 ldab #0 ; 2 2 sbcb 1,x ; 5 2 stab 1,x ; 6 2 ldab #0 ; 2 2 sbcb 0,x ; 5 2 stab 0,x ; 6 2 rts ; 5 1
アクセス先がインデックス修飾を必要としないなら、Xを使う方法もある。しかし、これはインデックスアクセスを必要とする領域には使えないし、意外に遅い。59cyc,25bytes.
com @long+3 ; 6 3 com @long+2 ; 6 3 com @long+1 ; 6 3 com @long ; 6 3 ldx @long+2 ; 4 2 inx ; 4 1 stx @long+2 ; 5 2 bne ret ; 4 2 ldx @long ; 4 2 inx ; 4 1 stx @long ; 5 2 ret: rts ; 5 1
CC6303やFuzix-Compiler-Kitでは、longは @hireg:AccAB という形で持っている。
この場合は、2バイトの場合のテクニックが使える。Xを壊しても良いなら、もう少し短く・速くできる。
com @hireg com @hireg+1 nega negb sbca #0 bne ret inc @hireg+1 bne ret inc @hireg ret: rts
ディスカッション
コメント一覧
まだ、コメントがありません