の高速飽和およびシフト2つのハーフワード32ビットワードに2つの符号付き16ビット値があり、一定値(1から6まで可能)で右シフト(分周)する必要があります。バイト(0..0xFF)に飽和します。 = 5シフト0X 0000 0005にならなければならないと例えばARMのasm
、
- 0X FFE1 00AA。
- の0x 2345 12340xの00FF 0091
私は、同時にこの擬似コードのようなものの値を飽和させるためにしようとしているになっている必要があります。私は取得
AND RT, R0, 0x80008000; - mask high bits to get negatives
ORR RT, RT, LSR #1
ORR RT, RT, LSR #2
ORR RT, RT, LSR #4
ORR RT, RT, LSR #8; - now its expanded signs in each halfword
MVN RT, RT
AND R0, RT; now negative values are zero
; here something to saturate high overflow and shift after
が、コードを非常に醜いと遅い。 :)私が今持っている 最高(最速)のものは、このような各半分の別の飽和、次のとおりです。
MOV RT, R0, LSL #16
MOVS RT, RT, ASR #16+5
MOVMI RT, #0
CMP RT, RT, #256
MOVCS RT, #255
MOVS R0, R0, ASR #16+5
MOVMI R0, #0
CMP R0, R0, #256
MOVCS R0, #255
ORR R0, RT, R0, LSL #16
しかし、それは10サイクルです。その後、私はこのためUSAT16命令を見つけましたが、それは、ARMv6のためだけだと、私はARMv5TE以降とARMv4の上で動作するコードが必要
編集:?:(はそれが
PSが高速になります。。:今私は私の最初のコードの書き換え:。
ANDS RT, 0x10000, R0 << 1; // 0x10000 is in register. Sign (HI) moves to C flag, Sign (LO) is masked
SUBNE RT, RT, 1; // Mask LO with 0xFFFF if it's negative
SUBCS RT, RT, 0x10000; // Mask HI with 0xFFFF if it's negative
BIC R0, R0, RT; // Negatives are 0 now. The mask can be used as XOR too
TST R0, 0xE0000000; // check HI overflow
ORRNE R0, R0, 0x1FE00000 // set HI to 0xFF (shifted) if so
TST R0, 0x0000E000 // check LO overflow
ORRNE R0, R0, 0x00001FE0 // set LO to 0xFF if so
AND R0, 0x00FF00FF, R0 >> 5; // 0x00FF00FF is in register
が、それは美しいではありませんが
は、あなたが見て、その後Cでそれを書いて、試してみましたがどのようなコンパイラ生成する? –
スティーブ、別の半分の処理をせずにC言語で書く方法がわかりません。しかし、私の脳はいくつかのアイデアを生み出しています:)その一つは "XORマスク"です。 numberがOKであれば0を含む必要があります(各半分に個別に)。 numberが負の場合は、それ自身を含みます。正のオーバフローでは、それは数値^ 0xFFFFを含むでしょう。結果はソース^マスクになります。しかし、アイデアはありません、同時にそれを行う方法 – zxcat