3

ARM7コマンドセットは、アセンブラで32ビット値を任意の量だけ右回転する効率的な方法を提供します。演算の第2オペランドの場合、シフターオペランドとしてror #nを指定することで「無料」になりますが、64ビット整数の場合、命令セットによる直接サポートは提供されません。1、31、33、または63ビット位置(0または32は言うまでもなく)でローテーションする特殊なケースを除いて、私は4つの命令を使用して64ビット値をローテーションする方法しか知りません(非常に簡単なので、書きませんここにあります)。4つの特殊なケースでは、これを3つの命令に減らすことができますが、一般的にそれを行う方法がわかりません。だからここに私の質問があります:

2つのレジスタ(たとえばR0とR1)に64ビット値がある場合、3つのARM7命令だけでこの値をn位置(任意のnに対して)右回転させることは可能ですか?

4

2 に答える 2

2

レジスター(例:r4)がたまたま適切なマジック定数(1を希望の左回転量だけ左にシフト)を保持している場合、2つの命令でそれを実行できると思います。

  umull r3、r2、r1、r4
  umlal r2、r3、r0、r4

4つのシングルサイクル命令を使用するよりも低速ですが、適切な定数でr4をロードする必要がある場合でも、4つの命令の方法よりもコンパクトです。

于 2011-03-29T16:17:31.510 に答える
1

これに対する解決策がある場合、gccもそれを認識しません。

unsigned long long int reg64 = random_value;
unsigned int n = shift_value;
reg64 = (reg64 >> (n%64)) | (reg64 << ((64-n)%64));

結果は次のようになります。

n = 1:

MOVS R2, R0, LSR #1
MOV R3, R1, RRX
ORR R2, R2, R1, ASL #31

n = 2-31:

MOV R2, R0, LSR #n
ORR R2, R2, R1, ASL #32-n
MOV R3, R0, ASL #32-n
ORR R3, R3, R1, LSR #n

n = 33-62:

MOV R3, R0, ASL #64-n
ORR R3, R3, R1, LSR #n-32
MOV R2, R0, LSR, #n-32
ORR R2, R2, R1, ASL #64-n

n = 63:

ADDS R2, R0, R0
ADC R3, R1, R1
ORR R2, R2, R1, LSR #31
于 2011-03-25T15:48:39.753 に答える