Write the bit vector as , with the least significant bit. Its unsigned interpretation of a bit string is , where each . The range is the integers from through ; a leading one contributes positive weight , not a sign.
Put for an -bit processor register. The carry flag for addition satisfies : the result retains the low bits and records an arithmetic carry beyond them.
For the ARM architecture family subtraction convention, . Thus means no borrow, equivalently the unsigned minuend is at least the subtrahend. This flag is different from signed overflow: an arithmetic carry decision is not a test of the signed result.
Let r1:r0 hold the first operand, high limb first, and r3:r2 the second. In assembly language the addition can be written:
adds r0, r0, r2
adcs r1, r1, r3
The first instruction produces the low result and its arithmetic carry; the second immediately consumes that arithmetic carry while adding the high limbs. No intervening flag-setting instruction is permitted.
For a proof, put and denote the input limbs by . If the low addition gives and arithmetic carry , then . The high addition gives and final arithmetic carry , so . Multiplying the second identity by and combining yields
The processor register pair is the correct result modulo , and the final arithmetic carry records overflow beyond that unsigned width. If the mathematical sum fits in 64 bits, no reduction changes it.
A subtract with carry instruction consumes the no-borrow carry flag. Its arithmetic is . Hence a low-limb subs followed immediately by a high-limb sbcs propagates exactly the low subtraction's borrow.
For example, with the same limb assignment as in (c):
subs r0, r0, r2
sbcs r1, r1, r3
It uses an ordinary 32-bit adder by complementing every bit of the subtrahend and adding the incoming arithmetic carry. For , the unreduced adder sum is
If this is , rearrangement gives . Thus both the result and outgoing no-borrow flag have the required meanings. With incoming arithmetic carry one this becomes ordinary subtraction.[ref]
Use four working processor registers by packing the growing quotient into the vacated low bits of the shifting dividend. The following is A32 assembly language with conditional execution, an allowed instance of the question's general 32-bit Reduced instruction set computer. It is not restricted to the sixteen-bit encodings in the supplied Thumb instruction set table. On entry r0 is the dividend and r1 the positive divisor; r2 becomes the high remainder machine word and r3 counts iterations. The quotient is returned in r0 and the ordinary remainder remains in r2.
mov   r2, #0
mov   r3, #32
loop:
adds  r0, r0, r0
adcs  r2, r2, r2
cmp   r2, r1
subcs r2, r2, r1
adc   r0, r0, #0
subs  r3, r3, #1
bne   loop
bx    lr
Here subcs means conditional sub when arithmetic carry is set, without the flag-setting suffix. adc also preserves flags. Consequently the arithmetic carry from cmp survives until it is inserted as the next quotient bit. The loop has seven instructions, one of them conditional, and no data-dependent branch. Its sole branch is the backwards loop branch, taken 31 times. It uses no separate quotient processor register, zero processor register, temporary comparison processor register or saved arithmetic carry processor register. A Thumb instruction set rendering using conditional execution would need an explicit conditional-execution encoding such as it cs; that is an additional encoded instruction, not an unexplained free operation.
The packed restoring division loop invariant relates it to the displayed algorithm. Specifically, let , let retain its original mathematical value, and let be the number of completed iterations. Define the processed prefix , its quotient and remainder . The processor register loop invariant is
The two terms in the low machine word occupy disjoint bit positions. Its next outgoing arithmetic carry is therefore the next original dividend bit, not a quotient bit. adds shifts the low machine word; adcs doubles the high remainder and incorporates that dividend bit. cmp decides whether this trial remainder is at least the divisor; subcs performs the conditional subtraction, and adc appends its decision to the shifted quotient. This is exactly the doubling, compare/subtract and quotient-bit update, with the counter maintained separately. Before processing bit , the trial remainder is at most , so the high-word addition does not require a hidden 33rd remainder bit for this 32-bit dividend problem. After 32 iterations the residual dividend portion is zero, giving the stated outputs.
There is a printed source error in the auxiliary bound. At the initial state, choosing valid inputs makes the printed strict inequality false. The algorithm instead preserves for its unpacked 64-bit variable, together with its printed equality loop invariant. Doubling and subtracting when necessary preserves that corrected bound. At termination the equality becomes ; since is then divisible by , it gives . This source error does not invalidate the algorithm or the packed implementation. The figure is mathematical pseudocode: its 2^32 denotes exponentiation, rather than C's XOR operator.
The displayed A32 routine assembled successfully with Clang and was disassembled to check the conditional and non-flag-setting forms. Its carry flag model was checked exhaustively at an eight-bit machine word size and against boundary and randomized 32-bit divisions. No native ARM architecture family execution is claimed.

Articles by others on the same topic (0)

There are currently no matching articles.