Use clocked processor registers, each storing an -bit word, two independent combinational read ports and one synchronous write port. Each address requires bits. The read addresses select two -to-one multiplexers, each bits wide. A write-address binary decoder combines its selected line with the global write enable to form the individual enables:
At the active clock edge, register captures the common write data if , otherwise retaining its word. Reads return the currently stored words selected by their respective addresses. For non-power-of-two , unused address codes need a specified harmless implementation. A simultaneous read and write of one address follows the chosen edge/read timing; an additional forwarding circuit would be needed if a different bypass convention were required.
Figure 1.
Two-read-port register file with a single synchronous write port
. The left panel uses a global write enable; the right shows the MIPS alternative with writes to index zero suppressed. Both read multiplexers select independently, and the alternative returns a hardwired zero for address zero. Details.
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.
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.
The following original schematic shows the two data organisations. Register-address, write-enable and memory controls are common background; the diagram highlights the changed combinational logic paths.
Figure 1.
Parallel ALU/shifter selection versus a shifter feeding one ALU operand
. Details.
In the parallel design the result-source multiplexer selects either the arithmetic logic unit or barrel shifter. Its control is additional to the ALU function and shift amount. (i) Addition: read the two operands, select ALU addition and select the ALU result; the shift amount is irrelevant. (ii) Constant left bit shift: read the operand to be shifted, set the shift amount from the immediate operand and select the barrel shifter result; the ALU operation is irrelevant.
In the serial design the result comes through the ALU, so that result-source selection disappears. Its shift-amount control is now relevant to arithmetic as well. (i) Addition: set the barrel shifter to zero shift and select ALU addition, so its inputs are the unshifted processor register values. (ii) Constant left bit shift: set the requested shift and select an ALU operation that passes the shifted operand through. If the ALU lacks that operation, implement it or provide a selectable zero on its other input and add zero. This requirement should be stated, rather than assuming that an ordinary two-input add automatically performs a shift alone.
The ALU result can still supply the memory address. For a register-result instruction, enable processor register writeback and leave memory writes disabled. If the ISA requires shift carry flags, the flag-generation control must retain the barrel shifter's outgoing-bit information; blindly using a pass-through ALU's arithmetic carry is insufficient.
SP-relative addressing forms an effective memory address by adding an offset to the stack pointer. It accesses local variables, saved processor registers or other stack-frame data without dedicating a separate base processor register for each object. The supplied reference gives word-aligned SP-relative offsets from to , which corresponds to an eight-bit nonnegative field scaled by four.
In the modified datapath, select the stack pointer for the unshifted ALU input, the instruction immediate operand for the barrel shifter input, and ALU addition. The effective address can then be . Scaling the immediate operand changes the reachable displacement range without storing a larger immediate operand. For example, an eight-bit field shifted by two reaches offsets through ; shifting it by four reaches through , but only on a sixteen-byte grid. Larger range and finer address granularity are different properties, so the extra reach is not free arbitrary-byte addressing.
The parallel layout cannot feed a shifted immediate operand directly into its address-producing ALU in the same pass. The serial layout can. The actual immediate operand width and permitted shift encodings of a new instruction must be specified; the question does not fix them, so no particular enlarged instruction encoding is implied.
A useful additional mode is base plus scaled register indexing, with effective address . For an array of four-byte elements choose , use its base address on the unshifted ALU input and its index processor register on the barrel shifter input, then add. This forms an indexed machine word address in one datapath pass. An eight-byte element uses .
With parallel ALU and barrel shifter outputs, shifting and adding require either separate instructions/cycles or another route from the barrel shifter to the ALU. The new serial connection supplies that route. This is an addressing mode capability, not a claim that the old instruction encoding already contains the new mode.
The likely effect in a single-cycle or unchanged pipeline-stage implementation is a longer combinational critical path and hence a lower maximum processor clock frequency. Previously the barrel shifter and ALU could work in parallel before result selection; the modified path can require both shift and addition before address or result use.
Ignoring common processor register and wiring delays, the relevant combinational logic contribution changes roughly from to , with any additional input selection included as needed. The processor clock period must also cover processor register timing and the rest of the instruction path, potentially including memory access. Removing a multiplexer offsets some delay, so a numerical frequency change cannot be inferred without component timings. Pipelining, a faster implementation or another pre-existing bottleneck can alter the outcome; the changed serial dependence is the reason for the likely reduction.
Use a logical right shift to discard one inspected bit at a time. The following Thumb instruction set subroutine accepts the word in r0, returns its population count in r0, preserves r4, and otherwise uses caller-saved processor registers.
popcount_loop:
    push {r4}
    movs r1, #0
    movs r2, #1
    movs r3, #32
pop_loop:
    movs r4, r0
    ands r4, r4, r2
    adds r1, r1, r4
    lsrs r0, r0, #1
    subs r3, r3, #1
    bne pop_loop
    movs r0, r1
    pop {r4}
    bx lr
