SH-2A、SH2A-FPU
6. 各命令の説明
6.4 SH-2E の CPU 命令
6.4.18 DIV1 DIVide 1 step:算術演算命令
除算
書式 動作概略 命令コード 実行
ステート
Tビット
DIV1 Rm,Rn 1ステップ除算 (Rn÷Rm) 0011nnnnmmmm0100 1 計算結果
(1)
説明汎用レジスタ
Rn
の32
ビットの内容(被除数)をRm
の内容(除数)で1
桁分の除算(1
ステップ 除算)を実行する命令です。本命令単独でまたは他の命令と組み合わせて繰り返し実行し商を求めま す。この繰り返し中は、指定したレジスタとM
、Q
、T
ビットを書き換えないでください。1
ステップ除算とは、被除数を左に1
ビットシフトし、それから除数を減算し、結果の正負によっ て商のビットをQ
ビットに反映するという処理を実行します。割り算で余りを求めるには、
DIV1
命令を用いて商を求めたあと、(被除数)-(除数)×(商)
=
(余り)として求めてください。なお、周辺機能として除算器を搭載している
SH7600
シリーズでは、除算 器の機能により余りを求めることができます。ゼロ除算とオーバフローの検出は用意していません。除算の前にゼロ除算とオーバフロー除算をチ ェックしてください。剰余の演算は用意していません。除数と求められた商との積を求めて、被除数 から減算して剰余を求めてください。
最初に、
DIV0S
またはDIV0U
で初期設定します。DIV1
を除数のビット数分繰り返します。商が17
ビット以上必要なとき、ROTCL
をDIV1
の前に置きます。詳しい 除算のシーケンスは下記の使用 例を参考にしてください。6.
各命令の説明Rev.4.00 2011.02.22 6-104 R01US0031JJ0400
SH-2A、SH2A-FPU
(2)
動作内容DIV1(long m, long n) /* DIV1 Rm,Rn */
{
unsigned long tmp0;
unsigned char old_q, tmp1;
old_q=Q;
Q=(unsigned char)((0x80000000 & R[n])!=0);
R[n]<<=1;
R[n]|=(unsigned long)T;
switch(old_q){
case 0:switch(M){
case 0:tmp0=R[n];
R[n]-=R[m];
tmp1=(R[n]>tmp0);
switch(Q){
case 0:Q=tmp1;
break;
case 1:Q=(unsigned char)(tmp1==0);
break;
} break;
case 1:tmp0=R[n];
R[n]+=R[m];
tmp1=(R[n]<tmp0);
switch(Q){
case 0:Q=(unsigned char)(tmp1==0);
break;
case 1:Q=tmp1;
break;
} break;
} break;
6.
各命令の説明Rev.4.00 2011.02.22 6-105 R01US0031JJ0400 SH-2A、SH2A-FPU
case 1:switch(M){
case 0:tmp0=R[n];
R[n]+=R[m];
tmp1=(R[n]<tmp0);
switch(Q){
case 0:Q=tmp1;
break;
case 1:Q=(unsigned char)(tmp1==0);
break;
} break;
case 1:tmp0=R[n];
R[n]-=R[m];
tmp1=(R[n]>tmp0);
switch(Q){
case 0:Q=(unsigned char)(tmp1==0);
break;
case 1:Q=tmp1;
break;
} break;
} break;
}
T=(Q==M);
PC+=2;
}
6.
各命令の説明Rev.4.00 2011.02.22 6-106 R01US0031JJ0400
SH-2A、SH2A-FPU
(3)
使用例1
;R1(32ビット)÷R0(16ビット)=R1(16ビット):符号なし
SHLL16 R0 ;除数を上位16ビット、下位16ビットを0に設定
TST R0,R0 ;ゼロ除算チェック
BT ZERO_DIV ;
CMP/HS R0,R1 ;オーバフローチェック
BT OVER_DIV ;
DIV0U ;フラグの初期化
.arepeat 16 ;
DIV1 R0,R1 ;16回繰り返し
.aendr ;
ROTCL R1 ;
EXTU.W R1,R1 ;R1=商
(4)
使用例2
;R1:R2(64ビット)÷R0(32ビット)=R2(32ビット):符号
なし
TST R0,R0 ;ゼロ除算チェック
BT ZERO_DIV ;
CMP/HS R0,R1 ;オーバフローチェック
BT OVER_DIV ;
DIV0U ;フラグの初期化
.arepeat 32 ;
ROTCL R2 ;32回繰り返し
DIV1 R0,R1 ;
.aendr ;
ROTCL R2 ;R2=商
6.
各命令の説明Rev.4.00 2011.02.22 6-107 R01US0031JJ0400 SH-2A、SH2A-FPU
(5)
使用例3
;R1(16ビット)÷R0(16ビット)=R1(16ビット):符号付き
SHLL16 R0 ;除数を上位16ビット、下位16ビットを0に設定
EXTS.W R1,R1 ;被除数は符号拡張して32ビット
XOR R2,R2 ;R2=0
MOV R1,R3 ;
ROTCL R3 ;
SUBC R2,R1 ;被除数が負のとき、-1する。
DIV0S R0,R1 ;フラグの初期化
.arepeat 16 ;
DIV1 R0,R1 ;16回繰り返し
.aendr ;
EXTS.W R1,R1 ;
ROTCL R1 ;R1=商(1の補数表現)
ADDC R2,R1 ;商のMSBが1のとき、+1して2の補数表現に変換
EXTS.W R1,R1 ;R1=商(2の補数表現)
(6)
使用例4
;R2(32ビット)÷R0(32ビット)=R2(32ビット):符号付き
MOV R2,R3 ;
ROTCL R3 ;
SUBC R1,R1 ;被除数は符号拡張して64ビット(R1:R2)
XOR R3,R3 ;R3=0
SUBC R3,R2 ;被除数が負のとき、-1して1の補数表現に変換
DIV0S R0,R1 ;フラグの初期化
.arepeat 32 ;
ROTCL R2 ; 32回繰り返し
DIV1 R0,R1 ;
.aendr ;
ROTCL R2 ;R2=商(1の補数表現)
ADDC R3,R2 ;商のMSBが1のとき、+1して2の補数表現に変換
;R2=商(2の補数表現)