2

ネイティブMIPSに多倍長演算を実装しようとしています。1つの64ビット整数がレジスター$12と$13にあり、別の整数がレジスター$14と$15にあると仮定します。合計はレジスター$10と$11に入れられます。64ビット整数の最上位ワードは偶数番号のレジスターにあり、最下位ワードは奇数番号のレジスターにあります。インターネット上では、これが可能な限り最短の実装であるとのことです。

addu  $11, $13, $15    # add least significant word
sltu  $10, $11, $15    # set carry-in bit 
addu  $10, $10, $12    # add in first most significant word
addu  $10, $10, $14    # add in second most significant word

正しく理解していることを再確認したいだけです。sltuは、2つの最下位ワードの合計がオペランドの1つよりも小さいか等しいかどうかをチェックします。この場合、キャリーが発生したよりも、これは正しいですか?

2つの最も重要な単語を追加するときにキャリーが発生したかどうかを確認し、結果を$ 9に格納するには、次のことを行う必要があります。

sltu  $9, $10, $12    # set carry-in bit 

これは意味がありますか?

4

1 に答える 1

1

sltu は、2 つの最下位ワードの合計がオペランドの 1 つより小さいか等しいかどうかをチェックします。

そうではありません: $102 つの最下位ワードの合計が厳密にオペランドの 1 つよりも小さい場合 (32 ビットの符号なし値と見なされます)、1 に設定されます。合計がそのオペランド以上の場合は 0。

この場合、キャリーが発生したというよりは、そうですか。

はい。

bのさまざまな可能な値を特定の値a (すべてが符号なし 32 ビット値である場合)に加算するとどうなるかを考えてみましょう。

  • オーバーフローが発生していない場合、 <= sum <= 0xFFFFFFFF である必要があるため、0 <= b <= (0xFFFFFFFF - a ) となります。
  • bの残りのケースでは、オーバーフローが発生します。これらの場合の実際の合計は、0x100000000 <= sum <= a + 0xFFFFFFFF でなければならず、32 ビットに切り捨てられると、0 <= sum <= a - 1 になります。

最も重要な 2 つの単語を追加するときにキャリーが発生したかどうかを確認し、結果を $9 に格納するには、次のようにする必要があります。

sltu $9, $10, $12 # set carry-in bit

そうではありません。

ここでの問題は、2 つの 32 ビット値を加算していることと、場合によっては最下位ワードの合計からキャリーを加算していることです。たとえば、キャリーがあり、両方の最上位ワードが 0xFFFFFFFF である場合を考えてみましょう。合計は 1+ 0xFFFFFFFF + 0xFFFFFFFF = 0xFFFFFFFF となり、キャリーは設定されません (ただし、設定する必要があります)。

これに対処する 1 つの方法は、 に加算$12した後にキャリーをチェック$10し、その合計に加算した後に再度チェックする$11ことです。これらの合計の 1 つだけがキャリーを生成できます (が 0 または 1であるため、 が 0xFFFFFFFF の$12 + $10場合にのみオーバーフローします。その場合、合計は 0 であるため、2 番目の合計もオーバーフローできません)。$12$10

したがって、これは(免責事項:遅く、これはテストされていません)トリックを行う可能性があります:

addu $11, $13, $15
sltu $10, $11, $15  # carry from low word
addu $10, $10, $12
sltu  $9, $10, $12  # possible carry from high word (1)
addu $10, $10, $14
sltu  $8, $10, $14  # possible carry from high word (2)
or    $9,  $8,  $9  # carry in result if either (1) or (2) were true (can't both be true at once)
于 2010-04-21T23:22:26.523 に答える