ands extracts the current least significant bit; adds includes it in the count. lsrs fills the newly vacant high position with zero. subs immediately precedes bne, so the branch tests the zero flag from decrementing the loop counter, not a flag left by the shift.
After iterations, the accumulator contains the number of one bits in the original word's lowest positions, and the remaining word is the original unsigned interpretation shifted right by . This loop invariant holds initially and is preserved by each iteration. At every position has been inspected, proving the result. The given example therefore returns 10, and the all-zero and all-one words return 0 and 32. The accumulator cannot overflow: it never exceeds 32.
More processor registers can reduce register spills and the associated loads and stores. A richer instruction set may also replace several old machine instructions by one new operation. Both effects can decrease the number of instructions in a compiled program, although a particular program might obtain no benefit.
Wider instruction encodings increase the bytes per instruction. Consequently the total machine-code size can increase or decrease: approximately, it is instruction count times average encoded instruction width, with alignment and padding also relevant. There is no universal net direction without the program and revised encoding. The length of assembly language source text is a separate matter and is not determined by instruction bit widths.
Use the AAPCS32 convention: r0 holds the input address, r1 the length, and r0 receives the result. The following Thumb instruction set assembly language uses only scratch processor registers, so no callee-saved registers need saving. Assume the array is valid, halfword-aligned, and has nonnegative length; for the mathematical sum assume it fits a signed 32-bit two's complement integer.
.syntax unified
.thumb
.thumb_func
sum16:
    movs r2, #0             @ accumulated sum
    cmp  r1, #0
    ble  .Ldone             @ empty array; also returns 0 if n < 0
.Lloop:
    movs r3, #0             @ Thumb signed load needs a register offset
    ldrsh r3, [r0, r3]      @ signed halfword at a; offset read before r3 changes
    adds r2, r2, r3         @ include this signed value
    adds r0, r0, #2         @ advance by one short, not one byte
    subs r1, r1, #1         @ one fewer element remains
    bne  .Lloop
.Ldone:
    movs r0, r2             @ result register
    bx   lr                 @ leaf routine: lr was not overwritten
After iterations, the loop invariant is that r2 contains the first elements' sum, r0 points to element , and r1 is . The sign extension in ldrsh supplies the correct signed addend. One iteration preserves this loop invariant, and the decreasing remaining length proves algorithm termination. For the seven-element calls, the sum lies between and , so it fits. For longer arrays that overflow, these instructions compute the sum modulo ; that is not a claim about defined signed C programming language overflow behavior. The operand forms are those of the paper's reference sheet.[ref]
Keep total in the callee-saved register r4, and the first returned sum in the callee-saved register r5. Suppose the surrounding function has made an aligned stack frame with the local seven-halfword array at the current sp, occupying fourteen bytes in a sixteen-byte slot. One possible frame setup is push {r4,r5,r6,lr} followed by sub sp,sp,#16; the earlier code initializes total, regular, and special before this fragment.
    ldr  r0, =regular       @ assembler literal load of the global array address
    movs r1, #7
    bl   sum16
    movs r5, r0             @ first sum must survive the next call

    add  r0, sp, #0         @ current frame's local special array
    movs r1, #7
    bl   sum16
    muls r0, r5, r0         @ second sum times first sum
    adds r4, r4, r0         @ update total
The AAPCS32 permits each call to overwrite r0–r3, r12, and condition flags, but requires preservation of r4–r8, r10, r11, and sp. Thus both r4 and r5 remain valid even if sum16 is replaced by another conforming implementation. bl changes the link processor register lr, so the enclosing function saves its own return address in its prologue. Its epilogue can use add sp,sp,#16 and pop {r4,r5,r6,pc}. The frame uses thirty-two bytes in total, preserving the required eight-byte stack pointer alignment at both calls.[ref]
The two calls may be evaluated in this order. Assume the product and final addition fit the signed 32-bit result expected by the source program; unlike each individual seven-element sum, their product need not fit. The assembly language operations retain their low 32 bits if this assumption fails, whereas signed integer overflow in the C programming language has different semantics.
For a 32-bit machine word and , use a left bit shift followed by a logical right shift:
lsls r1, r0, #(32-k)
lsrs r1, r1, #(32-k)
The left shift discards all but the lowest bits and moves those retained bits to the top. The logical right shift returns them to their original positions and fills the rest with zero. Hence r1 contains , the remainder identified in (b). For the remainder is zero; for it is , so these endpoints can be handled directly.
On a reduced instruction set computer, a bit mask such as may not fit an instruction's immediate field. Masking may therefore require materializing the constant in another processor register, possibly using several instructions or a memory load. Small shift counts are directly encodable, so the two shifts can save code space, a temporary processor register, or a load. This is an architecture-dependent advantage, rather than a universal speed claim. The source's compact instruction forms support these immediate shifts, while their bitwise AND form takes its other operand from a processor register.[ref]
Physical register 2026-10-31
A hardware value-storage location distinguished from an architectural processor register name. Several live versions of one logical register can occupy different physical registers.
Processor register Created 2026-10-13 Updated 2026-10-24
A small storage location within a CPU used by its instructions. Some hold data; others describe control state, such as the program counter or stack pointer. Saving and restoring processor registers lets different software threads reuse the same CPU while retaining separate execution contexts.
A processor design using a relatively regular instruction repertoire and explicit restrictions on operand forms. Immediate constants may have limited encodings, so extracting low bits with two bit shifts can avoid constructing a large bit mask in a temporary processor register. The benefit depends on the actual instruction set. A compact example appears in the Thumb 16-bit instruction set quick reference by Arm, whose logical bitwise AND instruction uses a processor register operand while shifts accept small immediate counts.
Register file 2026-10-24
A collection of indexed processor registers. Selecting one of registers requires at least bits in a register index field.
An assembly language memory operand whose effective address is the sum of a base processor register and an offset processor register. A byte-load table lookup uses the index directly as a byte offset; wider entries require an appropriate scale. The effective address is formed from the old register values before the destination register is overwritten.
Register renaming 2026-10-31
Mapping logical processor registers to versions identified by producer tags or physical registers. A conditional destination must still deliver the old logical value when its predicate is false.
Return value 2026-10-31
The result a called procedure supplies to its caller on returning. A calling convention specifies the processor register or memory location carrying it, separately from the return address, which identifies where execution resumes. In the elementary MIPS architecture convention, an integer result is placed in $v0, while $ra carries the return address.